diff --git a/frontend/src/components/App/PluginSettings/PluginSettings.tsx b/frontend/src/components/App/PluginSettings/PluginSettings.tsx index ca2a9ec815..0cfde7e8a7 100644 --- a/frontend/src/components/App/PluginSettings/PluginSettings.tsx +++ b/frontend/src/components/App/PluginSettings/PluginSettings.tsx @@ -93,6 +93,7 @@ const EnableSwitch = (props: SwitchProps) => { /** PluginSettingsPure is the main component to where we render the plugin data. */ export function PluginSettingsPure(props: PluginSettingsPureProps) { const { t } = useTranslation(['translation']); + const dispatch = useDispatch(); /** Plugin arr to be rendered to the page from prop data */ const pluginArr: any = props.plugins ? props.plugins : []; @@ -118,6 +119,36 @@ export function PluginSettingsPure(props: PluginSettingsPureProps) { }) ); + /** + * This is the name and isEnabled parts from the plugin JSON data that is saved in local storage + */ + const [pluginsEnabledSettings, setPluginsEnabledSettings] = useState( + useTypedSelector(state => state.plugins?.pluginSettings) + ); + + /** + * If there are no settings to be saved on local storage, then the default isEnabled from the plugins settings are saved. + */ + if (pluginsEnabledSettings.length === 0) { + storeEnableSettings(); + } + + /** + * This function is what trims the JSON data for the plugin into a smaller object to be used in local storage + */ + function storeEnableSettings() { + const pendingSettings = pluginChanges.map((plugin: PluginInfo) => { + return { + name: plugin.name, + isEnabled: plugin.isEnabled, + }; + }); + + setPluginsEnabledSettings(pendingSettings); + + dispatch(setPluginSettings(pendingSettings)); + } + /** * useEffect to control the rendering of the save button. * By default, the enableSave is set to false. @@ -154,6 +185,7 @@ export function PluginSettingsPure(props: PluginSettingsPureProps) { * This function then takes the current state of the pluginChanges array and inputs it to the onSave prop function. */ function onSaveButtonHandler() { + storeEnableSettings(); props.onSave(pluginChanges); } @@ -283,13 +315,12 @@ export function PluginSettingsPure(props: PluginSettingsPureProps) { export default function PluginSettings() { const dispatch = useDispatch(); - const pluginSettings = useTypedSelector(state => state.plugins.pluginSettings); + const pluginData = useTypedSelector(state => state.plugins.pluginData); return ( { - dispatch(setPluginSettings(plugins)); + plugins={pluginData} + onSave={() => { dispatch(reloadPage()); }} /> diff --git a/frontend/src/plugin/Plugins.tsx b/frontend/src/plugin/Plugins.tsx index 46521ec7b5..e78d1bdde5 100644 --- a/frontend/src/plugin/Plugins.tsx +++ b/frontend/src/plugin/Plugins.tsx @@ -8,7 +8,7 @@ import helpers from '../helpers'; import { UI_INITIALIZE_PLUGIN_VIEWS } from '../redux/actions/actions'; import { useTypedSelector } from '../redux/reducers/reducers'; import { fetchAndExecutePlugins } from './index'; -import { pluginsLoaded, setPluginSettings } from './pluginsSlice'; +import { pluginsLoaded, setPluginData } from './pluginsSlice'; /** * For discovering and executing plugins. @@ -35,7 +35,7 @@ export default function Plugins() { fetchAndExecutePlugins( settingsPlugins, updatedSettingsPackages => { - dispatch(setPluginSettings(updatedSettingsPackages)); + dispatch(setPluginData(updatedSettingsPackages)); }, incompatiblePlugins => { const pluginList = Object.values(incompatiblePlugins) diff --git a/frontend/src/plugin/pluginSlice.test.tsx b/frontend/src/plugin/pluginSlice.test.tsx index 805f6f31e3..8dbde098b4 100644 --- a/frontend/src/plugin/pluginSlice.test.tsx +++ b/frontend/src/plugin/pluginSlice.test.tsx @@ -12,6 +12,8 @@ const initialState: PluginsState = { loaded: false, /** If plugin settings are saved use those. */ pluginSettings: JSON.parse(localStorage.getItem('headlampPluginSettings') || '[]'), + /** Information stored by settings about plugins. */ + pluginData: [], }; // Mock React component for testing @@ -24,7 +26,7 @@ describe('pluginsSlice reducers', () => { const existingPluginName = 'test-plugin'; const initialStateWithPlugin: PluginsState = { ...initialState, - pluginSettings: [ + pluginData: [ { name: existingPluginName, settingsComponent: undefined, @@ -41,15 +43,15 @@ describe('pluginsSlice reducers', () => { const newState = pluginsSlice.reducer(initialStateWithPlugin, action); - expect(newState.pluginSettings[0].settingsComponent).toBeDefined(); - expect(newState.pluginSettings[0].displaySettingsComponentWithSaveButton).toBe(true); + expect(newState.pluginData[0].settingsComponent).toBeDefined(); + expect(newState.pluginData[0].displaySettingsComponentWithSaveButton).toBe(true); }); test('should not modify state when plugin name does not match any existing plugin', () => { const nonExistingPluginName = 'non-existing-plugin'; const initialStateWithPlugin: PluginsState = { ...initialState, - pluginSettings: [ + pluginData: [ { name: 'existing-plugin', settingsComponent: undefined, diff --git a/frontend/src/plugin/pluginsSlice.ts b/frontend/src/plugin/pluginsSlice.ts index 37e3277ac0..890ea796a2 100644 --- a/frontend/src/plugin/pluginsSlice.ts +++ b/frontend/src/plugin/pluginsSlice.ts @@ -92,12 +92,16 @@ export interface PluginsState { loaded: boolean; /** Information stored by settings about plugins. */ pluginSettings: PluginInfo[]; + /** Information stored by settings about plugins. */ + pluginData: PluginInfo[]; } const initialState: PluginsState = { /** Once the plugins have been fetched and executed. */ loaded: false, /** If plugin settings are saved use those. */ pluginSettings: JSON.parse(localStorage.getItem('headlampPluginSettings') || '[]'), + /** If plugin data is saved use those. */ + pluginData: [], }; export const pluginsSlice = createSlice({ @@ -114,6 +118,10 @@ export const pluginsSlice = createSlice({ state.pluginSettings = action.payload; localStorage.setItem('headlampPluginSettings', JSON.stringify(action.payload)); }, + /** Sets the plugin data */ + setPluginData(state, action: PayloadAction) { + state.pluginData = action.payload; + }, /** Reloads the browser page */ reloadPage() { window.location.reload(); @@ -130,7 +138,7 @@ export const pluginsSlice = createSlice({ }> ) { const { name, component, displaySaveButton } = action.payload; - state.pluginSettings = state.pluginSettings.map(plugin => { + state.pluginData = state.pluginData?.map(plugin => { if (plugin.name === name) { return { ...plugin, @@ -144,7 +152,12 @@ export const pluginsSlice = createSlice({ }, }); -export const { pluginsLoaded, setPluginSettings, setPluginSettingsComponent, reloadPage } = - pluginsSlice.actions; +export const { + pluginsLoaded, + setPluginSettings, + setPluginData, + setPluginSettingsComponent, + reloadPage, +} = pluginsSlice.actions; export default pluginsSlice.reducer;