From 402c980e94697ad01f387afb6a2e30c950461c6f Mon Sep 17 00:00:00 2001 From: Joe Heffernan Date: Fri, 22 Nov 2024 17:04:53 -0800 Subject: [PATCH] add button for previewing and resetting selected display data --- src/containers/ModelPanel/index.tsx | 44 ++++++++++- .../compoundSelectors.test.ts | 75 ++++++++++++++++++- src/state/compoundSelectors/index.ts | 15 ++++ src/state/selection/actions.ts | 7 ++ src/state/selection/constants.ts | 3 + src/state/selection/logics.ts | 26 ++++++- 6 files changed, 163 insertions(+), 7 deletions(-) diff --git a/src/containers/ModelPanel/index.tsx b/src/containers/ModelPanel/index.tsx index 7c742825..8a12965a 100644 --- a/src/containers/ModelPanel/index.tsx +++ b/src/containers/ModelPanel/index.tsx @@ -3,6 +3,7 @@ import { ActionCreator } from "redux"; import { connect } from "react-redux"; import { State } from "../../state/types"; +import { getDefaultUISettingsApplied } from "../../state/compoundSelectors"; import { ViewerStatus } from "../../state/viewer/types"; import { getStatus } from "../../state/viewer/selectors"; import { RequestNetworkFileAction } from "../../state/trajectory/types"; @@ -17,6 +18,9 @@ import { SetVisibleAction, SetRecentColorsAction, HandleColorChangeAction, + ColorSetting, + SetCurrentColorSettingAction, + ResetAction, } from "../../state/selection/types"; import { turnAgentsOnByDisplayKey, @@ -24,6 +28,8 @@ import { setAgentsVisible, setRecentColors, handleColorChange, + setCurrentColorSetting, + clearUserSelectedColors, } from "../../state/selection/actions"; import { getAgentVisibilityMap, @@ -36,7 +42,8 @@ import NoTrajectoriesText from "../../components/NoTrajectoriesText"; import NetworkFileFailedText from "../../components/NoTrajectoriesText/NetworkFileFailedText"; import NoTypeMappingText from "../../components/NoTrajectoriesText/NoTypeMappingText"; import SideBarContents from "../../components/SideBarContents"; -import { AgentMetadata } from "../../constants/interfaces"; +import NavButton from "../../components/NavButton"; +import { AgentMetadata, ButtonClass } from "../../constants/interfaces"; import { getSelectAllVisibilityMap, getSelectNoneVisibilityMap, @@ -63,6 +70,9 @@ interface ModelPanelProps { setRecentColors: ActionCreator; selectedAgentMetadata: AgentMetadata; handleColorChange: ActionCreator; + defaultUiSettingsApplied: boolean; + setCurrentColorSetting: ActionCreator; + clearUserSelectedColors: ActionCreator; } const ModelPanel: React.FC = ({ @@ -82,6 +92,9 @@ const ModelPanel: React.FC = ({ setRecentColors, selectedAgentMetadata, handleColorChange, + defaultUiSettingsApplied, + setCurrentColorSetting, + clearUserSelectedColors, }): JSX.Element => { const checkboxTree = ( = ({ ), }; + const handlePreviewDefaultColors = (colorSetting: ColorSetting) => { + if (!defaultUiSettingsApplied) { + setCurrentColorSetting({ currentColorSetting: colorSetting }); + } + }; + return (
+ {contentMap[viewerStatus]} + + handlePreviewDefaultColors(ColorSetting.Default) + } + onMouseLeave={() => + handlePreviewDefaultColors( + ColorSetting.UserSelected + ) + } + /> +
, + ]} selectedAgentMetadata={selectedAgentMetadata} uiDisplayData={uiDisplayDataTree} /> @@ -136,6 +173,7 @@ function mapStateToProps(state: State) { isNetworkedFile: getIsNetworkedFile(state), recentColors: getRecentColors(state), selectedAgentMetadata: getSelectedAgentMetadata(state), + defaultUiSettingsApplied: getDefaultUISettingsApplied(state), }; } @@ -147,6 +185,8 @@ const dispatchToPropsMap = { setAgentsVisible, setRecentColors, handleColorChange, + setCurrentColorSetting, + clearUserSelectedColors, }; export default connect(mapStateToProps, dispatchToPropsMap)(ModelPanel); diff --git a/src/state/compoundSelectors/compoundSelectors.test.ts b/src/state/compoundSelectors/compoundSelectors.test.ts index 008ca7ff..4711fd0e 100644 --- a/src/state/compoundSelectors/compoundSelectors.test.ts +++ b/src/state/compoundSelectors/compoundSelectors.test.ts @@ -1,4 +1,4 @@ -import { getCurrentUIData } from "."; +import { getCurrentUIData, getDefaultUISettingsApplied } from "."; import { initialState } from ".."; import { ColorSetting } from "../selection/types"; @@ -77,3 +77,76 @@ describe("getCurrentUIData", () => { ]); }); }); + +describe("getDefaultUISettingsApplied", () => { + it("returns false if selectedUIDisplayData contains selections and selectedUIDisplayData and defaultUIData are not equal", () => { + expect( + getDefaultUISettingsApplied({ + ...initialState, + trajectory: { + defaultUIData: [ + { + name: "agent1", + displayStates: [], + color: "#bbbbbb", + }, + ], + }, + selection: { + ...initialState.selection, + selectedUIDisplayData: [ + { + name: "agent1", + displayStates: [], + color: "#000", + }, + ], + }, + }) + ).toBe(false); + }); + it("returns true if selectedUIDisplayData contains no selections", () => { + expect( + getDefaultUISettingsApplied({ + ...initialState, + trajectory: { + defaultUIData: [ + { + name: "agent1", + displayStates: [], + color: "#bbbbbb", + }, + ], + }, + selection: { + selectedUIDisplayData: [], + }, + }) + ).toBe(true); + }); + it("returns true if selectedUIDisplayData and defaultUIData are equal", () => { + expect( + getDefaultUISettingsApplied({ + ...initialState, + trajectory: { + defaultUIData: [ + { + name: "agent1", + displayStates: [], + color: "#bbbbbb", + }, + ], + }, + selection: { + selectedUIDisplayData: [ + { + name: "agent1", + displayStates: [], + color: "#bbbbbb", + }, + ], + }, + }) + ).toBe(true); + }); +}); diff --git a/src/state/compoundSelectors/index.ts b/src/state/compoundSelectors/index.ts index 144687d4..952897e4 100644 --- a/src/state/compoundSelectors/index.ts +++ b/src/state/compoundSelectors/index.ts @@ -1,5 +1,6 @@ import { createSelector } from "reselect"; import { UIDisplayData } from "@aics/simularium-viewer"; +import { isEqual } from "lodash"; import { getDefaultUIDisplayData } from "../trajectory/selectors"; import { @@ -20,3 +21,17 @@ export const getCurrentUIData = createSelector( : defaultData; } ); + +export const getDefaultUISettingsApplied = createSelector( + [getSelectedUIDisplayData, getDefaultUIDisplayData], + (selectedUIDisplayData, defaultUIData) => { + /** + * we can't just check if currentColorSettings === ColorSettings.Default + * because that state can be used to preview settings + */ + return ( + selectedUIDisplayData.length === 0 || + isEqual(selectedUIDisplayData, defaultUIData) + ); + } +); diff --git a/src/state/selection/actions.ts b/src/state/selection/actions.ts index c384b98c..70c71506 100644 --- a/src/state/selection/actions.ts +++ b/src/state/selection/actions.ts @@ -14,6 +14,7 @@ import { GET_DISPLAY_DATA_FROM_BROWSER, SET_CURRENT_COLOR_SETTINGS, HANDLE_COLOR_CHANGE, + CLEAR_UI_DATA_FROM_STATE, } from "./constants"; import { ChangeAgentsRenderingStateAction, @@ -136,3 +137,9 @@ export function setCurrentColorSetting(payload: { type: SET_CURRENT_COLOR_SETTINGS, }; } + +export function clearUserSelectedColors(): ResetAction { + return { + type: CLEAR_UI_DATA_FROM_STATE, + }; +} diff --git a/src/state/selection/constants.ts b/src/state/selection/constants.ts index f72230fc..4db22ba1 100644 --- a/src/state/selection/constants.ts +++ b/src/state/selection/constants.ts @@ -32,3 +32,6 @@ export const GET_DISPLAY_DATA_FROM_BROWSER = makeSelectConstant( export const SET_CURRENT_COLOR_SETTINGS = makeSelectConstant( "set-current-color-settings" ); +export const CLEAR_UI_DATA_FROM_STATE = makeSelectConstant( + "clear-ui-data-from-state" +); diff --git a/src/state/selection/logics.ts b/src/state/selection/logics.ts index c8a85f22..1258402e 100644 --- a/src/state/selection/logics.ts +++ b/src/state/selection/logics.ts @@ -9,6 +9,7 @@ import { getCurrentUIData } from "../compoundSelectors"; import { GET_DISPLAY_DATA_FROM_BROWSER, HANDLE_COLOR_CHANGE, + CLEAR_UI_DATA_FROM_STATE, } from "./constants"; import { setCurrentColorSetting, setSelectedUIDisplayData } from "./actions"; import { applyColorChangeToUiDisplayData, isSameAgentTree } from "../../util"; @@ -57,9 +58,6 @@ const getDisplayDataFromBrowserLogic = createLogic({ ); reject(action); } - setCurrentColorSetting({ - currentColorSetting: ColorSetting.UserSelected, - }); allow(setSelectedUIDisplayData(storedUIData)); }, process() { @@ -70,4 +68,24 @@ const getDisplayDataFromBrowserLogic = createLogic({ type: GET_DISPLAY_DATA_FROM_BROWSER, }); -export default [handleColorChangeLogic, getDisplayDataFromBrowserLogic]; +export const resetSelectedUIDisplayDataLogic = createLogic({ + process(deps: ReduxLogicDeps, dispatch, done) { + const { getState } = deps; + const fileKey = getSimulariumFile(getState()).name; + localStorage.removeItem(fileKey); + dispatch( + setCurrentColorSetting({ + currentColorSetting: ColorSetting.Default, + }) + ); + dispatch(setSelectedUIDisplayData([])); + done(); + }, + type: CLEAR_UI_DATA_FROM_STATE, +}); + +export default [ + handleColorChangeLogic, + getDisplayDataFromBrowserLogic, + resetSelectedUIDisplayDataLogic, +];