feat: enhance collection settings with environment modals (#6242)

* feat: enhance collection settings with environment modals

* refactor: remove unused environment modal state and simplify Info component structure
This commit is contained in:
Sanjai Kumar
2025-12-05 19:20:04 +05:30
committed by GitHub
parent f479e0d325
commit 57222d2500
4 changed files with 47 additions and 18 deletions

View File

@@ -3,15 +3,23 @@ import { getTotalRequestCountInCollection } from 'utils/collections/';
import { IconBox, IconFolder, IconWorld, IconApi, IconShare } from '@tabler/icons';
import { areItemsLoading, getItemsLoadStats } from 'utils/collections/index';
import { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import ShareCollection from 'components/ShareCollection/index';
import { updateEnvironmentSettingsModalVisibility, updateGlobalEnvironmentSettingsModalVisibility } from 'providers/ReduxStore/slices/app';
const Info = ({ collection }) => {
const dispatch = useDispatch();
const totalRequestsInCollection = getTotalRequestCountInCollection(collection);
const isCollectionLoading = areItemsLoading(collection);
const { loading: itemsLoadingCount, total: totalItems } = getItemsLoadStats(collection);
const [showShareCollectionModal, toggleShowShareCollectionModal] = useState(false);
const globalEnvironments = useSelector((state) => state.globalEnvironments.globalEnvironments);
const collectionEnvironmentCount = collection.environments?.length || 0;
const globalEnvironmentCount = globalEnvironments?.length || 0;
const handleToggleShowShareCollectionModal = (value) => (e) => {
toggleShowShareCollectionModal(value);
};
@@ -39,9 +47,24 @@ const Info = ({ collection }) => {
<IconWorld className="w-5 h-5 text-green-500" stroke={1.5} />
</div>
<div className="ml-4">
<div className="font-medium">Environments</div>
<div className="mt-1 text-muted text-xs">
{collection.environments?.length || 0} environment{collection.environments?.length !== 1 ? 's' : ''} configured
<div className="font-medium text-sm">Environments</div>
<div className="mt-1 flex flex-col gap-1">
<button
type="button"
className="text-sm text-link cursor-pointer hover:underline text-left bg-transparent"
onClick={() => {
dispatch(updateEnvironmentSettingsModalVisibility(true));
}}
>
{collectionEnvironmentCount} collection environment{collectionEnvironmentCount !== 1 ? 's' : ''}
</button>
<button
type="button"
className="text-sm text-link cursor-pointer hover:underline text-left bg-transparent"
onClick={() => dispatch(updateGlobalEnvironmentSettingsModalVisibility(true))}
>
{globalEnvironmentCount} global environment{globalEnvironmentCount !== 1 ? 's' : ''}
</button>
</div>
</div>
</div>

View File

@@ -3,7 +3,7 @@ import find from 'lodash/find';
import Dropdown from 'components/Dropdown';
import { IconWorld, IconDatabase, IconCaretDown, IconSettings, IconPlus, IconDownload } from '@tabler/icons';
import { useSelector, useDispatch } from 'react-redux';
import { updateEnvironmentSettingsModalVisibility } from 'providers/ReduxStore/slices/app';
import { updateEnvironmentSettingsModalVisibility, updateGlobalEnvironmentSettingsModalVisibility } from 'providers/ReduxStore/slices/app';
import { selectEnvironment } from 'providers/ReduxStore/slices/collections/actions';
import { selectGlobalEnvironment } from 'providers/ReduxStore/slices/global-environments';
import toast from 'react-hot-toast';
@@ -20,8 +20,6 @@ const EnvironmentSelector = ({ collection }) => {
const dispatch = useDispatch();
const dropdownTippyRef = useRef();
const [activeTab, setActiveTab] = useState('collection');
const [showGlobalSettings, setShowGlobalSettings] = useState(false);
const [showCollectionSettings, setShowCollectionSettings] = useState(false);
const [showCreateGlobalModal, setShowCreateGlobalModal] = useState(false);
const [showImportGlobalModal, setShowImportGlobalModal] = useState(false);
const [showCreateCollectionModal, setShowCreateCollectionModal] = useState(false);
@@ -29,6 +27,8 @@ const EnvironmentSelector = ({ collection }) => {
const globalEnvironments = useSelector((state) => state.globalEnvironments.globalEnvironments);
const activeGlobalEnvironmentUid = useSelector((state) => state.globalEnvironments.activeGlobalEnvironmentUid);
const isEnvironmentSettingsModalOpen = useSelector((state) => state.app.isEnvironmentSettingsModalOpen);
const isGlobalEnvironmentSettingsModalOpen = useSelector((state) => state.app.isGlobalEnvironmentSettingsModalOpen);
const activeGlobalEnvironment = activeGlobalEnvironmentUid
? find(globalEnvironments, (e) => e.uid === activeGlobalEnvironmentUid)
: null;
@@ -79,9 +79,8 @@ const EnvironmentSelector = ({ collection }) => {
const handleSettingsClick = () => {
if (activeTab === 'collection') {
dispatch(updateEnvironmentSettingsModalVisibility(true));
setShowCollectionSettings(true);
} else {
setShowGlobalSettings(true);
dispatch(updateGlobalEnvironmentSettingsModalVisibility(true));
}
dropdownTippyRef.current.hide();
};
@@ -108,9 +107,8 @@ const EnvironmentSelector = ({ collection }) => {
// Modal handlers
const handleCloseSettings = () => {
setShowGlobalSettings(false);
setShowCollectionSettings(false);
dispatch(updateEnvironmentSettingsModalVisibility(false));
dispatch(updateGlobalEnvironmentSettingsModalVisibility(false));
};
// Calculate dropdown width based on the longest environment name.
@@ -220,7 +218,7 @@ const EnvironmentSelector = ({ collection }) => {
</div>
{/* Modals - Rendered outside dropdown to avoid conflicts */}
{showGlobalSettings && (
{isGlobalEnvironmentSettingsModalOpen && (
<GlobalEnvironmentSettings
globalEnvironments={globalEnvironments}
collection={collection}
@@ -229,13 +227,15 @@ const EnvironmentSelector = ({ collection }) => {
/>
)}
{showCollectionSettings && <EnvironmentSettings collection={collection} onClose={handleCloseSettings} />}
{isEnvironmentSettingsModalOpen && (
<EnvironmentSettings collection={collection} onClose={handleCloseSettings} />
)}
{showCreateGlobalModal && (
<CreateGlobalEnvironment
onClose={() => setShowCreateGlobalModal(false)}
onEnvironmentCreated={() => {
setShowGlobalSettings(true);
dispatch(updateGlobalEnvironmentSettingsModalVisibility(true));
}}
/>
)}
@@ -245,7 +245,7 @@ const EnvironmentSelector = ({ collection }) => {
type="global"
onClose={() => setShowImportGlobalModal(false)}
onEnvironmentCreated={() => {
setShowGlobalSettings(true);
dispatch(updateGlobalEnvironmentSettingsModalVisibility(true));
}}
/>
)}
@@ -255,7 +255,7 @@ const EnvironmentSelector = ({ collection }) => {
collection={collection}
onClose={() => setShowCreateCollectionModal(false)}
onEnvironmentCreated={() => {
setShowCollectionSettings(true);
dispatch(updateEnvironmentSettingsModalVisibility(true));
}}
/>
)}
@@ -266,7 +266,7 @@ const EnvironmentSelector = ({ collection }) => {
collection={collection}
onClose={() => setShowImportCollectionModal(false)}
onEnvironmentCreated={() => {
setShowCollectionSettings(true);
dispatch(updateEnvironmentSettingsModalVisibility(true));
}}
/>
)}

View File

@@ -27,6 +27,7 @@ export const HotkeysProvider = (props) => {
const collections = useSelector((state) => state.collections.collections);
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const isEnvironmentSettingsModalOpen = useSelector((state) => state.app.isEnvironmentSettingsModalOpen);
const isGlobalEnvironmentSettingsModalOpen = useSelector((state) => state.app.isGlobalEnvironmentSettingsModalOpen);
const [showEnvSettingsModal, setShowEnvSettingsModal] = useState(false);
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
const [showGlobalSearchModal, setShowGlobalSearchModal] = useState(false);
@@ -43,7 +44,7 @@ export const HotkeysProvider = (props) => {
// save hotkey
useEffect(() => {
Mousetrap.bind([...getKeyBindingsForActionAllOS('save')], (e) => {
if (isEnvironmentSettingsModalOpen) {
if (isEnvironmentSettingsModalOpen || isGlobalEnvironmentSettingsModalOpen) {
console.log('todo: save environment settings');
} else {
const activeTab = find(tabs, (t) => t.uid === activeTabUid);
@@ -70,7 +71,7 @@ export const HotkeysProvider = (props) => {
return () => {
Mousetrap.unbind([...getKeyBindingsForActionAllOS('save')]);
};
}, [activeTabUid, tabs, saveRequest, collections, isEnvironmentSettingsModalOpen]);
}, [activeTabUid, tabs, saveRequest, collections, isEnvironmentSettingsModalOpen, isGlobalEnvironmentSettingsModalOpen]);
// send request (ctrl/cmd + enter)
useEffect(() => {

View File

@@ -11,6 +11,7 @@ const initialState = {
showHomePage: false,
showPreferences: false,
isEnvironmentSettingsModalOpen: false,
isGlobalEnvironmentSettingsModalOpen: false,
preferences: {
request: {
sslVerification: true,
@@ -66,6 +67,9 @@ export const appSlice = createSlice({
updateEnvironmentSettingsModalVisibility: (state, action) => {
state.isEnvironmentSettingsModalOpen = action.payload;
},
updateGlobalEnvironmentSettingsModalVisibility: (state, action) => {
state.isGlobalEnvironmentSettingsModalOpen = action.payload;
},
showHomePage: (state) => {
state.showHomePage = true;
},
@@ -115,6 +119,7 @@ export const {
updateLeftSidebarWidth,
updateIsDragging,
updateEnvironmentSettingsModalVisibility,
updateGlobalEnvironmentSettingsModalVisibility,
showHomePage,
hideHomePage,
showPreferences,