Skip to content

Commit

Permalink
feature: UI: Response Panel Split Horizontally usebruno#1041
Browse files Browse the repository at this point in the history
  • Loading branch information
busy-panda committed Apr 22, 2024
1 parent d027d90 commit 560b80d
Show file tree
Hide file tree
Showing 22 changed files with 269 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import styled from 'styled-components';
const StyledWrapper = styled.div`
div.CodeMirror {
/* todo: find a better way */
height: calc(100vh - 240px);
.CodeMirror-scroll {
padding-bottom: 0px;
}
height: calc(100vh - 260px);
}
.editing-mode {
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions packages/bruno-app/src/components/Documentation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const Documentation = ({ item, collection }) => {
}

return (
<StyledWrapper className="mt-1 h-full w-full relative">
<div className="editing-mode mb-2" role="tab" onClick={toggleViewMode}>
<StyledWrapper className="h-full w-full flex flex-col">
<div className="editing-mode mb-2 mt-1" role="tab" onClick={toggleViewMode}>
{isEditing ? 'Preview' : 'Edit'}
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
</div>
<GraphQLSchemaActions item={item} collection={collection} onSchemaLoad={setSchema} toggleDocs={toggleDocs} />
</div>
<section className="flex w-full mt-5">{getTabPanel(focusedTab.requestPaneTab)}</section>
<section className="flex w-full mt-5 overflow-y-auto">{getTabPanel(focusedTab.requestPaneTab)}</section>
</StyledWrapper>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const HttpRequestPane = ({ item, collection, leftPaneWidth }) => {
) : null}
</div>
<section
className={`flex w-full ${
className={`flex w-full overflow-y-auto ${
['script', 'vars', 'auth', 'docs'].includes(focusedTab.requestPaneTab) ? '' : 'mt-5'
}`}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from 'styled-components';
const Wrapper = styled.div`
div.CodeMirror {
/* todo: find a better way */
height: calc(100vh - 220px);
height: calc(100vh - 250px);
}
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import styled from 'styled-components';

const StyledWrapper = styled.div`
div.CodeMirror {
height: inherit;
}
div.title {
Expand Down
68 changes: 41 additions & 27 deletions packages/bruno-app/src/components/RequestPane/Script/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect } from 'react';
import get from 'lodash/get';
import { useDispatch, useSelector } from 'react-redux';
import CodeEditor from 'components/CodeEditor';
Expand All @@ -11,10 +11,22 @@ const Script = ({ item, collection }) => {
const dispatch = useDispatch();
const requestScript = item.draft ? get(item, 'draft.request.script.req') : get(item, 'request.script.req');
const responseScript = item.draft ? get(item, 'draft.request.script.res') : get(item, 'request.script.res');
const isResponsePaneDockedToBottom = useSelector((state) => state.app.isResponsePaneDockedToBottom);

const { displayedTheme } = useTheme();
const preferences = useSelector((state) => state.app.preferences);

useEffect(() => {
// set code mirror controls height depending on where the response pane is docked (right or bottom)
let codeMirrorControls = document.querySelectorAll('#ScriptTab .CodeMirror');
let newHeight = isResponsePaneDockedToBottom ? '200px' : 'calc(50vh - 150px)';
codeMirrorControls.forEach((control) => {
if (control.style.height !== newHeight) {
control.style.height = newHeight;
}
});
});

const onRequestScriptEdit = (value) => {
dispatch(
updateRequestScript({
Expand All @@ -39,32 +51,34 @@ const Script = ({ item, collection }) => {
const onSave = () => dispatch(saveRequest(item.uid, collection.uid));

return (
<StyledWrapper className="w-full flex flex-col">
<div className="flex-1 mt-2">
<div className="mb-1 title text-xs">Pre Request</div>
<CodeEditor
collection={collection}
value={requestScript || ''}
theme={displayedTheme}
font={get(preferences, 'font.codeFont', 'default')}
onEdit={onRequestScriptEdit}
mode="javascript"
onRun={onRun}
onSave={onSave}
/>
</div>
<div className="flex-1 mt-6">
<div className="mt-1 mb-1 title text-xs">Post Response</div>
<CodeEditor
collection={collection}
value={responseScript || ''}
theme={displayedTheme}
font={get(preferences, 'font.codeFont', 'default')}
onEdit={onResponseScriptEdit}
mode="javascript"
onRun={onRun}
onSave={onSave}
/>
<StyledWrapper className="w-full">
<div id="ScriptTab" className="flex flex-col">
<div className="flex-1 mt-2">
<div className="mb-1 title text-xs">Pre Request</div>
<CodeEditor
collection={collection}
value={requestScript || ''}
theme={displayedTheme}
font={get(preferences, 'font.codeFont', 'default')}
onEdit={onRequestScriptEdit}
mode="javascript"
onRun={onRun}
onSave={onSave}
/>
</div>
<div className="flex-1 mt-6">
<div className="mt-1 mb-1 title text-xs">Post Response</div>
<CodeEditor
collection={collection}
value={responseScript || ''}
theme={displayedTheme}
font={get(preferences, 'font.codeFont', 'default')}
onEdit={onResponseScriptEdit}
mode="javascript"
onRun={onRun}
onSave={onSave}
/>
</div>
</div>
</StyledWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from 'styled-components';
const StyledWrapper = styled.div`
div.CodeMirror {
/* todo: find a better way */
height: calc(100vh - 220px);
height: calc(100vh - 250px);
}
`;

Expand Down
21 changes: 21 additions & 0 deletions packages/bruno-app/src/components/RequestTabPanel/StyledWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ const StyledWrapper = styled.div`
}
}
div.drag-request-horizontal {
display: flex;
justify-content: center;
height: 10px;
cursor: row-resize;
background: transparent;
div.drag-request-horizontal-border {
display: flex;
width: 100%;
height: 1px;
border-top: solid 1px ${(props) => props.theme.requestTabPanel.dragbar.border};
}
&:hover div.drag-request-horizontal-border {
border-top: solid 1px ${(props) => props.theme.requestTabPanel.dragbar.activeBorder};
}
}
div.graphql-docs-explorer-container {
background: white;
outline: none;
Expand Down
80 changes: 69 additions & 11 deletions packages/bruno-app/src/components/RequestTabPanel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, updateRequestPaneTabHeight } from 'providers/ReduxStore/slices/tabs';
import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import RequestNotFound from './RequestNotFound';
import QueryUrl from 'components/RequestPane/QueryUrl';
Expand All @@ -21,6 +21,9 @@ import StyledWrapper from './StyledWrapper';

const MIN_LEFT_PANE_WIDTH = 300;
const MIN_RIGHT_PANE_WIDTH = 350;
const MIN_TOP_PANE_HEIGHT = 40;
const MIN_BOTTOM_PANE_HEIGHT = 50;

const DEFAULT_PADDING = 5;

const RequestTabPanel = () => {
Expand All @@ -32,14 +35,18 @@ const RequestTabPanel = () => {
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const collections = useSelector((state) => state.collections.collections);
const screenWidth = useSelector((state) => state.app.screenWidth);

const screenHeight = useSelector((state) => state.app.screenHeight);
const isResponsePaneDockedToBottom = useSelector((state) => state.app.isResponsePaneDockedToBottom);
let asideWidth = useSelector((state) => state.app.leftSidebarWidth);
let asideHeight = useSelector((state) => state.app.topBarHeight);
const focusedTab = find(tabs, (t) => t.uid === activeTabUid);
const [leftPaneWidth, setLeftPaneWidth] = useState(
focusedTab && focusedTab.requestPaneWidth ? focusedTab.requestPaneWidth : (screenWidth - asideWidth) / 2.2
); // 2.2 so that request pane is relatively smaller
const [topPaneHeight, setTopPaneHeight] = useState((screenHeight - asideHeight) / 2);
const [rightPaneWidth, setRightPaneWidth] = useState(screenWidth - asideWidth - leftPaneWidth - DEFAULT_PADDING);
const [dragging, setDragging] = useState(false);
const [draggingHorizontal, setDraggingHorizontal] = useState(false);

// Not a recommended pattern here to have the child component
// make a callback to set state, but treating this as an exception
Expand All @@ -66,6 +73,11 @@ const RequestTabPanel = () => {
setRightPaneWidth(screenWidth - asideWidth - leftPaneWidth - DEFAULT_PADDING);
}, [screenWidth, asideWidth, leftPaneWidth]);

useEffect(() => {
const topPaneHeight = (screenHeight - asideHeight) / 2;
setTopPaneHeight(topPaneHeight);
}, [screenHeight]);

const handleMouseMove = (e) => {
if (dragging) {
e.preventDefault();
Expand All @@ -78,6 +90,16 @@ const RequestTabPanel = () => {
}
setLeftPaneWidth(leftPaneXPosition - asideWidth);
setRightPaneWidth(screenWidth - e.clientX - DEFAULT_PADDING);
} else if (draggingHorizontal) {
e.preventDefault();
let topPaneYPosition = e.clientY + 2;
if (
topPaneYPosition < asideHeight + DEFAULT_PADDING + MIN_TOP_PANE_HEIGHT ||
topPaneYPosition > screenHeight - MIN_BOTTOM_PANE_HEIGHT
) {
return;
}
setTopPaneHeight(topPaneYPosition - asideHeight);
}
};
const handleMouseUp = (e) => {
Expand All @@ -90,13 +112,21 @@ const RequestTabPanel = () => {
requestPaneWidth: e.clientX - asideWidth - DEFAULT_PADDING
})
);
} else if (draggingHorizontal) {
e.preventDefault();
setDraggingHorizontal(false);
}
};
const handleDragbarMouseDown = (e) => {
e.preventDefault();
setDragging(true);
};

const handleDragbarHorizontalMouseDown = (e) => {
e.preventDefault();
setDraggingHorizontal(true);
};

useEffect(() => {
document.addEventListener('mouseup', handleMouseUp);
document.addEventListener('mousemove', handleMouseMove);
Expand All @@ -105,7 +135,7 @@ const RequestTabPanel = () => {
document.removeEventListener('mouseup', handleMouseUp);
document.removeEventListener('mousemove', handleMouseMove);
};
}, [dragging, asideWidth]);
}, [dragging, draggingHorizontal, asideWidth, asideHeight]);

if (!activeTabUid) {
return <Welcome />;
Expand Down Expand Up @@ -146,17 +176,21 @@ const RequestTabPanel = () => {
};

return (
<StyledWrapper className={`flex flex-col flex-grow relative ${dragging ? 'dragging' : ''}`}>
<StyledWrapper
className={`flex flex-col flex-grow relative ${dragging ? 'dragging' : ''} ${
draggingHorizontal ? 'dragging-horizontal' : ''
}`}
>
<div className="pt-4 pb-3 px-4">
<QueryUrl item={item} collection={collection} handleRun={handleRun} />
</div>
<section className="main flex flex-grow pb-4 relative">
<section className={`main flex flex-grow pb-4 relative ${isResponsePaneDockedToBottom ? 'flex-col' : ''}`}>
<section className="request-pane">
<div
className="px-4"
className="px-4 "
style={{
width: `${Math.max(leftPaneWidth, MIN_LEFT_PANE_WIDTH)}px`,
height: `calc(100% - ${DEFAULT_PADDING}px)`
width: `${isResponsePaneDockedToBottom ? '100%' : Math.max(leftPaneWidth, MIN_LEFT_PANE_WIDTH) + 'px'}`,
height: `${isResponsePaneDockedToBottom ? Math.max(topPaneHeight, MIN_TOP_PANE_HEIGHT) + 'px' : '100%'}`
}}
>
{item.type === 'graphql-request' ? (
Expand All @@ -176,12 +210,36 @@ const RequestTabPanel = () => {
</div>
</section>

<div className="drag-request" onMouseDown={handleDragbarMouseDown}>
<div
className={`drag-request ${isResponsePaneDockedToBottom ? 'invisible' : ''}`}
onMouseDown={handleDragbarMouseDown}
>
<div className="drag-request-border" />
</div>

<section className="response-pane flex-grow">
<ResponsePane item={item} collection={collection} rightPaneWidth={rightPaneWidth} response={item.response} />
<div
className={`drag-request-horizontal ${isResponsePaneDockedToBottom ? 'px-4' : 'invisible'}`}
onMouseDown={handleDragbarHorizontalMouseDown}
>
<div className="drag-request-horizontal-border" />
</div>

<section className="response-pane flex-grow ">
<div
className="px-4 "
style={{
height: `${
isResponsePaneDockedToBottom ? screenHeight - asideHeight - topPaneHeight - 30 + 'px' : '100%'
}`
}}
>
<ResponsePane
item={item}
collection={collection}
rightPaneWidth={rightPaneWidth}
response={item.response}
/>
</div>
</section>
</section>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ const StyledWrapper = styled.div`
background-color: ${(props) => props.theme.requestTabPanel.responseOverlayBg};
div.overlay {
height: 100%;
z-index: 9;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 20%;
overflow: hidden;
text-align: center;
Expand Down
26 changes: 14 additions & 12 deletions packages/bruno-app/src/components/ResponsePane/Overlay/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ const ResponseLoadingOverlay = ({ item, collection }) => {

return (
<StyledWrapper className="px-3 w-full">
<div className="overlay">
<div style={{ marginBottom: 15, fontSize: 26 }}>
<div style={{ display: 'inline-block', fontSize: 20, marginLeft: 5, marginRight: 5 }}>
<StopWatch requestTimestamp={item?.requestSent?.timestamp} />
<div className="flex items-center justify-center h-full">
<div className="overlay">
<div style={{ marginBottom: 15, fontSize: 26 }}>
<div style={{ display: 'inline-block', fontSize: 20, marginLeft: 5, marginRight: 5 }}>
<StopWatch requestTimestamp={item?.requestSent?.timestamp} />
</div>
</div>
<IconRefresh size={24} className="loading-icon" />
<button
onClick={handleCancelRequest}
className="mt-4 uppercase btn-sm rounded btn-secondary ease-linear transition-all duration-150 relative z-50"
type="button"
>
Cancel Request
</button>
</div>
<IconRefresh size={24} className="loading-icon" />
<button
onClick={handleCancelRequest}
className="mt-4 uppercase btn-sm rounded btn-secondary ease-linear transition-all duration-150 relative z-50"
type="button"
>
Cancel Request
</button>
</div>
</StyledWrapper>
);
Expand Down

0 comments on commit 560b80d

Please sign in to comment.