Skip to content

Commit

Permalink
Merge pull request #1440 from headlamp-k8s/config-modernization
Browse files Browse the repository at this point in the history
frontend: redux/configSlice: Refactor config into a configSlice
  • Loading branch information
illume authored Oct 6, 2023
2 parents 0f09b81 + d1b1ef9 commit 2816a89
Show file tree
Hide file tree
Showing 17 changed files with 95 additions and 94 deletions.
4 changes: 2 additions & 2 deletions frontend/src/components/App/Home/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { configureStore } from '@reduxjs/toolkit';
import { Meta, Story } from '@storybook/react/types-6-0';
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import { INITIAL_STATE } from '../../../redux/reducers/config';
import { initialState } from '../../../redux/configSlice';
import Home from '.';

const ourState = {
config: {
...INITIAL_STATE,
...initialState,
clusters: [
{
name: 'cluster0',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/App/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ApiError, deleteCluster } from '../../../lib/k8s/apiProxy';
import { Cluster } from '../../../lib/k8s/cluster';
import { createRouteURL } from '../../../lib/router';
import { useFilterFunc, useId } from '../../../lib/util';
import { setConfig } from '../../../redux/actions/actions';
import { setConfig } from '../../../redux/configSlice';
import { Link, PageGrid, SectionBox, SectionFilterHeader } from '../../common';
import ResourceTable from '../../common/Resource/ResourceTable';
import RecentClusters from './RecentClusters';
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/App/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { useDispatch } from 'react-redux';
import { request } from '../../lib/k8s/apiProxy';
import { Cluster } from '../../lib/k8s/cluster';
import { getCluster } from '../../lib/util';
import { setConfig } from '../../redux/actions/actions';
import { ConfigState } from '../../redux/reducers/config';
import { setConfig } from '../../redux/configSlice';
import { ConfigState } from '../../redux/configSlice';
import { useTypedSelector } from '../../redux/reducers/reducers';
import store from '../../redux/stores/store';
import ActionsNotifier from '../common/ActionsNotifier';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/App/Notifications/List.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { configureStore } from '@reduxjs/toolkit';
import { Meta, Story } from '@storybook/react/types-6-0';
import helpers from '../../../helpers';
import { Notification } from '../../../lib/notification';
import { INITIAL_STATE as CONFIG_INITIAL_STATE } from '../../../redux/reducers/config';
import { initialState as CONFIG_INITIAL_STATE } from '../../../redux/configSlice';
import { INITIAL_STATE as FILTER_INITIAL_STATE } from '../../../redux/reducers/filter';
import { INITIAL_STATE as UI_INITIAL_STATE } from '../../../redux/reducers/ui';
import { TestContext } from '../../../test';
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/App/Settings/NumRowsInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { ChangeEvent, useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import helpers from '../../../helpers';
import { setAppSettings } from '../../../redux/actions/actions';
import { defaultTableRowsPerPageOptions } from '../../../redux/reducers/config';
import { setAppSettings } from '../../../redux/configSlice';
import { defaultTableRowsPerPageOptions } from '../../../redux/configSlice';

export default function NumRowsInput(props: { defaultValue: number[] }) {
const { t } = useTranslation(['frequent', 'settings']);
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/App/Settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import LocaleSelect from '../../../i18n/LocaleSelect/LocaleSelect';
import { setAppSettings, setVersionDialogOpen } from '../../../redux/actions/actions';
import { defaultTableRowsPerPageOptions } from '../../../redux/reducers/config';
import { setVersionDialogOpen } from '../../../redux/actions/actions';
import { setAppSettings } from '../../../redux/configSlice';
import { defaultTableRowsPerPageOptions } from '../../../redux/configSlice';
import { ActionButton, NameValueTable, SectionBox } from '../../common';
import TimezoneSelect from '../../common/TimezoneSelect';
import { useSettings } from './hook';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/App/Settings/SettingsCluster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useHistory } from 'react-router-dom';
import helpers, { ClusterSettings } from '../../../helpers';
import { useCluster, useClustersConf } from '../../../lib/k8s';
import { deleteCluster } from '../../../lib/k8s/apiProxy';
import { setConfig } from '../../../redux/actions/actions';
import { setConfig } from '../../../redux/configSlice';
import { Link, NameValueTable, SectionBox } from '../../common';
import ConfirmButton from '../../common/ConfirmButton';

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/Sidebar/Sidebar.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { configureStore } from '@reduxjs/toolkit';
import { Meta, Story } from '@storybook/react/types-6-0';
import { SnackbarProvider } from 'notistack';
import { INITIAL_STATE } from '../../redux/reducers/config';
import { initialState as CONFIG_INITIAL_STATE } from '../../redux/configSlice';
import { INITIAL_STATE as FILTER_INITIAL_STATE } from '../../redux/reducers/filter';
import { INITIAL_STATE as UI_INITIAL_STATE, UIState } from '../../redux/reducers/ui';
import { TestContext } from '../../test';
Expand Down Expand Up @@ -29,7 +29,7 @@ const Template: Story<StoryProps> = args => {
loaded: true,
},
config: {
...INITIAL_STATE,
...CONFIG_INITIAL_STATE,
},
filter: {
...FILTER_INITIAL_STATE,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/authchooser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useClustersConf } from '../../lib/k8s';
import { testAuth } from '../../lib/k8s/apiProxy';
import { createRouteURL, getRoute, getRoutePath } from '../../lib/router';
import { getCluster, getClusterPrefixedPath } from '../../lib/util';
import { setConfig } from '../../redux/actions/actions';
import { setConfig } from '../../redux/configSlice';
import { ClusterDialog } from '../cluster/Chooser';
import { Link, Loader } from '../common';
import { DialogTitle } from '../common/Dialog';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { configureStore } from '@reduxjs/toolkit';
import { Meta, Story } from '@storybook/react/types-6-0';
import React from 'react';
import { Cluster } from '../../lib/k8s/cluster';
import { INITIAL_STATE } from '../../redux/reducers/config';
import { initialState } from '../../redux/configSlice';
import { TestContext } from '../../test';
import ClusterChooserPopup from './ClusterChooserPopup';

const ourState = (clusters?: Cluster[]) => ({
config: {
...INITIAL_STATE,
...initialState,
clusters: clusters || [
{
name: 'cluster0',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/cluster/KubeConfigLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { setCluster } from '../../lib/k8s/apiProxy';
import { setConfig } from '../../redux/actions/actions';
import { setConfig } from '../../redux/configSlice';
import { DialogTitle } from '../common/Dialog';
import Loader from '../common/Loader';
import { ClusterDialog } from './Chooser';
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/k8s/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'lodash';
import React from 'react';
import { matchPath, useLocation } from 'react-router-dom';
import { ConfigState } from '../../redux/reducers/config';
import { ConfigState } from '../../redux/configSlice';
import { useTypedSelector } from '../../redux/reducers/reducers';
import { getCluster, getClusterPrefixedPath } from '../util';
import { ApiError, clusterRequest } from './apiProxy';
Expand Down
10 changes: 0 additions & 10 deletions frontend/src/redux/actions/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export const FILTER_SET_SEARCH = 'FILTER_SET_SEARCH';
export const CLUSTER_ACTION = 'CLUSTER_ACTION';
export const CLUSTER_ACTION_UPDATE = 'CLUSTER_ACTION_UPDATE';
export const CLUSTER_ACTION_CANCEL = 'CLUSTER_ACTION_CANCEL';
export const CONFIG_NEW = 'CONFIG_NEW';
export const UI_SIDEBAR_SET_SELECTED = 'UI_SIDEBAR_SET_SELECTED';
export const UI_SIDEBAR_SET_VISIBLE = 'UI_SIDEBAR_SET_VISIBLE';
export const UI_SIDEBAR_SET_ITEM = 'UI_SIDEBAR_SET_ITEM';
Expand All @@ -35,7 +34,6 @@ export const UI_BRANDING_SET_APP_LOGO = 'UI_BRANDING_SET_APP_LOGO';
export const UI_SET_CLUSTER_CHOOSER_BUTTON = 'UI_SET_CLUSTER_CHOOSER_BUTTON';
export const UI_HIDE_APP_BAR = 'UI_HIDE_APP_BAR';
export const UI_FUNCTIONS_OVERRIDE = 'UI_FUNCTIONS_OVERRIDE';
export const CONFIG_SET_SETTINGS = 'CONFIG_SET_SETTINGS';

export interface BrandingProps {
logo: AppLogoType;
Expand Down Expand Up @@ -182,10 +180,6 @@ export function setDetailsView(viewSection: DetailsViewSectionType) {
};
}

export function setConfig(config: object) {
return { type: CONFIG_NEW, config };
}

export function setTheme(name?: string) {
return { type: UI_THEME_SET, theme: { name } };
}
Expand Down Expand Up @@ -216,7 +210,3 @@ export type FunctionsToOverride = {
export function setFunctionsToOverride(override: FunctionsToOverride) {
return { type: UI_FUNCTIONS_OVERRIDE, override };
}

export function setAppSettings(settings: { [key: string]: any }) {
return { type: CONFIG_SET_SETTINGS, settings };
}
73 changes: 73 additions & 0 deletions frontend/src/redux/configSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { Cluster } from '../lib/k8s/cluster';

export interface ConfigState {
/**
* Clusters is a map of cluster names to cluster objects.
* Null indicates that the clusters have not been loaded yet.
*/
clusters: {
[clusterName: string]: Cluster;
} | null;
/**
* Settings is a map of settings names to settings values.
*/
settings: {
/**
* tableRowsPerPageOptions is the list of options for the number of rows per page in a table.
*/
tableRowsPerPageOptions: number[];
/**
* timezone is the timezone to use for displaying dates and times.
*/
timezone: string;
[key: string]: any;
};
}

export const defaultTableRowsPerPageOptions = [15, 25, 50];

function defaultTimezone() {
return process.env.UNDER_TEST ? 'UTC' : Intl.DateTimeFormat().resolvedOptions().timeZone;
}

const storedSettings = JSON.parse(localStorage.getItem('settings') || '{}');

export const initialState: ConfigState = {
clusters: null,
settings: {
tableRowsPerPageOptions:
storedSettings.tableRowsPerPageOptions || defaultTableRowsPerPageOptions,
timezone: storedSettings.timezone || defaultTimezone(),
},
};

const configSlice = createSlice({
name: 'config',
initialState,
reducers: {
/**
* Save the config. To both the store, and localStorage.
* @param state - The current state.
* @param action - The payload action containing the config.
*/
setConfig(state, action: PayloadAction<{ clusters: ConfigState['clusters'] }>) {
state.clusters = action.payload.clusters;
},
/**
* Save the settings. To both the store, and localStorage.
* @param state - The current state.
* @param action - The payload action containing the settings.
*/
setAppSettings(state, action: PayloadAction<Partial<ConfigState['settings']>>) {
Object.keys(action.payload).forEach(key => {
state.settings[key] = action.payload[key];
});
localStorage.setItem('settings', JSON.stringify(state.settings));
},
},
});

export const { setConfig, setAppSettings } = configSlice.actions;

export default configSlice.reducer;
63 changes: 0 additions & 63 deletions frontend/src/redux/reducers/config.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions frontend/src/redux/reducers/reducers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import { TypedUseSelectorHook, useSelector } from 'react-redux';
import { combineReducers } from 'redux';
import pluginsReducer from '../../plugin/pluginsSlice';
import actionButtons from '../actionButtonsSlice';
import configReducer from '../configSlice';
import detailsViewSectionsSlice from '../detailsViewSectionsSlice';
import clusterAction from './clusterAction';
import config from './config';
import filter from './filter';
import uiReducer from './ui';

const reducers = combineReducers({
filter: filter,
ui: uiReducer,
clusterAction: clusterAction,
config: config,
config: configReducer,
plugins: pluginsReducer,
actionButtons: actionButtons,
detailsViewSections: detailsViewSectionsSlice,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/redux/stores/store.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { configureStore } from '@reduxjs/toolkit';
import createSagaMiddleware from 'redux-saga';
import { INITIAL_STATE as CONFIG_INITIAL_STATE } from '../reducers/config';
import { initialState as CONFIG_INITIAL_STATE } from '../configSlice';
import { INITIAL_STATE as FILTER_INITIAL_STATE } from '../reducers/filter';
import reducers from '../reducers/reducers';
import { INITIAL_STATE as UI_INITIAL_STATE } from '../reducers/ui';
Expand Down

0 comments on commit 2816a89

Please sign in to comment.