diff --git a/portals/devportal/src/main/webapp/package-lock.json b/portals/devportal/src/main/webapp/package-lock.json index 0a50941b60b..6d9a2976b16 100644 --- a/portals/devportal/src/main/webapp/package-lock.json +++ b/portals/devportal/src/main/webapp/package-lock.json @@ -64,6 +64,7 @@ "react-intl": "^6.6.2", "react-loadable": "^5.5.0", "react-markdown": "^8.0.5", + "react-monaco-editor": "^0.55.0", "react-resizable": "^3.0.5", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", @@ -74,7 +75,8 @@ "subscriptions-transport-ws": "^0.11.0", "swagger-client": "^3.18.5", "swagger-ui-react": "^5.6.2", - "swagger2-postman2-converter": "0.0.3" + "swagger2-postman2-converter": "0.0.3", + "xml-formatter": "^3.6.2" }, "devDependencies": { "@babel/core": "^7.22.15", @@ -5223,6 +5225,25 @@ "node": "^12.20 || >=14.13" } }, + "node_modules/@stoplight/elements-core/node_modules/xml-formatter": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz", + "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==", + "dependencies": { + "xml-parser-xo": "^3.2.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@stoplight/elements-core/node_modules/xml-parser-xo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz", + "integrity": "sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==", + "engines": { + "node": ">= 10" + } + }, "node_modules/@stoplight/elements/node_modules/@stoplight/types": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-14.1.1.tgz", @@ -19857,6 +19878,12 @@ "global": "^4.3.2" } }, + "node_modules/monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "peer": true + }, "node_modules/moo": { "version": "0.5.2", "dev": true, @@ -22732,6 +22759,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/react-monaco-editor": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.55.0.tgz", + "integrity": "sha512-GdEP0Q3Rn1dczfKEEyY08Nes5plWwIYU4sWRBQO0+jsQWQsKMHKCC6+hPRwR7G/4aA3V/iU9jSmWPzVJYMVFSQ==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@types/react": ">=16 <= 18", + "monaco-editor": "^0.44.0", + "react": ">=16 <= 18" + } + }, "node_modules/react-overflow-list": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/react-overflow-list/-/react-overflow-list-0.5.0.tgz", @@ -29052,14 +29092,14 @@ } }, "node_modules/xml-formatter": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz", - "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.2.tgz", + "integrity": "sha512-enWhevZNOwffZFUhzl1WMcha8lFLZUgJ7NzFs5Ug4ZOFCoNheGYXz1J9Iz/e+cTn9rCkuT1GwTacz+YlmFHOGw==", "dependencies": { - "xml-parser-xo": "^3.2.0" + "xml-parser-xo": "^4.1.0" }, "engines": { - "node": ">= 10" + "node": ">= 14" } }, "node_modules/xml-name-validator": { @@ -29068,11 +29108,11 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "node_modules/xml-parser-xo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz", - "integrity": "sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.1.tgz", + "integrity": "sha512-Ggf2y90+Y6e9IK5hoPuembVHJ03PhDSdhldEmgzbihzu9k0XBo0sfcFxaSi4W1PlUSSI1ok+MJ0JCXUn+U4Ilw==", "engines": { - "node": ">= 10" + "node": ">= 14" } }, "node_modules/xmlchars": { @@ -32737,6 +32777,19 @@ "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" } + }, + "xml-formatter": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz", + "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==", + "requires": { + "xml-parser-xo": "^3.2.0" + } + }, + "xml-parser-xo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz", + "integrity": "sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==" } } }, @@ -43067,6 +43120,12 @@ "global": "^4.3.2" } }, + "monaco-editor": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz", + "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==", + "peer": true + }, "moo": { "version": "0.5.2", "dev": true @@ -45029,6 +45088,14 @@ } } }, + "react-monaco-editor": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.55.0.tgz", + "integrity": "sha512-GdEP0Q3Rn1dczfKEEyY08Nes5plWwIYU4sWRBQO0+jsQWQsKMHKCC6+hPRwR7G/4aA3V/iU9jSmWPzVJYMVFSQ==", + "requires": { + "prop-types": "^15.8.1" + } + }, "react-overflow-list": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/react-overflow-list/-/react-overflow-list-0.5.0.tgz", @@ -49444,11 +49511,11 @@ } }, "xml-formatter": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.6.1.tgz", - "integrity": "sha512-dOiGwoqm8y22QdTNI7A+N03tyVfBlQ0/oehAzxIZtwnFAHGeSlrfjF73YQvzSsa/Kt6+YZasKsrdu6OIpuBggw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-3.6.2.tgz", + "integrity": "sha512-enWhevZNOwffZFUhzl1WMcha8lFLZUgJ7NzFs5Ug4ZOFCoNheGYXz1J9Iz/e+cTn9rCkuT1GwTacz+YlmFHOGw==", "requires": { - "xml-parser-xo": "^3.2.0" + "xml-parser-xo": "^4.1.0" } }, "xml-name-validator": { @@ -49457,9 +49524,9 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xml-parser-xo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.2.0.tgz", - "integrity": "sha512-8LRU6cq+d7mVsoDaMhnkkt3CTtAs4153p49fRo+HIB3I1FD1o5CeXRjRH29sQevIfVJIcPjKSsPU/+Ujhq09Rg==" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-4.1.1.tgz", + "integrity": "sha512-Ggf2y90+Y6e9IK5hoPuembVHJ03PhDSdhldEmgzbihzu9k0XBo0sfcFxaSi4W1PlUSSI1ok+MJ0JCXUn+U4Ilw==" }, "xmlchars": { "version": "2.2.0", diff --git a/portals/devportal/src/main/webapp/package.json b/portals/devportal/src/main/webapp/package.json index 0b11795b4a4..70278172baf 100644 --- a/portals/devportal/src/main/webapp/package.json +++ b/portals/devportal/src/main/webapp/package.json @@ -81,6 +81,7 @@ "react-intl": "^6.6.2", "react-loadable": "^5.5.0", "react-markdown": "^8.0.5", + "react-monaco-editor": "^0.55.0", "react-resizable": "^3.0.5", "react-router": "^5.3.4", "react-router-dom": "^5.3.4", @@ -91,7 +92,8 @@ "subscriptions-transport-ws": "^0.11.0", "swagger-client": "^3.18.5", "swagger-ui-react": "^5.6.2", - "swagger2-postman2-converter": "0.0.3" + "swagger2-postman2-converter": "0.0.3", + "xml-formatter": "^3.6.2" }, "devDependencies": { "@babel/core": "^7.22.15", diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/ApiChat.jsx b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/ApiChat.jsx index 4ba0d70465c..b3ab9620cdd 100644 --- a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/ApiChat.jsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/ApiChat.jsx @@ -483,11 +483,12 @@ const ApiChat = () => { } // If response is neither JSON nor XML + const text = await response.text().catch(() => 'Unable to render this Content-Type'); return { code: response.status, path: fullPath, headers: response.headers, - body: 'Unsupported Content-Type detected', + body: text, }; } catch (error) { return { diff --git a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/components/ApiChatResponse.tsx b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/components/ApiChatResponse.tsx index 2361172fa8b..a202e258135 100644 --- a/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/components/ApiChatResponse.tsx +++ b/portals/devportal/src/main/webapp/source/src/app/components/Apis/Details/ApiChat/components/ApiChatResponse.tsx @@ -32,6 +32,8 @@ import Paper from '@mui/material/Paper'; import Box from '@mui/material/Box'; import { styled, alpha } from '@mui/material/styles'; import { CircularProgress, Typography } from '@mui/material'; +import MonacoEditor from 'react-monaco-editor'; +import xmlFormat from 'xml-formatter'; import Utils from 'AppData/Utils'; import CustomIcon from 'AppComponents/Shared/CustomIcon'; @@ -156,6 +158,54 @@ const ApiChatResponse: React.FC = ({ } }, []); + /** + * Renders the execution result body. + * + * @param {any} executionResult Execution result to render. + * @returns {JSX.Element} Execution result body to render. + */ + const renderExecutionResultBody = (executionResult: any) => { + const contentType = executionResult.headers.get('Content-Type'); + if (contentType.includes('application/json') && executionResult.body !== '') { + return ( + + ); + } else if (contentType.includes('application/xml') && executionResult.body !== '') { + const formattedMessage = xmlFormat(executionResult.body); + return ( + + ); + } else { + return ( + + {executionResult.body} + + ); + } + }; + return ( @@ -220,7 +270,7 @@ const ApiChatResponse: React.FC = ({ - {JSON.stringify(executionResult.body, null, 2)} + {renderExecutionResultBody(executionResult)}