fix(#279): fixed codemirror crashes resulting in white screen

This commit is contained in:
Anoop M D 2023-10-02 15:25:59 +05:30
parent 7297bb184e
commit bfc03f5ae4
5 changed files with 82 additions and 24 deletions

View File

@ -3,10 +3,12 @@ import CodeEditor from 'components/CodeEditor';
import { useTheme } from 'providers/Theme';
import { useDispatch } from 'react-redux';
import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import { getContentType, safeStringifyJSON, safeParseXML } from 'utils/common';
import { getCodeMirrorModeBasedOnContentType } from 'utils/common/codemirror';
import StyledWrapper from './StyledWrapper';
const QueryResult = ({ item, collection, value, width, disableRunEventListener, mode }) => {
const QueryResult = ({ item, collection, data, width, disableRunEventListener, headers }) => {
const { storedTheme } = useTheme();
const dispatch = useDispatch();
@ -17,17 +19,50 @@ const QueryResult = ({ item, collection, value, width, disableRunEventListener,
dispatch(sendRequest(item, collection.uid));
};
const contentType = getContentType(headers);
const mode = getCodeMirrorModeBasedOnContentType(contentType);
const formatResponse = (data, mode) => {
if (!data) {
return '';
}
if (mode.includes('json')) {
return safeStringifyJSON(data, true);
}
if (mode.includes('xml')) {
let parsed = safeParseXML(data, { collapseContent: true });
if (typeof parsed === 'string') {
return parsed;
}
return safeStringifyJSON(parsed, true);
}
if (['text', 'html'].includes(mode)) {
if (typeof data === 'string') {
return data;
}
return safeStringifyJSON(data);
}
// final fallback
if (typeof data === 'string') {
return data;
}
return safeStringifyJSON(data);
};
const value = formatResponse(data, mode);
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
/>
<CodeEditor collection={collection} theme={storedTheme} onRun={onRun} value={value} mode={mode} readOnly />
</div>
</StyledWrapper>
);

View File

@ -2,7 +2,6 @@ import React from 'react';
import find from 'lodash/find';
import classnames from 'classnames';
import { useDispatch, useSelector } from 'react-redux';
import { getContentType, formatResponse } from 'utils/common';
import { updateResponsePaneTab } from 'providers/ReduxStore/slices/tabs';
import QueryResult from './QueryResult';
import Overlay from './Overlay';
@ -41,8 +40,8 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
item={item}
collection={collection}
width={rightPaneWidth}
value={response.data ? formatResponse(response) : ''}
mode={getContentType(response.headers)}
data={response.data}
headers={response.headers}
/>
);
}

View File

@ -33,7 +33,8 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
collection={collection}
width={rightPaneWidth}
disableRunEventListener={true}
value={responseReceived && responseReceived.data ? safeStringifyJSON(responseReceived.data, true) : ''}
data={responseReceived.data}
headers={responseReceived.headers}
/>
);
}

View File

@ -42,3 +42,25 @@ export const defineCodeMirrorBrunoVariablesMode = (variables, mode) => {
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || mode), variablesOverlay);
});
};
export const getCodeMirrorModeBasedOnContentType = (contentType) => {
if (!contentType || typeof contentType !== 'string') {
return 'application/text';
}
if (contentType.includes('json')) {
return 'application/ld+json';
} else if (contentType.includes('xml')) {
return 'application/xml';
} else if (contentType.includes('html')) {
return 'application/html';
} else if (contentType.includes('text')) {
return 'application/text';
} else if (contentType.includes('application/edn')) {
return 'application/xml';
} else if (mimeType.includes('yaml')) {
return 'application/yaml';
} else {
return 'application/text';
}
};

View File

@ -51,6 +51,17 @@ export const safeStringifyJSON = (obj, indent = false) => {
}
};
export const safeParseXML = (str) => {
if (!str || !str.length || typeof str !== 'string') {
return str;
}
try {
return xmlFormat(str);
} catch (e) {
return str;
}
};
// Remove any characters that are not alphanumeric, spaces, hyphens, or underscores
export const normalizeFileName = (name) => {
if (!name) {
@ -80,16 +91,6 @@ export const getContentType = (headers) => {
return contentType[0];
}
}
return '';
};
export const formatResponse = (response) => {
let type = getContentType(response.headers);
if (type.includes('json')) {
return safeStringifyJSON(response.data, true);
}
if (type.includes('xml')) {
return xmlFormat(response.data, { collapseContent: true });
}
return response.data;
};