Merge pull request #4153 from ethereum/compiledetails-mainpanel-plugin

Move compilation details to Main panel plugin
pull/5370/head
Joseph Izang 1 year ago committed by GitHub
commit 831b4b9ff2
  1. 3
      .prettierrc.json
  2. 61
      apps/compile-details/project.json
  3. 13
      apps/compile-details/src/index.html
  4. 23
      apps/compile-details/tsconfig.app.json
  5. 16
      apps/compile-details/tsconfig.json
  6. 70
      apps/compile-details/webpack.config.js
  7. 14
      apps/remix-ide-e2e/src/commands/verifyContracts.ts
  8. 5
      apps/remix-ide/src/app.js
  9. 84
      apps/remix-ide/src/app/plugins/compile-details.tsx
  10. 1
      apps/remix-ide/src/app/tabs/locales/en/solidity.json
  11. 1
      apps/remix-ide/src/app/tabs/locales/es/solidity.json
  12. 1
      apps/remix-ide/src/app/tabs/locales/fr/solidity.json
  13. 1
      apps/remix-ide/src/app/tabs/locales/zh/solidity.json
  14. 3
      apps/remix-ide/src/remixAppManager.js
  15. 1
      libs/remix-ui/solidity-compile-details/src/index.ts
  16. 72
      libs/remix-ui/solidity-compile-details/src/lib/solidity-compile-details.tsx
  17. 5
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  18. 17
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  19. 5
      libs/remix-ui/solidity-compiler/src/lib/css/style.css
  20. 3
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  21. 1
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  22. 1
      libs/remix-ui/tabs/src/lib/remix-ui-tabs.tsx
  23. 5
      tsconfig.paths.json

@ -1,7 +1,8 @@
{
"tabWidth": 2,
"printWidth": 500,
"bracketSpacing": false,
"useTabs": false,
"printWidth": 180,
"semi": false,
"singleQuote": true
}

@ -0,0 +1,61 @@
{
"name": "compile-details",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/compile-details/src",
"projectType": "application",
"implicitDependencies": [
],
"targets": {
"build": {
"executor": "@nrwl/webpack:webpack",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "development",
"options": {
"compiler": "babel",
"outputPath": "dist/apps/compile-details",
"index": "apps/compile-details/src/index.html",
"baseHref": "./",
"main": "apps/compile-details/src/main.tsx",
"tsConfig": "apps/compile-details/tsconfig.app.json",
"assets": [
"apps/compile-details/src/favicon.ico",
"apps/compile-details/src/profile.json"
],
"styles": [],
"scripts": [],
"webpackConfig": "apps/compile-details/webpack.config.js"
},
"configurations": {
"development": {
},
"production": {
"fileReplacements": [
{
"replace": "apps/compile-details/src/environments/environment.ts",
"with": "apps/compile-details/src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"executor": "@nrwl/webpack:dev-server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "compile-details:build",
"hmr": true,
"baseHref": "/"
},
"configurations": {
"development": {
"buildTarget": "compile-details:build:development",
"port": 6003
},
"production": {
"buildTarget": "compile-details:build:production"
}
}
}
},
"tags": []
}

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Compilation Details</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<div id="root"></div>
</body>
</html>

@ -0,0 +1,23 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"exclude": [
"jest.config.ts",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
}
]
}

@ -0,0 +1,70 @@
const { composePlugins, withNx } = require('@nrwl/webpack')
const { withReact } = require('@nrwl/react')
const webpack = require('webpack')
const TerserPlugin = require('terser-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), withReact(), config => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
// add fallback for node modules
config.resolve.fallback = {
...config.resolve.fallback,
path: require.resolve('path-browserify'),
fs: false,
}
// add externals
config.externals = {
...config.externals,
solc: 'solc',
}
config.module.rules.push({
test: /\.hbs$/,
type: 'asset/source',
})
// add public path
config.output.publicPath = '/'
// add copy & provide plugin
config.plugins.push(
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
url: ['url', 'URL'],
process: 'process/browser',
}),
new webpack.DefinePlugin({}),
)
// souce-map loader
config.module.rules.push({
test: /\.js$/,
use: ['source-map-loader'],
enforce: 'pre',
})
config.ignoreWarnings = [/Failed to parse source map/] // ignore source-map-loader warnings
// set minimizer
config.optimization.minimizer = [
new TerserPlugin({
parallel: true,
terserOptions: {
ecma: 2015,
compress: false,
mangle: false,
format: {
comments: false,
},
},
extractComments: false,
}),
new CssMinimizerPlugin(),
]
return config
})

