Skip to content

Commit

Permalink
Merge branch 'main' into atar/type-config
Browse files Browse the repository at this point in the history
  • Loading branch information
atarashansky authored Aug 29, 2022
2 parents 5b25bbf + 51086b4 commit 4df0ebb
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 84 deletions.
6 changes: 3 additions & 3 deletions client/__tests__/reducers/genesetsUI.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import genesetsUIReducer from "../../src/reducers/genesetsUI";
import genesetsUIReducer, { GeneSetsUIState } from "../../src/reducers/genesetsUI";

// Format: GeneSetsUI(state,action)

const initialState = {
const initialState: GeneSetsUIState = {
createGenesetModeActive: false,
isEditingGenesetName: false,
isAddingGenesToGeneset: false,
Expand Down Expand Up @@ -30,7 +30,7 @@ describe("geneset UI states", () => {
});
test("geneset: disable create geneset mode", () => {
expect(
genesetsUIReducer(undefined, { isEditingGenesetName: false })
genesetsUIReducer(undefined, { type: "geneset: disable rename geneset mode", isEditingGenesetName: false })
).toMatchObject(initialState);
});

Expand Down
81 changes: 47 additions & 34 deletions client/src/reducers/cascade.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,59 @@
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
export default function cascadeReducers(arg: any) {
/*
Combine a set of cascading reducers into a single reducer. Cascading
reducers are reducers which may rely on state computed by another reducer.
Therefore, they:
- must be composed in a particular order (currently, this is a simple
linear list of reducers, run in list order)
- must have access to partially updated "next state" so they can further
derive state.
import { AnyAction, Reducer } from "redux";
import type { RootState } from ".";

Parameter is one of:
- a Map object
- an array of tuples, [ [key1, reducer1], [key2, reducer2], ... ]
Ie, cascadeReducers([ ["a", reduceA], ["b", reduceB] ])
export type ReducerFunction = (
prevStateForKey: RootState[keyof RootState],
action: AnyAction,
nextState?: RootState,
prevState?: RootState
) => RootState;

Each reducer will be called with the signature:
(prevState, action, sharedNextState, sharedPrevState) => newState
type CascadedReducers =
| [string, ReducerFunction][]
| Map<string, ReducerFunction>;

cascadeReducers will build a composite newState object, much
like combinedReducers. Additional semantics:
- reducers guaranteed to be called in order
- each reducer will receive shared objects
*/
export default function cascadeReducers(arg: CascadedReducers): Reducer {
/**
* Combine a set of cascading reducers into a single reducer. Cascading
* reducers are reducers which may rely on state computed by another reducer.
* Therefore, they:
* - must be composed in a particular order (currently, this is a simple
* linear list of reducers, run in list order)
* - must have access to partially updated "next state" so they can further
* derive state.
*
* Parameter is one of:
* - a Map object
* - an array of tuples, [ [key1, reducer1], [key2, reducer2], ... ]
* Ie, cascadeReducers([ ["a", reduceA], ["b", reduceB] ])
*
* Each reducer will be called with the signature:
* (prevState, action, sharedNextState, sharedPrevState) => newState
* cascadeReducers will build a composite newState object, much
* like combinedReducers. Additional semantics:
* - reducers guaranteed to be called in order
* - each reducer will receive shared objects
*/
const reducers = arg instanceof Map ? arg : new Map(arg);
const reducerKeys = [...reducers.keys()];
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
return (prevState: any, action: any) => {
const nextState = {};

return (prevState: RootState, action: AnyAction) => {
const nextState: RootState = {};
let stateChange = false;
for (let i = 0, l = reducerKeys.length; i < l; i += 1) {
const key = reducerKeys[i];
const reducer = reducers.get(key);
const prevStateForKey = prevState ? prevState[key] : undefined;
const nextStateForKey = reducer(
prevStateForKey,
action,
nextState,
prevState
);
// @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
nextState[key] = nextStateForKey;
stateChange = stateChange || nextStateForKey !== prevStateForKey;
if (reducer) {
const prevStateForKey = prevState ? prevState[key] : undefined;
const nextStateForKey = reducer(
prevStateForKey,
action,
nextState,
prevState
);
nextState[key] = nextStateForKey;
stateChange = stateChange || nextStateForKey !== prevStateForKey;
}
}
return stateChange ? nextState : prevState;
};
Expand Down
2 changes: 1 addition & 1 deletion client/src/reducers/categoricalSelection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const CategoricalSelection = (
state: CategoricalSelectionState,
action: AnyAction,
nextSharedState: RootState
) => {
): CategoricalSelectionState => {
switch (action.type) {
case "initial data load complete":
case "subset to selection":
Expand Down
11 changes: 6 additions & 5 deletions client/src/reducers/centroidLabels.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Action } from "redux";
import type { Action, AnyAction } from "redux";
import type { RootState } from ".";

export interface CentroidLabelsState {
showLabels: boolean;
Expand All @@ -14,15 +15,15 @@ const initialState: CentroidLabelsState = {

const centroidLabels = (
state = initialState,
action: CentroidLabelsAction,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
sharedNextState: any
action: AnyAction,
sharedNextState: RootState
): CentroidLabelsState => {
const {
colors: { colorAccessor },
} = sharedNextState;

const showLabels = action.showLabels ?? state.showLabels;
const showLabels =
(action as CentroidLabelsAction).showLabels ?? state.showLabels;

switch (action.type) {
case "color by categorical metadata":
Expand Down
22 changes: 11 additions & 11 deletions client/src/reducers/continuousSelection.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Action } from "redux";
import type { Action, AnyAction } from "redux";

import { makeContinuousDimensionName } from "../util/nameCreators";

Expand All @@ -16,7 +16,7 @@ export interface ContinuousSelectionState {

const ContinuousSelection = (
state: ContinuousSelectionState = {},
action: ContinuousSelectionAction
action: AnyAction
): ContinuousSelectionState => {
switch (action.type) {
case "reset subset":
Expand All @@ -27,20 +27,20 @@ const ContinuousSelection = (
case "continuous metadata histogram start":
case "continuous metadata histogram brush":
case "continuous metadata histogram end": {
const name = makeContinuousDimensionName(
action.continuousNamespace,
action.selection
);
const { continuousNamespace, selection, range } =
action as ContinuousSelectionAction;

const name = makeContinuousDimensionName(continuousNamespace, selection);
return {
...state,
[name]: action.range,
[name]: range,
};
}
case "continuous metadata histogram cancel": {
const name = makeContinuousDimensionName(
action.continuousNamespace,
action.selection
);
const { continuousNamespace, selection } =
action as ContinuousSelectionAction;

const name = makeContinuousDimensionName(continuousNamespace, selection);
const { [name]: deletedField, ...newState } = state;
return newState;
}
Expand Down
26 changes: 16 additions & 10 deletions client/src/reducers/datasetMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
/*
Dataset metadata reducer, modifies Portal collections-related state.
Dataset metadata reducer, modifies Portal collections-related state.
*/

// Core dependencies
import { Action } from "redux";
import { Action, AnyAction } from "redux";

// App dependencies
import { DatasetMetadata as IDatasetMetadata } from "../common/types/entities";

/*
Action dispatched on successful response from dataset-metadata endpoint.
*/
export interface DatasetMetdataAction extends Action<string> {
export interface DatasetMetadataAction extends Action<string> {
datasetMetadata: IDatasetMetadata;
error: string;
portalUrl: string;
}

/*
Dataset metdata state; selected dataset ID and corresponding collection information.
Dataset metadata state; selected dataset ID and corresponding collection information.
*/
export interface DatasetMetadataState {
datasetMetadata: IDatasetMetadata | null;
Expand All @@ -36,7 +36,7 @@ const DatasetMetadata = (
datasetMetadata: null,
portalUrl: null,
},
action: DatasetMetdataAction
action: AnyAction
): DatasetMetadataState => {
switch (action.type) {
case "initial data load start":
Expand All @@ -45,19 +45,25 @@ const DatasetMetadata = (
loading: true,
error: null,
};
case "dataset metadata load complete":
case "dataset metadata load complete": {
const { datasetMetadata, portalUrl } = action as DatasetMetadataAction;

return {
...state,
loading: false,
error: null,
datasetMetadata: action.datasetMetadata,
portalUrl: action.portalUrl,
datasetMetadata,
portalUrl,
};
case "initial data load error":
}
case "initial data load error": {
const { error } = action as DatasetMetadataAction;

return {
...state,
error: action.error,
error,
};
}
default:
return state;
}
Expand Down
13 changes: 9 additions & 4 deletions client/src/reducers/genesetsUI.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { AnyAction } from "redux";

export interface GeneSetsUIState {
createGenesetModeActive: boolean;
isEditingGenesetName: string | false;
isAddingGenesToGeneset: string | false;
}
/*
Reducers for geneset UI-state.
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS.
const GeneSetsUI = (
state = {
state: GeneSetsUIState = {
createGenesetModeActive: false,
isEditingGenesetName: false,
isAddingGenesToGeneset: false,
},
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS.
action: any
action: AnyAction
) => {
switch (action.type) {
/**
Expand Down
10 changes: 5 additions & 5 deletions client/src/reducers/layoutChoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ about commonly used names. Preferentially, pick in the following order:
4. give up, use the first available
*/

import type { Action } from "redux";
import type { Action, AnyAction } from "redux";
import type { RootState } from ".";
import { EmbeddingSchema, Schema } from "../common/types/schema";

function bestDefaultLayout(layouts: Array<string>): string {
Expand Down Expand Up @@ -39,9 +40,8 @@ export interface LayoutChoiceAction extends Action<string> {

const LayoutChoice = (
state: LayoutChoiceState,
action: LayoutChoiceAction,
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS.
nextSharedState: any
action: AnyAction,
nextSharedState: RootState
): LayoutChoiceState => {
switch (action.type) {
case "initial data load complete": {
Expand All @@ -55,7 +55,7 @@ const LayoutChoice = (

case "set layout choice": {
const { schema } = nextSharedState.annoMatrix;
const current = action.layoutChoice;
const current = (action as LayoutChoiceAction).layoutChoice;
const currentDimNames = schema.layout.obsByName[current].dims;
return { ...state, current, currentDimNames };
}
Expand Down
30 changes: 19 additions & 11 deletions client/src/reducers/quickGenes.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import uniq from "lodash.uniq";
import filter from "lodash.filter";
import { Action, AnyAction } from "redux";
import type { RootState } from ".";
import { track } from "../analytics";
import { EVENTS } from "../analytics/events";

interface QuickGenesActions {
type: string;
interface State {
userDefinedGenes: string[];
userDefinedGenesLoading: boolean;
}

interface QuickGenesActions extends Action<string> {
gene: string;
selection: string;
data: string;
}
const quickGenes = (
state: { userDefinedGenes: string[]; userDefinedGenesLoading: boolean } = {
state: State = {
userDefinedGenes: [],
userDefinedGenesLoading: false,
},
action: QuickGenesActions,
action: AnyAction,
nextSharedState: RootState
) => {
): State => {
switch (action.type) {
case "request user defined gene started": {
return {
Expand All @@ -33,7 +38,10 @@ const quickGenes = (
}
case "request user defined gene success": {
const { userDefinedGenes } = state;
const _userDefinedGenes = uniq([...userDefinedGenes, action.gene]);
const { gene } = action as QuickGenesActions;

const _userDefinedGenes = uniq([...userDefinedGenes, gene]);

return {
...state,
userDefinedGenes: _userDefinedGenes,
Expand All @@ -42,10 +50,10 @@ const quickGenes = (
}
case "clear user defined gene": {
const { userDefinedGenes } = state;
const newUserDefinedGenes = filter(
userDefinedGenes,
(d) => d !== action.gene
);
const { gene } = action as QuickGenesActions;

const newUserDefinedGenes = filter(userDefinedGenes, (d) => d !== gene);

return {
...state,
userDefinedGenes: newUserDefinedGenes,
Expand All @@ -56,7 +64,7 @@ const quickGenes = (
case "color by expression":
case "set scatterplot x":
case "set scatterplot y": {
const { selection, gene } = action;
const { selection, gene } = action as QuickGenesActions;
const { controls } = nextSharedState;
const { scatterplotXXaccessor, scatterplotYYaccessor } = controls;

Expand Down

0 comments on commit 4df0ebb

Please sign in to comment.