Improve contract selection

pull/1339/head
ioedeveloper 3 years ago
parent a25f1ef088
commit 1b08ed87fc
  1. 170
      apps/remix-ide/src/app/tabs/compile-tab.js
  2. 1
      libs/remix-ui/solidity-compiler/src/index.ts
  3. 2
      libs/remix-ui/solidity-compiler/src/lib/compileTabLogic.ts
  4. 44
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  5. 0
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.css
  6. 6
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  7. 7
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts

@ -1,8 +1,9 @@
/* global */
import React from 'react' // eslint-disable-line
import ReactDOM from 'react-dom'
import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { SolidityCompiler, CompileTab as CompileTabLogic } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { ViewPlugin } from '@remixproject/engine-web'
import { Renderer } from '@remix-ui/renderer'
import * as packageJson from '../../../../../package.json'
import publishToStorage from '../../publishToStorage'
import { compile } from '@remix-project/remix-solidity'
@ -18,7 +19,7 @@ const copyToClipboard = require('../ui/copy-to-clipboard')
const modalDialogCustom = require('../ui/modal-dialog-custom')
const parseContracts = require('./compileTab/contractParser')
const addTooltip = require('../ui/tooltip')
const Renderer = require('../ui/renderer')
// const Renderer = require('../ui/renderer')
const globalRegistry = require('../../global/registry')
var css = require('./styles/compile-tab-styles')
@ -58,11 +59,10 @@ class CompileTab extends ViewPlugin {
// dependencies
this.editor = editor
this.config = config
this.renderer = new Renderer(this)
// this.renderer = new Renderer(this)
this.fileManager = fileManager
this.contractsDetails = {}
this.data = {
contractsDetails: {},
eventHandlers: {},
loading: false
}
@ -86,7 +86,7 @@ class CompileTab extends ViewPlugin {
this._view.errorContainer.innerHTML = ''
}
this.currentFile = ''
this.data.contractsDetails = {}
this.contractsDetails = {}
yo.update(this._view.contractSelection, this.contractSelection())
this.emit('statusChanged', { key: 'none' })
this.renderComponent()
@ -162,9 +162,9 @@ class CompileTab extends ViewPlugin {
})
} else this.emit('statusChanged', { key: 'succeed', title: 'compilation successful', type: 'success' })
// Store the contracts
this.data.contractsDetails = {}
this.contractsDetails = {}
this.compiler.visitContracts((contract) => {
this.data.contractsDetails[contract.name] = parseContracts(
this.contractsDetails[contract.name] = parseContracts(
contract.name,
contract.object,
this.compiler.getSource(contract.file)
@ -181,11 +181,11 @@ class CompileTab extends ViewPlugin {
yo.update(this._view.contractSelection, contractSelection)
if (data.error) {
this.renderer.error(
data.error.formattedMessage || data.error,
this._view.errorContainer,
{ type: data.error.severity || 'error', errorType: data.error.type }
)
// this.renderer.error(
// data.error.formattedMessage || data.error,
// this._view.errorContainer,
// { type: data.error.severity || 'error', errorType: data.error.type }
// )
if (data.error.mode === 'panic') {
return modalDialogCustom.alert(yo`
<div><i class="fas fa-exclamation-circle ${css.panicError}" aria-hidden="true"></i>
@ -199,13 +199,14 @@ class CompileTab extends ViewPlugin {
data.errors.forEach((err) => {
if (this.config.get('hideWarnings')) {
if (err.severity !== 'warning') {
this.renderer.error(err.formattedMessage, this._view.errorContainer, { type: err.severity, errorType: err.type })
// this.renderer.error(err.formattedMessage, this._view.errorContainer, { type: err.severity, errorType: err.type })
}
} else {
this.renderer.error(err.formattedMessage, this._view.errorContainer, { type: err.severity, errorType: err.type })
// this.renderer.error(err.formattedMessage, this._view.errorContainer, { type: err.severity, errorType: err.type })
}
})
}
this.renderComponent()
}
this.compiler.event.register('compilationFinished', this.data.eventHandlers.onCompilationFinished)
@ -301,73 +302,73 @@ class CompileTab extends ViewPlugin {
* Section to select the compiled contract
* @param {string[]} contractList Names of the compiled contracts
*/
contractSelection (contractMap) {
// Return the file name of a path: ex "browser/ballot.sol" -> "ballot.sol"
const getFileName = (path) => {
const part = path.split('/')
return part[part.length - 1]
}
const contractList = contractMap ? Object.keys(contractMap).map((key) => ({
name: key,
file: getFileName(contractMap[key].file)
})) : []
const selectEl = yo`
<select
onchange="${e => this.selectContract(e.target.value)}"
data-id="compiledContracts" id="compiledContracts" class="custom-select"
>
${contractList.map(({ name, file }) => yo`<option value="${name}">${name} (${file})</option>`)}
</select>
`
// define swarm logo
const result = contractList.length
? yo`<section class="${css.compilerSection} pt-3">
<!-- Select Compiler Version -->
<div class="mb-3">
<label class="${css.compilerLabel} form-check-label" for="compiledContracts">Contract</label>
${selectEl}
</div>
<article class="mt-2 pb-0">
<button id="publishOnSwarm" class="btn btn-secondary btn-block" title="Publish on Swarm" onclick="${() => { publishToStorage('swarm', this.fileProvider, this.fileManager, this.data.contractsDetails[this.selectedContract]) }}">
<span>Publish on Swarm</span>
<img id="swarmLogo" class="${css.storageLogo} ml-2" src="assets/img/swarm.webp">
</button>
<button id="publishOnIpfs" class="btn btn-secondary btn-block" title="Publish on Ipfs" onclick="${() => { publishToStorage('ipfs', this.fileProvider, this.fileManager, this.data.contractsDetails[this.selectedContract]) }}">
<span>Publish on Ipfs</span>
<img id="ipfsLogo" class="${css.storageLogo} ml-2" src="assets/img/ipfs.webp">
</button>
<button data-id="compilation-details" class="btn btn-secondary btn-block" title="Display Contract Details" onclick="${() => { this.details() }}">
Compilation Details
</button>
<!-- Copy to Clipboard -->
<div class="${css.contractHelperButtons}">
<div class="input-group">
<div class="btn-group" role="group" aria-label="Copy to Clipboard">
<button class="btn ${css.copyButton}" title="Copy ABI to clipboard" onclick="${() => { this.copyABI() }}">
<i class="${css.copyIcon} far fa-copy" aria-hidden="true"></i>
<span>ABI</span>
</button>
<button class="btn ${css.copyButton}" title="Copy Bytecode to clipboard" onclick="${() => { this.copyBytecode() }}">
<i class="${css.copyIcon} far fa-copy" aria-hidden="true"></i>
<span>Bytecode</span>
</button>
</div>
</div>
</div>
</div>
</section>`
: yo`<section class="${css.container} clearfix"><article class="px-2 mt-2 pb-0 d-flex">
<span class="mt-2 mx-3 w-100 alert alert-warning" role="alert">No Contract Compiled Yet</span>
</article></section>`
if (contractList.length) {
this.selectedContract = selectEl.value
} else {
delete this.selectedContract
}
return result
}
// contractSelection (contractMap) {
// // Return the file name of a path: ex "browser/ballot.sol" -> "ballot.sol"
// const getFileName = (path) => {
// const part = path.split('/')
// return part[part.length - 1]
// }
// const contractList = contractMap ? Object.keys(contractMap).map((key) => ({
// name: key,
// file: getFileName(contractMap[key].file)
// })) : []
// const selectEl = yo`
// <select
// onchange="${e => this.selectContract(e.target.value)}"
// data-id="compiledContracts" id="compiledContracts" class="custom-select"
// >
// ${contractList.map(({ name, file }) => yo`<option value="${name}">${name} (${file})</option>`)}
// </select>
// `
// // define swarm logo
// const result = contractList.length
// ? yo`<section class="${css.compilerSection} pt-3">
// <!-- Select Compiler Version -->
// <div class="mb-3">
// <label class="${css.compilerLabel} form-check-label" for="compiledContracts">Contract</label>
// ${selectEl}
// </div>
// <article class="mt-2 pb-0">
// <button id="publishOnSwarm" class="btn btn-secondary btn-block" title="Publish on Swarm" onclick="${() => { publishToStorage('swarm', this.fileProvider, this.fileManager, this.data.contractsDetails[this.selectedContract]) }}">
// <span>Publish on Swarm</span>
// <img id="swarmLogo" class="${css.storageLogo} ml-2" src="assets/img/swarm.webp">
// </button>
// <button id="publishOnIpfs" class="btn btn-secondary btn-block" title="Publish on Ipfs" onclick="${() => { publishToStorage('ipfs', this.fileProvider, this.fileManager, this.data.contractsDetails[this.selectedContract]) }}">
// <span>Publish on Ipfs</span>
// <img id="ipfsLogo" class="${css.storageLogo} ml-2" src="assets/img/ipfs.webp">
// </button>
// <button data-id="compilation-details" class="btn btn-secondary btn-block" title="Display Contract Details" onclick="${() => { this.details() }}">
// Compilation Details
// </button>
// <!-- Copy to Clipboard -->
// <div class="${css.contractHelperButtons}">
// <div class="input-group">
// <div class="btn-group" role="group" aria-label="Copy to Clipboard">
// <button class="btn ${css.copyButton}" title="Copy ABI to clipboard" onclick="${() => { this.copyABI() }}">
// <i class="${css.copyIcon} far fa-copy" aria-hidden="true"></i>
// <span>ABI</span>
// </button>
// <button class="btn ${css.copyButton}" title="Copy Bytecode to clipboard" onclick="${() => { this.copyBytecode() }}">
// <i class="${css.copyIcon} far fa-copy" aria-hidden="true"></i>
// <span>Bytecode</span>
// </button>
// </div>
// </div>
// </div>
// </div>
// </section>`
// : yo`<section class="${css.container} clearfix"><article class="px-2 mt-2 pb-0 d-flex">
// <span class="mt-2 mx-3 w-100 alert alert-warning" role="alert">No Contract Compiled Yet</span>
// </article></section>`
// if (contractList.length) {
// this.selectedContract = selectEl.value
// } else {
// delete this.selectedContract
// }
// return result
// }
// TODO : Add success alert when compilation succeed
contractCompiledSuccess () {
@ -403,7 +404,7 @@ class CompileTab extends ViewPlugin {
web3Deploy: 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract'
}
if (!this.selectedContract) throw new Error('No contract compiled yet')
const contractProperties = this.data.contractsDetails[this.selectedContract]
const contractProperties = this.contractsDetails[this.selectedContract]
const log = yo`<div class="${css.detailsJSON}"></div>`
Object.keys(contractProperties).map(propertyName => {
const copyDetails = yo`<span class="${css.copyDetails}">${copyToClipboard(() => contractProperties[propertyName])}</span>`
@ -457,7 +458,7 @@ class CompileTab extends ViewPlugin {
getContractProperty (property) {
if (!this.selectedContract) throw new Error('No contract compiled yet')
const contractProperties = this.data.contractsDetails[this.selectedContract]
const contractProperties = this.contractsDetails[this.selectedContract]
return contractProperties[property] || null
}
@ -503,6 +504,7 @@ class CompileTab extends ViewPlugin {
plugin={this}
compileTabLogic={this.compileTabLogic}
compiledFileName={this.currentFile}
contractsDetails={this.contractsDetails}
/>
, this.el)
}

@ -1 +1,2 @@
export * from './lib/solidity-compiler'
export * from './lib/compileTabLogic'

@ -9,7 +9,7 @@ const profile = {
description: 'Compile solidity contracts - Logic',
version: packageJson.version
}
export default class CompileTab extends Plugin {
export class CompileTab extends Plugin {
public compiler
public optimize
public runs: number

@ -5,11 +5,9 @@ import { PublishToStorage } from '@remix-ui/publish-to-storage'
import './css/style.css'
export const ContractSelection = (props: ContractSelectionProps) => {
const { contractMap } = props
const [state, setState] = useState({
contractList: null,
selectedContract: ''
})
const { contractMap, fileProvider, fileManager, contractsDetails } = props
const [contractList, setContractList] = useState([])
const [selectedContract, setSelectedContract] = useState('')
useEffect(() => {
const contractList = contractMap ? Object.keys(contractMap).map((key) => ({
@ -17,9 +15,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
file: getFileName(contractMap[key].file)
})) : []
setState(prevState => {
return { ...prevState, contractList }
})
setContractList(contractList)
}, [])
// Return the file name of a path: ex "browser/ballot.sol" -> "ballot.sol"
const getFileName = (path) => {
@ -29,9 +25,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
}
const selectContract = (contractName: string) => {
setState(prevState => {
return { ...prevState, selectedContract: contractName }
})
setSelectedContract(contractName)
}
const handlePublishToStorage = (type) => {
@ -60,12 +54,15 @@ export const ContractSelection = (props: ContractSelectionProps) => {
}
const getContractProperty = (property) => {
// if (!this.selectedContract) throw new Error('No contract compiled yet')
// const contractProperties = this.data.contractsDetails[this.selectedContract]
// return contractProperties[property] || null
if (!selectedContract) throw new Error('No contract compiled yet')
const contractProperties = contractsDetails[selectedContract]
return contractProperties[property] || null
}
const details = () => {
if (!selectedContract) throw new Error('No contract compiled yet')
const help = {
Assembly: 'Assembly opcodes describing the contract including corresponding solidity source code',
Opcodes: 'Assembly opcodes describing the contract',
@ -80,17 +77,22 @@ export const ContractSelection = (props: ContractSelectionProps) => {
swarmLocation: 'Swarm url where all metadata information can be found (contract needs to be published first)',
web3Deploy: 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract'
}
if (!this.selectedContract) throw new Error('No contract compiled yet')
const contractProperties = this.data.contractsDetails[this.selectedContract]
const log = yo`<div class="${css.detailsJSON}"></div>`
const contractProperties = contractsDetails[selectedContract]
const log = <div className="remixui_detailsJSON"></div>
Object.keys(contractProperties).map(propertyName => {
const copyDetails = yo`<span class="${css.copyDetails}">${copyToClipboard(() => contractProperties[propertyName])}</span>`
const questionMark = yo`<span class="${css.questionMark}"><i title="${help[propertyName]}" class="fas fa-question-circle" aria-hidden="true"></i></span>`
const copyDetails = <span className="remixui_copyDetails">{ copyToClipboard(() => contractProperties[propertyName]) }</span>
const questionMark = <span className="remixui_questionMark"><i title={ help[propertyName] } className="fas fa-question-circle" aria-hidden="true"></i></span>
log.appendChild(yo`<div class=${css.log}>
<div class="${css.key}">${propertyName} ${copyDetails} ${questionMark}</div>
${this.insertValue(contractProperties, propertyName)}
</div>`)
})
return {
}
modalDialog(this.selectedContract, log, { label: '' }, { label: 'Close' })
}
@ -101,13 +103,13 @@ export const ContractSelection = (props: ContractSelectionProps) => {
return (
// define swarm logo
<>
{ state.contractList.length ?
{ contractList.length ?
<section className="remixui_compilerSection pt-3">
{/* Select Compiler Version */}
<div className="mb-3">
<label className="remixui_compilerLabel form-check-label" htmlFor="compiledContracts">Contract</label>
<select onChange={(e) => selectContract(e.target.value)} data-id="compiledContracts" id="compiledContracts" className="custom-select">
{state.contractList.map(({ name, file }) => <option value={name}>{name} ({file})</option>)}
{ contractList.map(({ name, file }) => <option value={name}>{name} ({file})</option>)}
</select>
</div>
<article className="mt-2 pb-0">

@ -1,14 +1,14 @@
import React, { useState, useEffect } from 'react' // eslint-disable-line
import { SolidityCompilerProps } from './types'
import { CompilerContainer } from './compiler-container' // eslint-disable-line
import { ContractSelection } from './contract-selection'
import { Toaster } from '@remix-ui/toaster' // eslint-disable-line
import { ModalDialog } from '@remix-ui/modal-dialog' // eslint-disable-line
import { Renderer } from '@remix-ui/renderer'
import './css/style.css'
export const SolidityCompiler = (props: SolidityCompilerProps) => {
const { editor, config, queryParams, plugin, compileTabLogic, compiledFileName } = props
const { editor, config, queryParams, plugin, compileTabLogic, compiledFileName, fileProvider, fileManager, contractsDetails } = props
const [state, setState] = useState({
contractsDetails: {},
eventHandlers: {},
@ -66,7 +66,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
<>
<div id="compileTabView">
<CompilerContainer editor={editor} config={config} queryParams={queryParams} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={compiledFileName} />
{/* ${this._view.contractSelection} */}
<ContractSelection contractMap={{}} fileProvider={fileProvider} fileManager={fileManager} contractsDetails={contractsDetails} />
<div className="remixui_errorBlobs p-4" data-id="compiledErrors"></div>
</div>
<Toaster message={state.toasterMsg} />

@ -8,7 +8,8 @@ export interface SolidityCompilerProps {
plugin: any,
queryParams: any,
compileTabLogic: any,
compiledFileName: string
compiledFileName: string,
contractsDetails: Record<string, any>
}
export interface CompilerContainerProps {
@ -23,5 +24,7 @@ export interface CompilerContainerProps {
export interface ContractSelectionProps {
contractMap: {
file: string
}
} | Record<string, any>,
fileManager: any,
fileProvider: any
}

Loading…
Cancel
Save