Skip to content

Commit 31c2b50

Browse files
authored
chore: Migrate interrelated jotai states (#4142)
* chore: migrate interrellated states * chore: migrate interrellated states * chore: further migration adjustments * chore: remove recoil * chore: adjust openapiPathIDSelector * chore: fix tiny migration error * chore: a couple more tiny adjustments * chore: adjust recoil format to jotai * merge main * chore: adjust format in remaining places
1 parent 6b98941 commit 31c2b50

File tree

230 files changed

+1256
-1506
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

230 files changed

+1256
-1506
lines changed

cypress/cypress.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ declare namespace Cypress {
55
/**
66
* Custom command to mount a React component with common providers
77
* @param component - React component to mount
8-
* @param options - Options for mount, may include initializeRecoil function
9-
* @example cy.mount(<MyComponent />, { initializeRecoil: (snapshot) => {...} })
8+
* @param options - Options for mount, may include initializeJotai function
9+
* @example cy.mount(<MyComponent />, { initializeJotai: [[atom, value]] })
1010
*/
1111
mount(
1212
component: React.ReactNode,
1313
options?: {
14-
initializeRecoil?: (snapshot: any) => void;
14+
initializeJotai?: Array<[any, any]>;
1515
[key: string]: any;
1616
},
1717
): Chainable<any>;

cypress/support/component.jsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import { mount } from 'cypress/react18';
33
import { ThemeProvider } from '@ui5/webcomponents-react';
44
import { MemoryRouter } from 'react-router';
5-
import { RecoilRoot } from 'recoil';
5+
import { Provider } from 'jotai';
6+
import { useHydrateAtoms } from 'jotai/utils';
67

78
import i18n from 'i18next';
89
import { I18nextProvider, initReactI18next } from 'react-i18next';
@@ -18,17 +19,25 @@ i18n.use(initReactI18next).init({
1819
},
1920
});
2021

22+
// Component to initialize Jotai atoms with test data
23+
function JotaiHydrator({ children, atomValues = [] }) {
24+
useHydrateAtoms(atomValues);
25+
return children;
26+
}
27+
2128
Cypress.Commands.add(
2229
'mount',
23-
(component, { initializeRecoil, ...options } = {}) => {
30+
(component, { initializeJotai, ...options } = {}) => {
2431
return mount(
25-
<RecoilRoot initializeState={initializeRecoil}>
26-
<I18nextProvider i18n={i18n}>
27-
<MemoryRouter>
28-
<ThemeProvider>{component}</ThemeProvider>
29-
</MemoryRouter>
30-
</I18nextProvider>
31-
</RecoilRoot>,
32+
<Provider>
33+
<JotaiHydrator atomValues={initializeJotai}>
34+
<I18nextProvider i18n={i18n}>
35+
<MemoryRouter>
36+
<ThemeProvider>{component}</ThemeProvider>
37+
</MemoryRouter>
38+
</I18nextProvider>
39+
</JotaiHydrator>
40+
</Provider>,
3241
options,
3342
);
3443
},

package-lock.json

Lines changed: 0 additions & 39 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
"react-router": "^7.5.2",
113113
"react-syntax-highlighter": "^15.6.1",
114114
"react-tippy": "^1.4.0",
115-
"recoil": "^0.7.7",
116115
"resize-observer-polyfill": "^1.5.1",
117116
"rfc6902": "^5.1.2",
118117
"url": "^0.11.4"

src/command-pallette/CommandPalletteUI/CommandPaletteSearchBar.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import { useEffect, RefObject, useState } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import { createPortal } from 'react-dom';
4-
import { useRecoilValue } from 'recoil';
54
import { useAtomValue } from 'jotai';
65
import { Icon, Input } from '@ui5/webcomponents-react';
76
import { K8sResource } from 'types';
87
import { useEventListener } from 'hooks/useEventListener';
98
import { useObjectState } from 'shared/useObjectState';
109
import { CommandPaletteUI } from './CommandPaletteUI';
11-
import { availableNodesSelector } from 'state/navigation/availableNodesSelector';
12-
import { showKymaCompanionState } from 'state/companion/showKymaCompanionAtom';
10+
import { showKymaCompanionAtom } from 'state/companion/showKymaCompanionAtom';
1311
import { SCREEN_SIZE_BREAKPOINT_M } from './types';
1412
import './CommandPaletteSearchBar.scss';
1513

@@ -26,14 +24,13 @@ export function CommandPaletteSearchBar({
2624
setShouldFocus,
2725
shellbarRef,
2826
}: CommandPaletteSearchBarProps) {
29-
useRecoilValue(availableNodesSelector); // preload the values to prevent page rerenders
3027
const { t } = useTranslation();
3128
const [open, setOpen] = useState(shouldFocus || false);
3229
const [shellbarWidth, setShellbarWidth] = useState(window.innerWidth);
3330
const [resourceCache, updateResourceCache] = useObjectState<
3431
Record<string, K8sResource[]>
3532
>();
36-
const showCompanion = useAtomValue(showKymaCompanionState);
33+
const showCompanion = useAtomValue(showKymaCompanionAtom);
3734
const shouldShowDialog = shouldFocus ? shouldFocus : open;
3835

3936
const htmlWrapEl = document.getElementById('html-wrap');

src/command-pallette/CommandPalletteUI/CommandPaletteUI.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import { ReactNode, useEffect, useRef, useState } from 'react';
2-
import { useRecoilValue } from 'recoil';
32
import { useAtomValue } from 'jotai';
43
import { useEventListener } from 'hooks/useEventListener';
54
import { getHistoryEntries } from './search-history';
6-
import { activeNamespaceIdState } from 'state/activeNamespaceIdAtom';
5+
import { activeNamespaceIdAtom } from 'state/activeNamespaceIdAtom';
76
import {
87
CommandPalletteHelp,
98
NamespaceContextDisplay,
@@ -14,12 +13,11 @@ import { ResultsList } from './ResultsList/ResultsList';
1413
import { useSearchResults } from './useSearchResults';
1514
import { K8sResource } from 'types';
1615
import { Button, Icon, Input } from '@ui5/webcomponents-react';
17-
import { showKymaCompanionState } from 'state/companion/showKymaCompanionAtom';
16+
import { showKymaCompanionAtom } from 'state/companion/showKymaCompanionAtom';
1817
import { SCREEN_SIZE_BREAKPOINT_M } from './types';
1918
import { useFormNavigation } from 'shared/hooks/useFormNavigation';
20-
21-
import './CommandPaletteUI.scss';
2219
import { activateResult, isResultGoingToRedirect } from './helpers';
20+
import './CommandPaletteUI.scss';
2321

2422
function Background({
2523
hide,
@@ -58,7 +56,7 @@ export function CommandPaletteUI({
5856
updateResourceCache,
5957
shellbarWidth,
6058
}: CommandPaletteProps) {
61-
const namespace = useRecoilValue(activeNamespaceIdState);
59+
const namespace = useAtomValue(activeNamespaceIdAtom);
6260
const { navigateSafely } = useFormNavigation();
6361

6462
const [query, setQuery] = useState('');
@@ -70,7 +68,7 @@ export function CommandPaletteUI({
7068
const [activeResultIndex, setActiveResultIndex] = useState(0);
7169
const [isHistoryMode, setHistoryMode] = useState(false);
7270
const [historyIndex, setHistoryIndex] = useState(0);
73-
const showCompanion = useAtomValue(showKymaCompanionState);
71+
const showCompanion = useAtomValue(showKymaCompanionAtom);
7472

7573
const commandPaletteRef = useRef<HTMLDivElement | null>(null);
7674

src/command-pallette/CommandPalletteUI/useSearchResults.tsx

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
import { useEffect } from 'react';
22
import { useTranslation } from 'react-i18next';
3-
import { useRecoilValue } from 'recoil';
43
import { useAtomValue, useSetAtom } from 'jotai';
5-
import { isPreferencesOpenState } from 'state/preferences/isPreferencesModalOpenAtom';
4+
import { isPreferencesOpenAtom } from 'state/preferences/isPreferencesModalOpenAtom';
65
import { useFetch } from 'shared/hooks/BackendAPI/useFetch';
7-
import { showHiddenNamespacesState } from 'state/preferences/showHiddenNamespacesAtom';
8-
import { columnLayoutState } from 'state/columnLayoutAtom';
6+
import { showHiddenNamespacesAtom } from 'state/preferences/showHiddenNamespacesAtom';
7+
import { columnLayoutAtom } from 'state/columnLayoutAtom';
98

109
import * as handlers from './handlers';
1110
import { useGetHiddenNamespaces } from 'shared/hooks/useGetHiddenNamespaces';
1211
import { K8sResource } from 'types';
13-
import { clustersState } from 'state/clustersAtom';
14-
import { clusterState } from 'state/clusterAtom';
15-
import { availableNodesSelector } from 'state/navigation/availableNodesSelector';
12+
import { clustersAtom } from 'state/clustersAtom';
13+
import { clusterAtom } from 'state/clusterAtom';
14+
import { availableNodesAtom } from 'state/navigation/availableNodesAtom';
1615
import { CommandPaletteContext, HelpEntries, Result } from './types';
1716
import { useClustersInfo } from 'state/utils/getClustersInfo';
1817
import { useNavigate, To } from 'react-router';
19-
import { showYamlUploadDialogState } from 'state/showYamlUploadDialogAtom';
18+
import { showYamlUploadDialogAtom } from 'state/showYamlUploadDialogAtom';
2019

2120
type useSearchResultsProps = {
2221
query: string;
@@ -40,18 +39,17 @@ export function useSearchResults({
4039
resourceCache,
4140
updateResourceCache,
4241
}: useSearchResultsProps): SearchResults {
43-
const clusters = useAtomValue(clustersState);
44-
45-
const cluster = useRecoilValue(clusterState);
46-
const availableNodes = useRecoilValue(availableNodesSelector);
47-
const setLayoutColumn = useSetAtom(columnLayoutState);
42+
const clusters = useAtomValue(clustersAtom);
43+
const cluster = useAtomValue(clusterAtom);
44+
const availableNodes = useAtomValue(availableNodesAtom);
45+
const setLayoutColumn = useSetAtom(columnLayoutAtom);
4846

4947
const hiddenNamespaces = useGetHiddenNamespaces();
50-
const showHiddenNamespaces = useRecoilValue(showHiddenNamespacesState);
48+
const showHiddenNamespaces = useAtomValue(showHiddenNamespacesAtom);
5149
const fetch = useFetch();
5250
const { t } = useTranslation();
53-
const setOpenPreferencesModal = useSetAtom(isPreferencesOpenState);
54-
const setShowYamlUpload = useSetAtom(showYamlUploadDialogState);
51+
const setOpenPreferencesModal = useSetAtom(isPreferencesOpenAtom);
52+
const setShowYamlUpload = useSetAtom(showYamlUploadDialogAtom);
5553
const clustersInfo = useClustersInfo();
5654
const navigate = useNavigate();
5755

src/components/App/App.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,15 @@ import {
88
useSearchParams,
99
} from 'react-router';
1010
import { useTranslation } from 'react-i18next';
11-
import { useRecoilValue, useSetRecoilState } from 'recoil';
12-
import { useAtom, useAtomValue } from 'jotai';
11+
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
1312

1413
import { useUrl } from 'hooks/useUrl';
1514
import { useSentry } from 'hooks/useSentry';
1615
import { useAppTracking } from 'hooks/tracking';
1716

18-
import { clusterState } from 'state/clusterAtom';
17+
import { clusterAtom } from 'state/clusterAtom';
1918
import { languageAtom } from 'state/preferences/languageAtom';
20-
import { activeNamespaceIdState } from 'state/activeNamespaceIdAtom';
19+
import { activeNamespaceIdAtom } from 'state/activeNamespaceIdAtom';
2120
import { useAuthHandler } from 'state/authDataAtom';
2221
import { useGetConfiguration } from 'state/configuration/configurationAtom';
2322
import { useGetExtensions } from 'state/navigation/extensionsAtom';
@@ -30,15 +29,15 @@ import { useResourceSchemas } from './resourceSchemas/useResourceSchemas';
3029
import { removePreviousPath, useAfterInitHook } from 'state/useAfterInitHook';
3130
import useSidebarCondensed from 'sidebar/useSidebarCondensed';
3231
import { useGetValidationEnabledSchemas } from 'state/validationEnabledSchemasAtom';
33-
import { multipleContexts } from 'state/multipleContextsAtom';
32+
import { multipleContextsAtom } from 'state/multipleContextsAtom';
3433

3534
import {
3635
Button,
3736
Dialog,
3837
SplitterElement,
3938
SplitterLayout,
4039
} from '@ui5/webcomponents-react';
41-
import { showKymaCompanionState } from 'state/companion/showKymaCompanionAtom';
40+
import { showKymaCompanionAtom } from 'state/companion/showKymaCompanionAtom';
4241
import KymaCompanion from 'components/KymaCompanion/components/KymaCompanion';
4342
import { Preferences } from 'components/Preferences/Preferences';
4443
import { Header } from 'header/Header';
@@ -50,30 +49,30 @@ import { IncorrectPath } from './IncorrectPath';
5049
import { Spinner } from 'shared/components/Spinner/Spinner';
5150
import { ContextChooserMessage } from 'components/Clusters/components/ContextChooser/ContextChooser';
5251

53-
import { themeState } from 'state/preferences/themeAtom';
52+
import { themeAtom } from 'state/preferences/themeAtom';
5453
import { initTheme } from './initTheme';
5554

5655
import './App.scss';
5756
import '../../web-components/index'; //Import for custom Web Components
58-
import { manualKubeConfigIdState } from 'state/manualKubeConfigIdAtom';
57+
import { manualKubeConfigIdAtom } from 'state/manualKubeConfigIdAtom';
5958
import { AuthForm } from 'components/Clusters/components/AuthForm';
6059
import { ResourceForm } from 'shared/ResourceForm';
6160
import { checkAuthRequiredInputs } from 'components/Clusters/helper';
6261

6362
export default function App() {
64-
const theme = useRecoilValue(themeState);
65-
const language = useRecoilValue(languageAtom);
66-
const cluster = useRecoilValue(clusterState);
67-
const setNamespace = useSetRecoilState(activeNamespaceIdState);
63+
const theme = useAtomValue(themeAtom);
64+
const language = useAtomValue(languageAtom);
65+
const cluster = useAtomValue(clusterAtom);
66+
const setNamespace = useSetAtom(activeNamespaceIdAtom);
6867
const { namespace } = useUrl();
6968
const makeGardenerLoginRoute = useMakeGardenerLoginRoute();
7069
const { t, i18n } = useTranslation();
7170
const navigate = useNavigate();
7271
const authFormRef = useRef<HTMLFormElement>(null);
7372
const [search] = useSearchParams();
74-
const [contextsState, setContextsState] = useAtom(multipleContexts);
73+
const [contextsState, setContextsState] = useAtom(multipleContextsAtom);
7574
const [manualKubeConfigId, setManualKubeConfigId] = useAtom(
76-
manualKubeConfigIdState,
75+
manualKubeConfigIdAtom,
7776
);
7877
const [authFormState, setAuthFormState] = useState<{
7978
users?: Users;
@@ -104,7 +103,7 @@ export default function App() {
104103
useAppTracking();
105104
useAfterInitHook(kubeconfigIdState);
106105

107-
const showCompanion = useAtomValue(showKymaCompanionState);
106+
const showCompanion = useAtomValue(showKymaCompanionAtom);
108107

109108
const updateManualKubeConfigIdState = (e: any) => {
110109
e.preventDefault();

0 commit comments

Comments
 (0)