Skip to content

Commit e9a2fcf

Browse files
Merge pull request #75 from AllenInstitute/feature/persistant-columns
Feature/persistant columns
2 parents e343558 + f3b21ab commit e9a2fcf

File tree

8 files changed

+89
-22
lines changed

8 files changed

+89
-22
lines changed

packages/core/services/PersistentConfigService/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import { AnnotationResponse } from "../AnnotationService";
2+
13
/**
24
* Keys for the data saved by this service
35
*/
46
export enum PersistedConfigKeys {
57
AllenMountPoint = "ALLEN_MOUNT_POINT",
68
CsvColumns = "CSV_COLUMNS",
9+
DisplayAnnotations = "DISPLAY_ANNOTATIONS",
710
ImageJExecutable = "IMAGE_J_EXECUTABLE", // Deprecated
811
HasUsedApplicationBefore = "HAS_USED_APPLICATION_BEFORE",
912
UserSelectedApplications = "USER_SELECTED_APPLICATIONS",
@@ -16,6 +19,7 @@ export interface UserSelectedApplication {
1619

1720
export interface PersistedConfig {
1821
[PersistedConfigKeys.CsvColumns]?: string[];
22+
[PersistedConfigKeys.DisplayAnnotations]?: AnnotationResponse[];
1923
[PersistedConfigKeys.ImageJExecutable]?: string; // Deprecated
2024
[PersistedConfigKeys.HasUsedApplicationBefore]?: boolean;
2125
[PersistedConfigKeys.UserSelectedApplications]?: UserSelectedApplication[];

packages/core/state/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { PersistedConfig, PersistedConfigKeys } from "../services/PersistentConf
88
import interaction, { InteractionStateBranch } from "./interaction";
99
import metadata, { MetadataStateBranch } from "./metadata";
1010
import selection, { SelectionStateBranch } from "./selection";
11+
import Annotation from "../entity/Annotation";
1112

1213
export { interaction, metadata, selection };
1314

@@ -63,6 +64,13 @@ export function createReduxStore(options: CreateStoreOptions = {}) {
6364
userSelectedApplications:
6465
persistedConfig && persistedConfig[PersistedConfigKeys.UserSelectedApplications],
6566
},
67+
selection: {
68+
displayAnnotations:
69+
persistedConfig &&
70+
persistedConfig[PersistedConfigKeys.DisplayAnnotations]?.map(
71+
(annotation) => new Annotation(annotation)
72+
),
73+
},
6674
});
6775
return configureStore<State>({
6876
middleware: [...(options.middleware || []), ...(middleware || [])],

packages/core/state/metadata/logics.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from "./actions";
1111
import { AnnotationName, TOP_LEVEL_FILE_ANNOTATIONS } from "../../constants";
1212
import AnnotationService from "../../services/AnnotationService";
13+
import Annotation from "../../entity/Annotation";
1314

1415
/**
1516
* Interceptor responsible for turning REQUEST_ANNOTATIONS action into a network call for available annotations. Outputs
@@ -20,14 +21,25 @@ const requestAnnotations = createLogic({
2021
const { getState, httpClient } = deps;
2122
const applicationVersion = interaction.selectors.getApplicationVersion(getState());
2223
const baseUrl = interaction.selectors.getFileExplorerServiceBaseUrl(getState());
24+
const displayAnnotations = selection.selectors.getAnnotationsToDisplay(getState());
2325
const annotationService = new AnnotationService({
2426
applicationVersion,
2527
baseUrl,
2628
httpClient,
2729
});
2830

31+
let annotations: Annotation[] = [];
32+
2933
try {
30-
const annotations = await annotationService.fetchAnnotations();
34+
annotations = await annotationService.fetchAnnotations();
35+
dispatch(receiveAnnotations(annotations));
36+
} catch (err) {
37+
console.error("Failed to fetch annotations", err);
38+
done();
39+
return;
40+
}
41+
42+
if (!displayAnnotations.length) {
3143
const defaultDisplayAnnotations = compact([
3244
find(
3345
TOP_LEVEL_FILE_ANNOTATIONS,
@@ -40,14 +52,9 @@ const requestAnnotations = createLogic({
4052
(annotation) => annotation.name === AnnotationName.FILE_SIZE
4153
),
4254
]);
43-
44-
dispatch(receiveAnnotations(annotations));
4555
dispatch(selection.actions.selectDisplayAnnotation(defaultDisplayAnnotations, true));
46-
} catch (err) {
47-
console.error("Failed to fetch annotations", err);
48-
} finally {
49-
done();
5056
}
57+
done();
5158
},
5259
type: REQUEST_ANNOTATIONS,
5360
});

packages/core/state/selection/actions.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,19 @@ export const DESELECT_DISPLAY_ANNOTATION = makeConstant(
157157
);
158158

159159
export interface DeselectDisplayAnnotationAction {
160-
payload: Annotation | Annotation[];
160+
payload: {
161+
annotation: Annotation | Annotation[];
162+
};
161163
type: string;
162164
}
163165

164166
export function deselectDisplayAnnotation(
165167
annotation: Annotation | Annotation[]
166168
): DeselectDisplayAnnotationAction {
167169
return {
168-
payload: annotation,
170+
payload: {
171+
annotation,
172+
},
169173
type: DESELECT_DISPLAY_ANNOTATION,
170174
};
171175
}

packages/core/state/selection/reducer.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { makeReducer } from "@aics/redux-utils";
2-
import { castArray, difference, omit, without } from "lodash";
2+
import { castArray, difference, omit } from "lodash";
33

44
import interaction from "../interaction";
55
import { AnnotationName, PAST_YEAR_FILTER } from "../../constants";
@@ -123,9 +123,9 @@ export default makeReducer<SelectionStateBranch>(
123123
sortColumn: action.payload,
124124
}),
125125
[DESELECT_DISPLAY_ANNOTATION]: (state, action) => {
126-
const displayAnnotations = without(
127-
state.displayAnnotations,
128-
...castArray(action.payload)
126+
// remove deselected annotation from state.displayAnnotations
127+
const displayAnnotations = state.displayAnnotations.filter(
128+
(annotation) => annotation.name !== action.payload.annotation.name
129129
);
130130

131131
const columnWidthsToPrune = difference(

packages/desktop/src/renderer/index.tsx

+10-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Provider } from "react-redux";
1010

1111
import FmsFileExplorer from "../../../core/App";
1212
import { PersistedConfigKeys } from "../../../core/services";
13-
import { createReduxStore, interaction } from "../../../core/state";
13+
import { createReduxStore, interaction, selection } from "../../../core/state";
1414

1515
import ApplicationInfoServiceElectron from "../services/ApplicationInfoServiceElectron";
1616
import ExecutionEnvServiceElectron from "../services/ExecutionEnvServiceElectron";
@@ -73,19 +73,20 @@ const store = createReduxStore({
7373
store.subscribe(() => {
7474
const state = store.getState();
7575
const csvColumns = interaction.selectors.getCsvColumns(state);
76+
const displayAnnotations = selection.selectors.getAnnotationsToDisplay(state);
7677
const userSelectedApplications = interaction.selectors.getUserSelectedApplications(state);
77-
const hasUsedApplicationBefore = interaction.selectors.hasUsedApplicationBefore(state);
7878
const appState = {
7979
[PersistedConfigKeys.CsvColumns]: csvColumns,
80+
[PersistedConfigKeys.DisplayAnnotations]: displayAnnotations.map((annotation) => ({
81+
annotationDisplayName: annotation.displayName,
82+
annotationName: annotation.name,
83+
description: annotation.description,
84+
type: annotation.type,
85+
})),
8086
[PersistedConfigKeys.UserSelectedApplications]: userSelectedApplications,
87+
[PersistedConfigKeys.HasUsedApplicationBefore]: true,
8188
};
82-
if (JSON.stringify(appState) !== JSON.stringify(persistentConfigService.getAll())) {
83-
persistentConfigService.persist({
84-
[PersistedConfigKeys.CsvColumns]: csvColumns,
85-
[PersistedConfigKeys.UserSelectedApplications]: userSelectedApplications,
86-
[PersistedConfigKeys.HasUsedApplicationBefore]: hasUsedApplicationBefore,
87-
});
88-
}
89+
persistentConfigService.persist(appState);
8990
});
9091

9192
function renderFmsFileExplorer() {

packages/desktop/src/services/PersistentConfigServiceElectron.ts

+20
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,26 @@ const OPTIONS: Options<Record<string, unknown>> = {
2222
type: "string",
2323
},
2424
},
25+
[PersistedConfigKeys.DisplayAnnotations]: {
26+
type: "array",
27+
items: {
28+
type: "object",
29+
properties: {
30+
annotationDisplayName: {
31+
type: "string",
32+
},
33+
annotationName: {
34+
type: "string",
35+
},
36+
description: {
37+
type: "string",
38+
},
39+
type: {
40+
type: "string",
41+
},
42+
},
43+
},
44+
},
2545
// ImageJExecutable is Deprecated
2646
[PersistedConfigKeys.ImageJExecutable]: {
2747
type: "string",

packages/desktop/src/services/test/PersistentConfigServiceElectron.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ describe(`${RUN_IN_RENDERER} PersistentConfigServiceElectron`, () => {
4545
name: "ZEN",
4646
},
4747
];
48+
49+
const expectedDisplayAnnotations = [
50+
{
51+
annotationDisplayName: "Foo",
52+
annotationName: "foo",
53+
description: "foo-long",
54+
type: "string",
55+
units: "string",
56+
},
57+
];
58+
4859
service.persist(PersistedConfigKeys.AllenMountPoint, expectedAllenMountPoint);
4960
service.persist(PersistedConfigKeys.CsvColumns, expectedCsvColumns);
5061
service.persist(PersistedConfigKeys.ImageJExecutable, expectedImageJExecutable);
@@ -53,12 +64,15 @@ describe(`${RUN_IN_RENDERER} PersistentConfigServiceElectron`, () => {
5364
expectedHasUsedApplicationBefore
5465
);
5566
service.persist(PersistedConfigKeys.UserSelectedApplications, expectedUserSelectedApps);
67+
service.persist(PersistedConfigKeys.DisplayAnnotations, expectedDisplayAnnotations);
68+
5669
const expectedConfig = {
5770
[PersistedConfigKeys.AllenMountPoint]: expectedAllenMountPoint,
5871
[PersistedConfigKeys.CsvColumns]: expectedCsvColumns,
5972
[PersistedConfigKeys.ImageJExecutable]: expectedImageJExecutable,
6073
[PersistedConfigKeys.HasUsedApplicationBefore]: expectedHasUsedApplicationBefore,
6174
[PersistedConfigKeys.UserSelectedApplications]: expectedUserSelectedApps,
75+
[PersistedConfigKeys.DisplayAnnotations]: expectedDisplayAnnotations,
6276
};
6377

6478
// Act
@@ -85,6 +99,15 @@ describe(`${RUN_IN_RENDERER} PersistentConfigServiceElectron`, () => {
8599
name: "ImageJ/Fiji",
86100
},
87101
],
102+
[PersistedConfigKeys.DisplayAnnotations]: [
103+
{
104+
annotationDisplayName: "Foo",
105+
annotationName: "foo",
106+
description: "foo-long",
107+
type: "string",
108+
units: "string",
109+
},
110+
],
88111
};
89112

90113
// Act

0 commit comments

Comments
 (0)