From e720fed63b0656b317751cccfe85865c67494c5a Mon Sep 17 00:00:00 2001 From: Its-treason <39559178+Its-treason@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:26:24 +0200 Subject: [PATCH 1/2] feat(#245): Add HTML preview to response --- .../ResponsePane/QueryResult/StyledWrapper.js | 23 ++++++- .../ResponsePane/QueryResult/index.js | 66 +++++++++++++++---- .../src/components/ResponsePane/index.js | 2 +- packages/bruno-electron/src/index.js | 3 +- 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js index 9f7583222..18c1c5314 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js @@ -1,9 +1,28 @@ import styled from 'styled-components'; const StyledWrapper = styled.div` + display: grid; + grid-template-columns: 100%; + grid-template-rows: 50px calc(100% - 50px); + + /* If there is only one element (the preview, not tabs) make it span over both grid rows */ + > *:last-child:first-child { + grid-row: 1 / 3; + margin-top: 1.25rem; + height: 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 e6d6f94a8..f6698df22 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js @@ -3,11 +3,15 @@ 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 StyledWrapper from './StyledWrapper'; +import { useState } from 'react'; +import { useMemo } from 'react'; const QueryResult = ({ item, collection, value, width, disableRunEventListener, mode }) => { const { storedTheme } = useTheme(); + const [tab, setTab] = useState('raw'); const dispatch = useDispatch(); const onRun = () => { @@ -17,18 +21,58 @@ const QueryResult = ({ item, collection, value, width, disableRunEventListener, dispatch(sendRequest(item, collection.uid)); }; - return ( - -
- + const getTabClassname = (tabName) => { + return classnames(`tab select-none ${tabName}`, { + active: tabName === tab + }); + }; + + const tabs = [( +
setTab('raw')}> + Raw +
+ )]; + if (mode.includes('text/html')) { + tabs.push( +
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 = value.replace('', ``); + return ( + + ); + } + + return ( + + ); + }, [tab, collection, storedTheme, onRun, value, mode]); + + return ( + + {tabs.length > 1 ? ( +
+ {tabs} +
+ ) : null} + {activeResult}
); }; diff --git a/packages/bruno-app/src/components/ResponsePane/index.js b/packages/bruno-app/src/components/ResponsePane/index.js index c8e071625..64ff9eb25 100644 --- a/packages/bruno-app/src/components/ResponsePane/index.js +++ b/packages/bruno-app/src/components/ResponsePane/index.js @@ -116,7 +116,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..8f56d6461 100644 --- a/packages/bruno-electron/src/index.js +++ b/packages/bruno-electron/src/index.js @@ -35,7 +35,8 @@ app.on('ready', async () => { webPreferences: { nodeIntegration: true, contextIsolation: true, - preload: path.join(__dirname, 'preload.js') + preload: path.join(__dirname, 'preload.js'), + webviewTag: true, } }); From ea9e294c546f640b1bd9ecb9079ef0295447b68c Mon Sep 17 00:00:00 2001 From: Its-treason <39559178+Its-treason@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:50:01 +0200 Subject: [PATCH 2/2] feat(#245): Update tab design + Remove CSP --- .../ResponsePane/QueryResult/StyledWrapper.js | 9 +---- .../ResponsePane/QueryResult/index.js | 39 ++++++++++--------- packages/bruno-electron/src/index.js | 2 - 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js index 18c1c5314..df65244d6 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js @@ -3,14 +3,7 @@ import styled from 'styled-components'; const StyledWrapper = styled.div` display: grid; grid-template-columns: 100%; - grid-template-rows: 50px calc(100% - 50px); - - /* If there is only one element (the preview, not tabs) make it span over both grid rows */ - > *:last-child:first-child { - grid-row: 1 / 3; - margin-top: 1.25rem; - height: calc(100% - 1.25rem); - } + grid-template-rows: 1.25rem calc(100% - 1.25rem); /* This is a hack to force Codemirror to use all available space */ > div { diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js index dd4c8a502..faa0e1e14 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js @@ -63,23 +63,28 @@ const QueryResult = ({ item, collection, data, width, disableRunEventListener, h }; const getTabClassname = (tabName) => { - return classnames(`tab select-none ${tabName}`, { - active: tabName === tab + return classnames(`select-none ${tabName}`, { + 'text-yellow-500': tabName === tab, + 'cursor-pointer': tabName !== tab, }); }; - const tabs = [( -
setTab('raw')}> - Raw -
- )]; - if (mode.includes('html')) { - tabs.push( -
setTab('preview')}> - Preview -
+ const getTabs = () => { + if (!mode.includes('html')) { + return null; + } + + return ( + <> +
setTab('raw')}> + Raw +
+
setTab('preview')}> + Preview +
+ ); - } + }; const activeResult = useMemo(() => { if (tab === 'preview') { @@ -108,11 +113,9 @@ const QueryResult = ({ item, collection, data, width, disableRunEventListener, h return ( - {tabs.length > 1 ? ( -
- {tabs} -
- ) : null} +
+ {getTabs()} +
{activeResult}
); diff --git a/packages/bruno-electron/src/index.js b/packages/bruno-electron/src/index.js index 8f56d6461..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);