refactor(environments): use tabState.environment.tab for env tabs (#8528)

* refactor(environments): use tabState.environment.tab for env tabs

* add: playwright test

* fix

* rm: only

* rm: tabs container style

* add: style
This commit is contained in:
Pooja
2026-07-09 00:03:20 +05:30
committed by GitHub
parent 12961db95d
commit d5b9d0a677
7 changed files with 74 additions and 6 deletions

View File

@@ -28,8 +28,8 @@ const EnvironmentDetails = ({ environment, setIsModified, collection, searchQuer
const [newName, setNewName] = useState('');
const [nameError, setNameError] = useState('');
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const activeTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.envTab) || 'variables';
const setActiveTab = (tab) => dispatch(updateTabState({ uid: activeTabUid, tabState: { envTab: tab } }));
const activeTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.environment?.tab) || 'variables';
const setActiveTab = (tab) => dispatch(updateTabState({ uid: activeTabUid, tabState: { environment: { tab } } }));
// Use the immediate query on a tab switch (debounced value lags and briefly
// flashes the unfiltered table).

View File

@@ -43,7 +43,7 @@ const EnvironmentList = ({
}) => {
const dispatch = useDispatch();
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const activeEnvTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.envTab) || 'variables';
const activeEnvTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.environment?.tab) || 'variables';
const envSearchQuery = useSelector((state) => state.app.envVarSearch?.collection?.[activeEnvTab]?.query ?? '');
const isEnvSearchExpanded = useSelector((state) => state.app.envVarSearch?.collection?.[activeEnvTab]?.expanded ?? false);
const setEnvSearchQuery = (q) => dispatch(setEnvVarSearchQuery({ context: 'collection', tab: activeEnvTab, query: q }));

View File

@@ -28,8 +28,8 @@ const EnvironmentDetails = ({ environment, setIsModified, collection, searchQuer
const [newName, setNewName] = useState('');
const [nameError, setNameError] = useState('');
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const activeTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.envTab) || 'variables';
const setActiveTab = (tab) => dispatch(updateTabState({ uid: activeTabUid, tabState: { envTab: tab } }));
const activeTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.environment?.tab) || 'variables';
const setActiveTab = (tab) => dispatch(updateTabState({ uid: activeTabUid, tabState: { environment: { tab } } }));
// Use the immediate query on a tab switch (debounced value lags and briefly
// flashes the unfiltered table).

View File

@@ -44,7 +44,7 @@ const EnvironmentList = ({
const dispatch = useDispatch();
const globalEnvs = useSelector((state) => state?.globalEnvironments?.globalEnvironments);
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const activeEnvTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.envTab) || 'variables';
const activeEnvTab = useSelector((state) => state.tabs.tabs.find((t) => t.uid === activeTabUid)?.tabState?.environment?.tab) || 'variables';
const envSearchQuery = useSelector((state) => state.app.envVarSearch?.global?.[activeEnvTab]?.query ?? '');
const isEnvSearchExpanded = useSelector((state) => state.app.envVarSearch?.global?.[activeEnvTab]?.expanded ?? false);
const setEnvSearchQuery = (q) => dispatch(setEnvVarSearchQuery({ context: 'global', tab: activeEnvTab, query: q }));

View File

@@ -472,6 +472,11 @@ export const serializeTab = (tab, collection) => {
};
}
const isEnvironmentTab = tab.type === 'environment-settings' || tab.type === 'global-environment-settings';
if (isEnvironmentTab && tab.tabState?.environment?.tab) {
serialized.environment = { tab: tab.tabState.environment.tab };
}
return serialized;
};
@@ -650,6 +655,10 @@ export const deserializeTab = (snapshotTab, collection) => {
}
}
if (snapshotTab.environment?.tab) {
tab.tabState = { environment: { tab: snapshotTab.environment.tab } };
}
return tab;
};

View File

@@ -45,6 +45,9 @@ const tabSchema = yup.object({
tab: yup.string(),
format: yup.string().nullable(),
viewTab: yup.string().nullable()
}).optional(),
environment: yup.object({
tab: yup.string()
}).optional()
});

View File

@@ -2,6 +2,7 @@ import path from 'path';
import fs from 'fs';
import { test, expect, closeElectronApp } from '../../../playwright';
import {
buildCommonLocators,
createCollection,
createEnvironment,
openCollection,
@@ -358,4 +359,59 @@ test.describe('Snapshot: Collection Environment Persistence', () => {
expect(entry?.selectedEnvironment).toBe('local-bad');
expect(entry?.environmentPath).toContain('local-bad');
});
const envSubTab = (page: any, key: string) => {
const { environment } = buildCommonLocators(page);
return key === 'secrets' ? environment.secretsTab() : environment.variablesTab();
};
for (const subTab of ['variables', 'secrets']) {
test(`persists the "${subTab}" environment-settings sub-tab across snapshot saves and restarts`, async ({ launchElectronApp, createTmpDir }) => {
// One restart plus environment creation; the default budget is tight on slower machines.
test.setTimeout(60000);
const userDataPath = await createTmpDir(`snap-env-subtab-${subTab}`);
const collectionPath = await createTmpDir(`snap-env-subtab-col-${subTab}`);
const collectionRoot = path.join(collectionPath, 'SubTabCollection');
const app = await launchElectronApp({ userDataPath });
const page = await waitForReadyPage(app);
await test.step(`Open environment settings and switch to the "${subTab}" sub-tab`, async () => {
await createCollection(page, 'SubTabCollection', collectionPath);
await openCollection(page, 'SubTabCollection');
await createEnvironment(page, 'local', 'collection');
const tab = envSubTab(page, subTab);
await tab.click();
await expect(tab).toHaveClass(/active/);
});
await test.step('Close app and assert the snapshot stores the selected sub-tab', async () => {
await page.waitForTimeout(2000);
await closeElectronApp(app);
const snapshot = readSnapshot(userDataPath);
expect(snapshot).not.toBeNull();
const collections = Array.isArray(snapshot?.collections) ? snapshot.collections : [];
const collectionEntry = collections.find((collection: any) => collection?.pathname === collectionRoot);
const environmentTab = (Array.isArray(collectionEntry?.tabs) ? collectionEntry.tabs : [])
.find((tab: any) => tab?.type === 'environment-settings');
expect(environmentTab?.environment?.tab).toBe(subTab);
});
await test.step(`Restart app and verify the "${subTab}" sub-tab is restored`, async () => {
const app2 = await launchElectronApp({ userDataPath });
const page2 = await waitForReadyPage(app2);
await openCollection(page2, 'SubTabCollection');
// Focus the restored Environments tab; the sub-tab only renders while it is active.
await buildCommonLocators(page2).environment.collectionEnvTab().click();
await expect(envSubTab(page2, subTab)).toHaveClass(/active/);
await closeElectronApp(app2);
});
});
}
});