diff --git a/package-lock.json b/package-lock.json index c372c42e..a3c66d75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "d3-selection": "3.0.0", "d3-zoom": "3.0.0", "font-awesome": "4.7.0", + "highlight.js": "^11.10.0", "jquery": "3.7.1", "lodash": "4.17.21", "npm-run-all": "4.1.5", @@ -11881,6 +11882,14 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "node_modules/highlight.js": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz", + "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", diff --git a/package.json b/package.json index d2135905..0d1df4fb 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "d3-selection": "3.0.0", "d3-zoom": "3.0.0", "font-awesome": "4.7.0", + "highlight.js": "^11.10.0", "jquery": "3.7.1", "lodash": "4.17.21", "npm-run-all": "4.1.5", diff --git a/src/api/nanoApi.js b/src/api/nanoApi.js index d0d2d151..23b9294c 100644 --- a/src/api/nanoApi.js +++ b/src/api/nanoApi.js @@ -67,6 +67,22 @@ const nanoApi = { } ); }, + + /** + * Get the blueprint source code + * + * @param {string} blueprintId ID of the blueprint + * + * For more details, see full node api docs + */ + getBlueprintSourceCode(blueprintId) { + const data = { blueprint_id: blueprintId }; + return requestExplorerServiceV1.get(`node_api/nc_blueprint_source_code`, {params: data}).then((res) => { + return res.data + }, (res) => { + throw new Error(res.data.message); + }); + }, }; export default nanoApi; diff --git a/src/index.js b/src/index.js index b201b5fe..63bfd96f 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,7 @@ import App from './App'; import 'bootstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; import 'font-awesome/css/font-awesome.min.css'; +import 'highlight.js/styles/github.css'; import './index.css'; import store from './store/index'; diff --git a/src/index.scss b/src/index.scss index 37289a7c..7c6eee8b 100644 --- a/src/index.scss +++ b/src/index.scss @@ -629,4 +629,8 @@ th.sortable { .table-method-arguments tbody tr { background-color: transparent !important; +} + +.source-code { + background-color: #f2f2f2; } \ No newline at end of file diff --git a/src/screens/nano/BlueprintDetail.js b/src/screens/nano/BlueprintDetail.js index 0fd7f1fd..f86c6223 100644 --- a/src/screens/nano/BlueprintDetail.js +++ b/src/screens/nano/BlueprintDetail.js @@ -5,12 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import Loading from '../../components/Loading'; import nanoApi from '../../api/nanoApi'; +import hljs from 'highlight.js/lib/core'; +import python from 'highlight.js/lib/languages/python'; + +hljs.registerLanguage('python', python); /** - * Details of a Nano Contract + * Details of a Blueprint * * @memberof Screens */ @@ -19,11 +23,15 @@ function BlueprintDetail(props) { // blueprintInformation {Object | null} Blueprint information const [blueprintInformation, setBlueprintInformation] = useState(null); + // blueprintSourceCode {string | null} Blueprint source code + const [blueprintSourceCode, setBlueprintSourceCode] = useState(null); // loading {boolean} Bool to show/hide loading when getting blueprint information const [loading, setLoading] = useState(true); // errorMessage {string | null} Error message in case a request to get nano contract data fails const [errorMessage, setErrorMessage] = useState(null); + const codeRef = useRef(); + useEffect(() => { let ignore = false; @@ -32,18 +40,20 @@ function BlueprintDetail(props) { setBlueprintInformation(null); try { const blueprintInformation = await nanoApi.getBlueprintInformation(blueprintId); + const blueprintSourceCode = await nanoApi.getBlueprintSourceCode(blueprintId); if (ignore) { // This is to prevent setting a state after the component has been already cleaned return; } setBlueprintInformation(blueprintInformation); - setLoading(false); + setBlueprintSourceCode(blueprintSourceCode.source_code); } catch (e) { if (ignore) { // This is to prevent setting a state after the component has been already cleaned return; } setErrorMessage('Error getting blueprint information.'); + } finally { setLoading(false); } } @@ -54,6 +64,12 @@ function BlueprintDetail(props) { }; }, [blueprintId]); + useEffect(() => { + if (codeRef && codeRef.current) { + hljs.highlightBlock(codeRef.current); + } + }, [blueprintSourceCode]); + if (errorMessage) { return

{errorMessage}

; } @@ -132,10 +148,11 @@ function BlueprintDetail(props) { {blueprintInformation.name}

Attributes

- {renderBlueprintAttributes()} - {renderBlueprintMethods('public_methods', 'Public Methods')} - {renderBlueprintMethods('private_methods', 'Private Methods')} -
+ { renderBlueprintAttributes() } + { renderBlueprintMethods('public_methods', 'Public Methods') } + { renderBlueprintMethods('private_methods', 'Private Methods') } +

Source Code

+
{blueprintSourceCode}
);