Merge pull request #282 from Its-treason/feature/preview-response-html

feature/preview-response-html
This commit is contained in:
Anoop M D 2023-10-04 03:40:11 +05:30 committed by GitHub
commit 1a8feb8029
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 17 deletions

View File

@ -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%;
}
`;

View File

@ -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 (
<StyledWrapper className="px-3 w-full" style={{ maxWidth: width }}>
<div className="h-full">
<CodeEditor collection={collection} theme={storedTheme} onRun={onRun} value={value} mode={mode} readOnly />
<>
<div className={getTabClassname('raw')} role="tab" onClick={() => setTab('raw')}>
Raw
</div>
<div className={getTabClassname('preview')} role="tab" onClick={() => setTab('preview')}>
Preview
</div>
</>
);
};
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('<head>', `<head><base href="${item.requestSent.url}">`);
return (
<webview
src={`data:text/html; charset=utf-8,${encodeURIComponent(webViewSrc)}`}
webpreferences="disableDialogs=true, javascript=yes"
className="h-full bg-white"
/>
);
}
return (
<CodeEditor
collection={collection}
theme={storedTheme}
onRun={onRun}
value={value}
mode={mode}
readOnly
/>
);
}, [tab, collection, storedTheme, onRun, value, mode]);
return (
<StyledWrapper className="px-3 w-full h-full" style={{ maxWidth: width }}>
<div className="flex justify-end gap-2 text-xs" role="tablist">
{getTabs()}
</div>
{activeResult}
</StyledWrapper>
);
};

View File

@ -115,7 +115,7 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
</div>
) : null}
</div>
<section className="flex flex-grow mt-5">{getTabPanel(focusedTab.responsePaneTab)}</section>
<section className="flex flex-grow">{getTabPanel(focusedTab.responsePaneTab)}</section>
</StyledWrapper>
);
};

View File

@ -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,
}
});