diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js index 9f7583222..df65244d6 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js @@ -1,9 +1,21 @@ import styled from 'styled-components'; const StyledWrapper = styled.div` + display: grid; + grid-template-columns: 100%; + grid-template-rows: 1.25rem calc(100% - 1.25rem); + + /* This is a hack to force Codemirror to use all available space */ + > div { + position: relative; + } + div.CodeMirror { - /* todo: find a better way */ - height: calc(100vh - 220px); + position: absolute; + top: 0; + bottom: 0; + height: 100%; + width: 100%; } `; diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js index 4093dfcf9..faa0e1e14 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js @@ -3,22 +3,18 @@ import CodeEditor from 'components/CodeEditor'; import { useTheme } from 'providers/Theme'; import { useDispatch } from 'react-redux'; import { sendRequest } from 'providers/ReduxStore/slices/collections/actions'; +import classnames from 'classnames'; import { getContentType, safeStringifyJSON, safeParseXML } from 'utils/common'; import { getCodeMirrorModeBasedOnContentType } from 'utils/common/codemirror'; import StyledWrapper from './StyledWrapper'; +import { useState } from 'react'; +import { useMemo } from 'react'; const QueryResult = ({ item, collection, data, width, disableRunEventListener, headers }) => { const { storedTheme } = useTheme(); + const [tab, setTab] = useState('raw'); const dispatch = useDispatch(); - - const onRun = () => { - if (disableRunEventListener) { - return; - } - dispatch(sendRequest(item, collection.uid)); - }; - const contentType = getContentType(headers); const mode = getCodeMirrorModeBasedOnContentType(contentType); @@ -59,11 +55,68 @@ const QueryResult = ({ item, collection, data, width, disableRunEventListener, h const value = formatResponse(data, mode); + const onRun = () => { + if (disableRunEventListener) { + return; + } + dispatch(sendRequest(item, collection.uid)); + }; + + const getTabClassname = (tabName) => { + return classnames(`select-none ${tabName}`, { + 'text-yellow-500': tabName === tab, + 'cursor-pointer': tabName !== tab, + }); + }; + + const getTabs = () => { + if (!mode.includes('html')) { + return null; + } + + return ( + <> +
setTab('raw')}> + Raw +
+
setTab('preview')}> + Preview +
+ + ); + }; + + const activeResult = useMemo(() => { + if (tab === 'preview') { + // Add the Base tag to the head so content loads proparly. This also needs the correct CSP settings + const webViewSrc = data.replace('', ``); + return ( + + ); + } + + return ( + + ); + }, [tab, collection, storedTheme, onRun, value, mode]); + return ( - -
- + +
+ {getTabs()}
+ {activeResult}
); }; diff --git a/packages/bruno-app/src/components/ResponsePane/index.js b/packages/bruno-app/src/components/ResponsePane/index.js index 0b56840fa..21c4ca16f 100644 --- a/packages/bruno-app/src/components/ResponsePane/index.js +++ b/packages/bruno-app/src/components/ResponsePane/index.js @@ -115,7 +115,7 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
) : null} -
{getTabPanel(focusedTab.responsePaneTab)}
+
{getTabPanel(focusedTab.responsePaneTab)}
); }; diff --git a/packages/bruno-electron/src/index.js b/packages/bruno-electron/src/index.js index 2a62dd969..ac2e92208 100644 --- a/packages/bruno-electron/src/index.js +++ b/packages/bruno-electron/src/index.js @@ -16,9 +16,7 @@ setContentSecurityPolicy(` default-src * 'unsafe-inline' 'unsafe-eval'; script-src * 'unsafe-inline' 'unsafe-eval'; connect-src * 'unsafe-inline'; - base-uri 'none'; form-action 'none'; - img-src 'self' data:image/svg+xml; `); const menu = Menu.buildFromTemplate(menuTemplate); @@ -35,7 +33,8 @@ app.on('ready', async () => { webPreferences: { nodeIntegration: true, contextIsolation: true, - preload: path.join(__dirname, 'preload.js') + preload: path.join(__dirname, 'preload.js'), + webviewTag: true, } });