diff --git a/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js b/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js index ec0a032171..62a49fcfd3 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js +++ b/packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js @@ -45,6 +45,70 @@ const StyledWrapper = styled.div` display: flex; } } + + .response-toggle { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 48px; + position: absolute; + right: ${props => props.showResponsePane ? 'auto' : '0'}; + top: 50%; + transform: translateY(-50%); + background: ${props => props.theme.requestTabPanel.dragbar.border}; + border-radius: 4px 0 0 4px; + cursor: pointer; + color: ${props => props.theme.requestTabPanel.responseToggle.color}; + z-index: 10; + transition: all 0.2s ease-in-out; + box-shadow: -2px 0 4px rgba(0, 0, 0, 0.1); + + &:hover { + width: 28px; + height: 52px; + background: ${props => props.theme.requestTabPanel.dragbar.activeBorder}; + + svg { + transform: scale(1.2); + } + } + + svg { + transition: transform 0.2s ease-in-out; + } + } + + .response-pane { + animation: slideIn 0.3s ease-in-out; + } + + @keyframes slideIn { + from { + opacity: 0; + transform: translateX(20px); + } + to { + opacity: 1; + transform: translateX(0); + } + } + + .response-pane-exit { + animation: slideOut 0.3s ease-in-out; + } + + @keyframes slideOut { + from { + opacity: 1; + transform: translateX(0); + } + to { + opacity: 0; + transform: translateX(20px); + } + } `; + export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RequestTabPanel/index.js b/packages/bruno-app/src/components/RequestTabPanel/index.js index 4bcfff1c3a..0229c624e6 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/index.js +++ b/packages/bruno-app/src/components/RequestTabPanel/index.js @@ -7,7 +7,7 @@ import HttpRequestPane from 'components/RequestPane/HttpRequestPane'; import ResponsePane from 'components/ResponsePane'; import Welcome from 'components/Welcome'; import { findItemInCollection } from 'utils/collections'; -import { updateRequestPaneTabWidth } from 'providers/ReduxStore/slices/tabs'; +import { updateRequestPaneTabWidth, toggleResponsePane } from 'providers/ReduxStore/slices/tabs'; import { sendRequest } from 'providers/ReduxStore/slices/collections/actions'; import RequestNotFound from './RequestNotFound'; import QueryUrl from 'components/RequestPane/QueryUrl'; @@ -16,6 +16,7 @@ import RunnerResults from 'components/RunnerResults'; import VariablesEditor from 'components/VariablesEditor'; import CollectionSettings from 'components/CollectionSettings'; import { DocExplorer } from '@usebruno/graphql-docs'; +import { IconChevronRight, IconChevronLeft } from '@tabler/icons'; import StyledWrapper from './StyledWrapper'; import SecuritySettings from 'components/SecuritySettings'; @@ -34,6 +35,7 @@ const RequestTabPanel = () => { const dispatch = useDispatch(); const tabs = useSelector((state) => state.tabs.tabs); const activeTabUid = useSelector((state) => state.tabs.activeTabUid); + const showResponsePane = useSelector((state) => state.tabs.showResponsePane); const focusedTab = find(tabs, (t) => t.uid === activeTabUid); const { globalEnvironments, activeGlobalEnvironmentUid } = useSelector((state) => state.globalEnvironments); const _collections = useSelector((state) => state.collections.collections); @@ -56,6 +58,18 @@ const RequestTabPanel = () => { let collection = find(collections, (c) => c.uid === focusedTab?.collectionUid); + const handleToggleResponsePane = () => { + const responsePane = document.querySelector('.response-pane'); + if (showResponsePane) { + responsePane?.classList.add('response-pane-exit'); + setTimeout(() => { + dispatch(toggleResponsePane()); + }, 280); + } else { + dispatch(toggleResponsePane()); + } + }; + const screenWidth = useSelector((state) => state.app.screenWidth); let asideWidth = useSelector((state) => state.app.leftSidebarWidth); const [leftPaneWidth, setLeftPaneWidth] = useState( @@ -168,6 +182,9 @@ const RequestTabPanel = () => { } const handleRun = async () => { + if (!showResponsePane) { + dispatch(toggleResponsePane()); + } dispatch(sendRequest(item, collection.uid)).catch((err) => toast.custom((t) => toast.dismiss(t.id)} />, { duration: 5000 @@ -185,14 +202,16 @@ const RequestTabPanel = () => {
{item.type === 'graphql-request' ? ( { ) : null} {item.type === 'http-request' ? ( - + ) : null}
-
-
+
+ {showResponsePane ? ( + + ) : ( + + )}
-
- -
+ {showResponsePane && ( + <> +
+
+
+ +
+ +
+ + )} {item.type === 'graphql-request' ? ( diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js b/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js index 935be60752..761dd4d789 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/tabs.js @@ -7,7 +7,8 @@ import last from 'lodash/last'; const initialState = { tabs: [], - activeTabUid: null + activeTabUid: null, + showResponsePane: false }; const tabTypeAlreadyExists = (tabs, collectionUid, type) => { @@ -89,6 +90,9 @@ export const tabsSlice = createSlice({ tab.responsePaneTab = action.payload.responsePaneTab; } }, + toggleResponsePane: (state) => { + state.showResponsePane = !state.showResponsePane; + }, closeTabs: (state, action) => { const activeTab = find(state.tabs, (t) => t.uid === state.activeTabUid); const tabUids = action.payload.tabUids || []; @@ -136,7 +140,8 @@ export const { updateRequestPaneTab, updateResponsePaneTab, closeTabs, - closeAllCollectionTabs + closeAllCollectionTabs, + toggleResponsePane } = tabsSlice.actions; export default tabsSlice.reducer; diff --git a/packages/bruno-app/src/themes/dark.js b/packages/bruno-app/src/themes/dark.js index 9e8e923aad..83fb1a3801 100644 --- a/packages/bruno-app/src/themes/dark.js +++ b/packages/bruno-app/src/themes/dark.js @@ -99,6 +99,11 @@ const darkTheme = { }, requestTabPanel: { + responseToggle: { + color: '#ffffff', + hoverBg: '#666666', + shadow: '0 2px 4px rgba(0, 0, 0, 0.2)' + }, url: { bg: '#3D3D3D', icon: 'rgb(204, 204, 204)' diff --git a/packages/bruno-app/src/themes/light.js b/packages/bruno-app/src/themes/light.js index a25583136c..eb69955ee4 100644 --- a/packages/bruno-app/src/themes/light.js +++ b/packages/bruno-app/src/themes/light.js @@ -99,6 +99,11 @@ const lightTheme = { }, requestTabPanel: { + responseToggle: { + color: '#333333', + hoverBg: '#e0e0e0', + shadow: '0 2px 4px rgba(0, 0, 0, 0.1)' + }, url: { bg: '#f3f3f3', icon: '#515151'