@ -30,8 +30,10 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str
.pause(2000)
.click('*[data-id="treeViewDivtreeViewItemcompiler"]')
.waitForElementVisible('*[data-id="treeViewLiversion"]')
.assert.containsText('*[data-id="treeViewLiversion"]', `${opts.version}`)
.click('[data-id="workspacesModalDialog-modal-footer-cancel-react"]')
.waitForElementContainsText('*[data-id="treeViewLiversion"]', `${opts.version}`)
.waitForElementVisible('*[id="compileDetails"]')
.waitForElementVisible('*[data-path="compilationDetails"]')
.click('*[data-id="close_compilationDetails"]')
.perform(() => {
done()
callback()
@ -42,14 +44,16 @@ function verifyContracts (browser: NightwatchBrowser, compiledContractNames: str
.waitForElementVisible('*[data-id="remixui_treeviewitem_metadata"]')
.pause(2000)
.click('*[data-id="remixui_treeviewitem_metadata"]')
.waitForElementVisible('*[data-id="treeViewDivtreeViewItemsettings"]')
.assert.visible('*[data-id="treeViewDivtreeViewItemsettings"]')
.pause(2000)
.click('*[data-id="treeViewDivtreeViewItemsettings"]')
.waitForElementVisible('*[data-id="treeViewDivtreeViewItemoptimizer"]')
.click('*[data-id="treeViewDivtreeViewItemoptimizer"]')
.waitForElementVisible('*[data-id="treeViewDivruns"]')
.assert.containsText('*[data-id="treeViewDivruns"]', `${opts.runs}`)
.click('[data-id="workspacesModalDialog-modal-footer-cancel-react"]')
.waitForElementContainsText('*[data-id="treeViewDivruns"]', `${opts.runs}`)
.waitForElementVisible('*[id="compileDetails"]')
.waitForElementVisible('*[data-id="close_compilationDetails"]')
.click('*[data-id="close_compilationDetails"]')
.perform(() => {
done()
callback()

@ -46,6 +46,7 @@ import {InjectedSKALEChaosTestnetProvider} from './app/providers/injected-skale-
import {FileDecorator} from './app/plugins/file-decorator'
import {CodeFormat} from './app/plugins/code-format'
import {SolidityUmlGen} from './app/plugins/solidity-umlgen'
import { CompilationDetailsPlugin } from './app/plugins/compile-details'
import {ContractFlattener} from './app/plugins/contractFlattener'
import {OpenAIGpt} from './app/plugins/openaigpt'
@ -179,6 +180,9 @@ class AppComponent {
//---------------- Solidity UML Generator -------------------------
const solidityumlgen = new SolidityUmlGen(appManager)
// ----------------- Compilation Details ----------------------------
const compilationDetails = new CompilationDetailsPlugin(appManager)
// ----------------- ContractFlattener ----------------------------
const contractFlattener = new ContractFlattener()
@ -303,6 +307,7 @@ class AppComponent {
this.walkthroughService,
search,
solidityumlgen,
compilationDetails,
contractFlattener,
solidityScript,
openaigpt

@ -0,0 +1,84 @@
import React from 'react'
import { ViewPlugin } from '@remixproject/engine-web'
import {PluginViewWrapper} from '@remix-ui/helper'
import { RemixAppManager } from '../../remixAppManager'
import { RemixUiCompileDetails } from '@remix-ui/solidity-compile-details'
const _paq = (window._paq = window._paq || [])
const profile = {
name: 'compilationDetails',
displayName: 'Solidity Compile Details',
description: 'Displays details from solidity compiler',
location: 'mainPanel',
methods: ['showDetails'],
events: []
}
export class CompilationDetailsPlugin extends ViewPlugin {
dispatch: React.Dispatch<any> = () => {}
appManager: RemixAppManager
element: HTMLDivElement
payload: any
constructor(appManager: RemixAppManager) {
super(profile)
this.appManager = appManager
this.element = document.createElement('div')
this.element.setAttribute('id', 'compileDetails')
this.payload = {
contractProperties: {} as any,
selectedContract: '',
help: {} as any,
insertValue: {} as any,
saveAs: {} as any,
}
}
async onActivation() {
await this.call('tabs', 'focus', 'compilationDetails')
this.renderComponent()
_paq.push(['trackEvent', 'plugin', 'activated', 'compilationDetails'])
}
onDeactivation(): void {
}
async showDetails(sentPayload: any) {
await this.call('tabs', 'focus', 'compilationDetails')
this.payload = sentPayload
this.renderComponent()
}
setDispatch(dispatch: React.Dispatch<any>): void {
this.dispatch = dispatch
}
render() {
return (
<div id="compileDetails">
<PluginViewWrapper plugin={this} />
</div>
)
}
renderComponent() {
this.dispatch({
...this,
...this.payload
})
}
updateComponent(state: any) {
return (
<RemixUiCompileDetails
plugin={this}
contractProperties={state.contractProperties}
selectedContract={state.selectedContract}
saveAs={state.saveAs}
help={state.help}
insertValue={state.insertValue}
/>
)
}
}

@ -59,6 +59,7 @@
"solidity.copyBytecode": "Copy Bytecode to clipboard",
"solidity.unableToDisplay": "Unable to display",
"solidity.download": "Download",
"solidity.compileDetails": "Download compilation details (JSON format)",
"solidity.close": "Close",
"solidity.contract": "Contract",
"solidity.displayContractDetails": "Display Contract Details",

@ -1,6 +1,7 @@
{
"solidity.displayName": "Solidity compiler",
"solidity.compiler": "Compiler",
"solidity.compileDetails": "Descargar detalles de compilación (formato JSON)",
"solidity.addACustomCompiler": "Add a custom compiler",
"solidity.addACustomCompilerWithURL": "Add a custom compiler with URL",
"solidity.includeNightlyBuilds": "Include nightly builds",

@ -1,6 +1,7 @@
{
"solidity.displayName": "Solidity compiler",
"solidity.compiler": "Compiler",
"solidity.compileDetails": "Télécharger les détails de la compilation (format JSON)",
"solidity.addACustomCompiler": "Add a custom compiler",
"solidity.addACustomCompilerWithURL": "Add a custom compiler with URL",
"solidity.includeNightlyBuilds": "Include nightly builds",

@ -4,6 +4,7 @@
"solidity.addACustomCompiler": "添加一个自定义编译器",
"solidity.addACustomCompilerWithURL": "通过URL添加一个自定义编译器",
"solidity.includeNightlyBuilds": "包含每日构造版本",
"solidity.compileDetails": "下载编译详细信息(JSON 格式",
"solidity.autoCompile": "自动编译",
"solidity.hideWarnings": "隐藏警告",
"solidity.enableHardhat": "启用 Hardhat 编译",

@ -71,6 +71,7 @@ const requiredModules = [
'codeParser',
'codeFormatter',
'solidityumlgen',
'compilationDetails',
'contractflattener',
'solidity-script',
'openaigpt'
@ -79,7 +80,7 @@ const requiredModules = [
// dependentModules shouldn't be manually activated (e.g hardhat is activated by remixd)
const dependentModules = ['foundry', 'hardhat', 'truffle', 'slither']
const loadLocalPlugins = ['doc-gen', 'doc-viewer', 'etherscan', 'vyper', 'solhint', 'walletconnect', 'circuit-compiler']
const loadLocalPlugins = ['doc-gen', 'doc-viewer', 'etherscan', 'vyper', 'solhint', 'walletconnect', 'circuit-compiler', 'compilationDetails']
const sensitiveCalls = {
fileManager: ['writeFile', 'copyFile', 'rename', 'copyDir'],

@ -0,0 +1 @@
export * from './lib/solidity-compile-details'

@ -0,0 +1,72 @@
import { CopyToClipboard } from '@remix-ui/clipboard'
import { CustomTooltip } from '@remix-ui/helper'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view'
import React from 'react'
import { useIntl } from 'react-intl'
export interface RemixUiCompileDetailsProps {
plugin: any
contractProperties: any
selectedContract: string
help: any
insertValue: any
saveAs: any
}
const _paq = (window._paq = window._paq || [])
export function RemixUiCompileDetails({ plugin, contractProperties, selectedContract, saveAs, help, insertValue }: RemixUiCompileDetailsProps) {
const intl = useIntl()
const downloadFn = () => {
_paq.push(['trackEvent', 'compiler', 'compilerDetails', 'download'])
saveAs(new Blob([JSON.stringify(contractProperties, null, '\t')]), `${selectedContract}_compData.json`)
}
return (
<>
<div className="d-flex justify-content-between align-items-center mr-1">
<span className="lead">{selectedContract}</span>
<CustomTooltip tooltipText={intl.formatMessage({id: 'solidity.compileDetails'})}>
<span className="btn btn-outline-success border-success mr-1" onClick={downloadFn}>Download</span>
</CustomTooltip>
</div>
<div className="remixui_detailsJSON">
<TreeView>
{Object.keys(contractProperties).map((propertyName, index) => {
const copyDetails = (
<span className="remixui_copyDetails">
<CopyToClipboard tip={intl.formatMessage({id: 'solidity.copy'})} content={contractProperties[propertyName]} direction="top" />
</span>
)
const questionMark = (
<span className="remixui_questionMark">
<i
title={intl.formatMessage({
id: `solidity.${propertyName}`,
defaultMessage: help[propertyName]
})}
className="fas fa-question-circle"
aria-hidden="true"
></i>
</span>
)
return (
<div className="remixui_log" key={index}>
<TreeViewItem
label={
<div data-id={`remixui_treeviewitem_${propertyName}`} className="remixui_key">
{propertyName} {copyDetails} {questionMark}
</div>
}
>
{insertValue(contractProperties, propertyName)}
</TreeViewItem>
</div>
)
})}
</TreeView>
</div>
</>
)
}

@ -37,8 +37,11 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
isFoundryProject,
workspaceName,
configFilePath,
setConfigFilePath
setConfigFilePath,
//@ts-ignore
pluginProps
} = props // eslint-disable-line
const [state, setState] = useState({
hideWarnings: false,
autoCompile: false,

@ -156,6 +156,14 @@ export const ContractSelection = (props: ContractSelectionProps) => {
return <pre className="remixui_value">{node || ''}</pre>
}
const payload = {
saveAs: saveAs,
contractProperties: {},
selectedContract: '',
help: {},
insertValue: insertValue
}
const details = () => {
_paq.push(['trackEvent', 'compiler', 'compilerDetails', 'display'])
if (!selectedContract) throw new Error('No contract compiled yet')
@ -182,6 +190,10 @@ export const ContractSelection = (props: ContractSelectionProps) => {
// Make 'compilerInput' first field to display it as first item in 'Compilation Details' modal
if (compilerInput) contractProperties.compilerInput = compilerInput
contractProperties = Object.assign(contractProperties, contractsDetails[selectedContract])
payload.contractProperties = contractProperties
payload.selectedContract = selectedContract
payload.help = help
payload.insertValue = insertValue
const log = (
<div className="remixui_detailsJSON">
<TreeView>
@ -225,7 +237,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
_paq.push(['trackEvent', 'compiler', 'compilerDetails', 'download'])
saveAs(new Blob([JSON.stringify(contractProperties, null, '\t')]), `${selectedContract}_compData.json`)
}
modal(selectedContract, log, intl.formatMessage({id: 'solidity.download'}), downloadFn, true, intl.formatMessage({id: 'solidity.close'}), null)
// modal(selectedContract, log, intl.formatMessage({id: 'solidity.download'}), downloadFn, true, intl.formatMessage({id: 'solidity.close'}), null)
}
const copyBytecode = () => {
@ -301,8 +313,9 @@ export const ContractSelection = (props: ContractSelectionProps) => {
<button
data-id="compilation-details"
className="btn btn-secondary btn-block"
onClick={() => {
onClick={async () => {
details()
await (api as any).call('compilationDetails', 'showDetails', payload)
}}
>
<CustomTooltip

@ -245,3 +245,8 @@
70% { top: -0.3em; }
100% { top: 0; }
}
#compileDetails {
margin: 15px;
padding: 15px;
}

@ -13,6 +13,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
api,
api: {currentFile, compileTabLogic, configurationSettings}
} = props
const [state, setState] = useState({
isHardhatProject: false,
isTruffleProject: false,
@ -207,6 +208,8 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
<div id="compileTabView">
<CompilerContainer
api={api}
//@ts-ignore
pluginProps={props}
isHardhatProject={state.isHardhatProject}
workspaceName={state.workspaceName}
isTruffleProject={state.isTruffleProject}

@ -8,6 +8,7 @@ export interface SolidityCompilerProps {
export interface CompilerContainerProps {
api: ICompilerApi,
pluginProps: SolidityCompilerProps,
compileTabLogic: CompileTabLogic,
isHardhatProject: boolean,
isTruffleProject: boolean,

@ -106,6 +106,7 @@ export const TabsUI = (props: TabsUIProps) => {
{getFileDecorationIcons(tab)}
<span
className="close-tabs"
data-id={`close_${tab.name}`}
onClick={(event) => {
props.onClose(index)
event.stopPropagation()

@ -97,6 +97,9 @@
"@remix-ui/settings": [
"libs/remix-ui/settings/src/index.ts"
],
"@remix-ui/solidity-compile-details": [
"libs/remix-ui/solidity-compile-details/src/index.ts"
],
"@remix-ui/solidity-compiler": [
"libs/remix-ui/solidity-compiler/src/index.ts"
],
@ -153,7 +156,7 @@
],
"@remixproject/walletconnect-plugin": [
"apps/walletconnect/src/index.ts"
],
]
}
}
}
Loading…
Cancel
Save