Skip to content

Commit

Permalink
refactor: Changed CSV load action to be a logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ShrimpCryptid committed Nov 22, 2024
1 parent b2e058f commit 1498c5d
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 65 deletions.
45 changes: 13 additions & 32 deletions src/containers/CsvInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,26 @@ import { Flex } from "antd";
import { RcFile } from "antd/es/upload";
import Dragger from "antd/es/upload/Dragger";
import React, { ReactElement } from "react";
import { connect } from "react-redux";
import { ActionCreator, connect } from "react-redux";

import imageDatasetBranch from "../../state/image-dataset";
import CsvRequest, { DEFAULT_CSV_DATASET_KEY } from "../../state/image-dataset/csv-dataset";
import { ImageDataset, Megaset, ReceiveImageDatasetAction } from "../../state/image-dataset/types";
import metadataStateBranch from "../../state/metadata";
import { ReceiveAvailableDatasetsAction } from "../../state/metadata/types";
import selectionStateBranch from "../../state/selection";
import { ChangeSelectionAction } from "../../state/selection/types";

type CsvInputProps = {
receiveImageDataset: (dataset: ImageDataset) => ReceiveImageDatasetAction;
receiveAvailableDatasets: (megasets: Megaset[]) => ReceiveAvailableDatasetsAction;
changeDataset: (id: string) => ChangeSelectionAction;
};
import { State } from "../../state";
import imageDatasetStateBranch from "../../state/image-dataset";
import { LoadCsvDatasetAction } from "../../state/image-dataset/types";

type DispatchProps = {
receiveAvailableDatasets: (megasets: Megaset[]) => ReceiveAvailableDatasetsAction;
changeDataset: (id: string) => ChangeSelectionAction;
receiveImageDataset: (dataset: ImageDataset) => ReceiveImageDatasetAction;
loadCsvDataset: ActionCreator<LoadCsvDatasetAction>;
};

type CsvInputProps = DispatchProps;

/**
* An input area for CSV files. When CSV data is provided, replaces the current image dataset
* with a new `CsvRequest` image dataset and triggers the loading of the CSV data.
*/
function CsvInput(props: CsvInputProps): ReactElement {
const action = async (file: RcFile): Promise<string> => {
// TODO: handle loading via URL
const fileContents = await file.text();
const dataset = new CsvRequest(fileContents);
props.receiveImageDataset(dataset);

// CSV Request mocks up a single dataset
const megasets = await dataset.getAvailableDatasets();
props.receiveAvailableDatasets(megasets);
props.changeDataset(DEFAULT_CSV_DATASET_KEY);

const fileText = await file.text();
props.loadCsvDataset(fileText);
return Promise.resolve("");
};

Expand All @@ -55,10 +37,9 @@ function CsvInput(props: CsvInputProps): ReactElement {
</Dragger>
);
}
const dispatchToPropsMap = {
receiveAvailableDatasets: metadataStateBranch.actions.receiveAvailableDatasets,
changeDataset: selectionStateBranch.actions.changeDataset,
receiveImageDataset: imageDatasetBranch.actions.receiveImageDataset,

const dispatchToPropsMap: DispatchProps = {
loadCsvDataset: imageDatasetStateBranch.actions.loadCsvDataset,
};

export default connect(undefined, dispatchToPropsMap)(CsvInput);
export default connect<{}, DispatchProps, {}, State>(null, dispatchToPropsMap)(CsvInput);
2 changes: 1 addition & 1 deletion src/state/configure-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const reducers = {
imageDataset: imageDataset.reducer,
};

const logics = [...metadata.logics, ...selection.logics];
const logics = [...metadata.logics, ...selection.logics, ...imageDataset.logics];

const reduxLogicDependencies = {
httpClient: axios,
Expand Down
15 changes: 11 additions & 4 deletions src/state/image-dataset/actions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { ReceiveImageDatasetAction } from "./types";
import { RECEIVE_IMAGE_DATASET } from "./constants";
import { ChangeImageDatasetTypeAction } from "./types";
import { CHANGE_IMAGE_DATASET_TYPE, LOAD_CSV_DATASET } from "./constants";
import { ImageDataset } from "./types";

export function receiveImageDataset(payload: ImageDataset): ReceiveImageDatasetAction {
return { payload, type: RECEIVE_IMAGE_DATASET };
export function changeImageDatasetType(payload: ImageDataset): ChangeImageDatasetTypeAction {
return { payload, type: CHANGE_IMAGE_DATASET_TYPE };
}

export function loadCsvDataset(payload: string) {
return {
payload,
type: LOAD_CSV_DATASET,
};
}
6 changes: 5 additions & 1 deletion src/state/image-dataset/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { makeConstant } from "../util";

export const RECEIVE_IMAGE_DATASET = makeConstant("metadata", "receive-image-dataset");
const makeImageDatasetConstant = (constant: string) => makeConstant("image-dataset", constant);

export const LOAD_CSV_DATASET = makeImageDatasetConstant("load-csv-dataset");

export const CHANGE_IMAGE_DATASET_TYPE = makeImageDatasetConstant("change-image-dataset-type");
14 changes: 2 additions & 12 deletions src/state/image-dataset/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import FirebaseRequest from "./firebase";
import JsonRequest from "./json-dataset";
import { ImageDataset } from "./types";

// by default will use Firebase for dataset, can be switched to JSON dataset using ENV
// variable
export function GetImageDatasetInstance(): ImageDataset {
return process.env.USE_JSON_DATASET ? new JsonRequest() : new FirebaseRequest();
}

import * as actions from "./actions";
// import logics from "./logics";
import logics from "./logics";
import reducer from "./reducer";
import * as selectors from "./selectors";
import * as types from "./types";

export default {
actions,
// logics,
logics,
reducer,
selectors,
types,
Expand Down
27 changes: 27 additions & 0 deletions src/state/image-dataset/logics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createLogic } from "redux-logic";
import { ReduxLogicDeps } from "..";
import { LOAD_CSV_DATASET } from "./constants";
import CsvRequest, { DEFAULT_CSV_DATASET_KEY } from "./csv-dataset";
import { changeImageDatasetType } from "./actions";
import { receiveAvailableDatasets } from "../metadata/actions";
import { changeDataset } from "../selection/actions";

/**
* Parses a CSV file and opens it as a new image dataset.
*/
const loadCsvDataset = createLogic({
type: LOAD_CSV_DATASET,
async process(deps: ReduxLogicDeps, dispatch: any, done: any) {
const { action } = deps;
const fileContents = action.payload as string;
const dataset = new CsvRequest(fileContents);
dispatch(changeImageDatasetType(dataset));

const megasets = await dataset.getAvailableDatasets();
dispatch(receiveAvailableDatasets(megasets));
dispatch(changeDataset(DEFAULT_CSV_DATASET_KEY));
done();
},
});

export default [loadCsvDataset];
37 changes: 26 additions & 11 deletions src/state/image-dataset/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
import { TypeToDescriptionMap } from "..";
import { AnyAction } from "redux";
import { RECEIVE_IMAGE_DATASET } from "./constants";
import { ImageDatasetStateBranch, ReceiveAction } from "./types";
import { CHANGE_IMAGE_DATASET_TYPE, LOAD_CSV_DATASET } from "./constants";

Check warning on line 3 in src/state/image-dataset/reducer.ts

View workflow job for this annotation

GitHub Actions / build

'LOAD_CSV_DATASET' is defined but never used
import {
ImageDataset,
ImageDatasetStateBranch,
LoadCsvDatasetAction,

Check warning on line 7 in src/state/image-dataset/reducer.ts

View workflow job for this annotation

GitHub Actions / build

'LoadCsvDatasetAction' is defined but never used
ReceiveImageDatasetAction,
} from "./types";
import { makeReducer } from "../util";
import { GetImageDatasetInstance } from ".";
import FirebaseRequest from "./firebase";
import JsonRequest from "./json-dataset";

// by default will use Firebase for dataset, can be switched to JSON dataset using ENV
// variable
function getImageDatasetInstance(): ImageDataset {
return process.env.USE_JSON_DATASET ? new JsonRequest() : new FirebaseRequest();
}

export const initialState: ImageDatasetStateBranch = {
imageDataset: GetImageDatasetInstance(),
imageDataset: getImageDatasetInstance(),
};

const actionToConfigMap: TypeToDescriptionMap = {
[RECEIVE_IMAGE_DATASET]: {
accepts: (action: AnyAction): action is ReceiveAction =>
action.type === RECEIVE_IMAGE_DATASET,
perform: (state: ImageDatasetStateBranch, action: ReceiveAction) => ({
...state,
imageDataset: action.payload,
}),
[CHANGE_IMAGE_DATASET_TYPE]: {
accepts: (action: AnyAction): action is ReceiveImageDatasetAction =>
action.type === CHANGE_IMAGE_DATASET_TYPE,
perform: (state: ImageDatasetStateBranch, action: ReceiveImageDatasetAction) => {
console.log("Changing dataset type", action.payload);
return {
...state,
imageDataset: action.payload,
};
},
},
};

Expand Down
11 changes: 8 additions & 3 deletions src/state/image-dataset/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ export interface ImageDatasetStateBranch {
imageDataset: ImageDataset;
}

export interface ReceiveAction {
payload: { [key: string]: any };
export interface ReceiveImageDatasetAction {
payload: ImageDataset;
type: string;
}

export interface LoadCsvDatasetAction {
payload: string; // CSV contents
type: string;
}

Expand Down Expand Up @@ -75,7 +80,7 @@ export interface ImageDataset {
getFileInfoByArrayOfCellIds(ids: string[]): Promise<(FileInfo | undefined)[]>;
} // ACTIONS

export interface ReceiveImageDatasetAction {
export interface ChangeImageDatasetTypeAction {
payload: ImageDataset;
type: string;
}
1 change: 0 additions & 1 deletion src/state/metadata/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import {
SetLoadingAction,
SetSmallScreenWarningAction,
} from "./types";
import { ReceiveImageDatasetAction } from "../image-dataset/types";

export function requestAvailableDatasets() {
return { type: REQUEST_AVAILABLE_DATASETS };
Expand Down

0 comments on commit 1498c5d

Please sign in to comment.