From 8b1a599d7548958cfe1e646c6a7411dcd8a0607c Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 7 Aug 2017 17:11:17 +0200 Subject: [PATCH] add new tabs --- src/app/compile-tab.js | 304 ++++++++++++++++++++++++++++++++ src/app/run-tab.js | 384 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 688 insertions(+) create mode 100644 src/app/compile-tab.js create mode 100644 src/app/run-tab.js diff --git a/src/app/compile-tab.js b/src/app/compile-tab.js new file mode 100644 index 0000000000..793d93b7d0 --- /dev/null +++ b/src/app/compile-tab.js @@ -0,0 +1,304 @@ +/* global alert */ +var $ = require('jquery') + +var yo = require('yo-yo') +const copy = require('clipboard-copy') + +var parseContracts = require('./contract/contractParser') +var publishOnSwarm = require('./contract/publishOnSwarm') +var modalDialog = require('./modaldialog') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .compileTabView { + padding: 2%; + } + .contract { + display: block; + margin: 3% 0; + } + .compileContainer extends ${styles.displayBox} { + margin-bottom: 2%; + } + .autocompileContainer { + width: 90px; + } + .autocompileTitle { + font-weight: bold; + margin: 1% 0; + } + .autocompile { + float: left; + align-self: center; + } + .autocompileText { + align-self: center; + margin: 1% 0; + font-size: 11px; + overflow: hidden; + word-break: normal; + line-height: initial; + margin-left: 3%; + } + .warnCompilationSlow { + color: orange; + } + .compileButtons { + display: flex; + align-items: baseline; + flex-wrap: wrap; + } + .name { + display: flex; + } + .size { + display: flex; + } + .compileButton extends ${styles.button} { + width: 130px; + min-width: 130px; + display: flex; + align-items: baseline; + justify-content: center; + margin-right: 1%; + font-size: 13px; + } + .container extends ${styles.displayBox} { + margin: 0; + display: flex; + align-items: center; + } + .contractNames extends ${styles.dropdown} { + width: 250px; + margin-right: 5%; + height: 32px; + font-size: 12px; + font-weight: bold; + } + .contractButtons { + display: flex; + cursor: pointer; + justify-content: center; + text-align: center; + } + .details extends ${styles.button} { + min-width: 70px; + } + .publish extends ${styles.button} { + min-width: 70px; + margin-left: 2%; + } + .copyDetails { + margin-top: 5%; + font-size: 20px; + cursor: pointer; + color: ${styles.colors.grey}; + opacity: .5; + } + .copyDetails:hover { + opacity: 1; + } + .detailsJSON { + padding: 8px 0; + background-color: ${styles.colors.white}; + border: none; + color: ${styles.colors.grey}; + } + .icon { + margin-right: 3%; + } + .spinningIcon { + margin-right: .3em; + animation: spin 2s linear infinite; + } + .bouncingIcon { + margin-right: .3em; + animation: bounce 2s infinite; + } + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + @-webkit-keyframes bounce { + 0% { + margin-bottom: 0; + color: ${styles.colors.transparent}; + } + 70% { + margin-bottom: 0; + color: ${styles.colors.grey}; + } + 100% { + margin-bottom: 0; + color: ${styles.colors.transparent}; + } +} +` + +module.exports = compileTab + +function compileTab (container, appAPI, appEvents, opts) { + if (typeof container === 'string') container = document.querySelector(container) + if (!container) throw new Error('no container given') + + // Containers + var warnCompilationSlow = yo`` + var compileIcon = yo`` + var compileContainer = yo` +
+
+
${compileIcon} Start to compile
+
+ + Auto compile +
+ ${warnCompilationSlow} +
+
+ ` + + // REGISTER EVENTS + + // compilationDuration + appEvents.compiler.register('compilationDuration', function tabHighlighting (speed) { + var settingsView = document.querySelector('#righthand-panel #menu .settingsView') + if (speed > 1000) { + warnCompilationSlow.setAttribute('title', `Last compilation took ${speed}ms. We suggest to turn off autocompilation.`) + warnCompilationSlow.style.display = 'inline-block' + settingsView.style.color = '#FF8B8B' + } else { + warnCompilationSlow.style.display = 'none' + settingsView.style.color = '' + } + }) + // loadingCompiler + appEvents.editor.register('contentChanged', function changedFile () { + var compileTab = document.querySelector('.compileView') + compileTab.style.color = styles.colors.red + compileIcon.classList.add(`${css.bouncingIcon}`) + }) + appEvents.compiler.register('loadingCompiler', function start () { + compileIcon.classList.add(`${css.spinningIcon}`) + warnCompilationSlow.style.display = 'none' + compileIcon.setAttribute('title', 'compiler is loading, please wait a few moments.') + }) + appEvents.compiler.register('compilationFinished', function finish () { + var compileTab = document.querySelector('.compileView') + compileTab.style.color = styles.colors.black + compileIcon.style.color = styles.colors.black + compileIcon.classList.remove(`${css.spinningIcon}`) + compileIcon.classList.remove(`${css.bouncingIcon}`) + compileIcon.setAttribute('title', 'idle') + }) + appEvents.compiler.register('compilationStarted', function start () { + compileIcon.classList.remove(`${css.bouncingIcon}`) + compileIcon.classList.add(`${css.spinningIcon}`) + compileIcon.setAttribute('title', 'compiling...') + }) + appEvents.compiler.register('compilerLoaded', function loaded () { + compileIcon.classList.remove(`${css.spinningIcon}`) + compileIcon.setAttribute('title', '') + }) + + var el = yo` +
+ ${compileContainer} + ${contractNames(container, appAPI, appEvents, opts)} +
+
+ ` + container.appendChild(el) + + /* ------------------------------------------------ + section CONTRACT DROPDOWN, DETAILS AND PUBLISH + ------------------------------------------------ */ + + function contractNames (container, appAPI, appEvents, opts) { + var contractsDetails = {} + appEvents.compiler.register('compilationFinished', function (success, data, source) { + // reset the contractMetadata list (used by the publish action) + contractsDetails = {} + // refill the dropdown list + getContractNames(success, data) + // hightlight the tab if error + if (success) { + document.querySelector('#righthand-panel #menu .compileView').style.color = '' + } else { + document.querySelector('#righthand-panel #menu .compileView').style.color = '#FF8B8B' + } + // display warning error if any + var errorContainer = container.querySelector('.error') + errorContainer.innerHTML = '' + if (data['error']) { + appAPI.compilationMessage(data['error'], $(errorContainer)) + } + if (data['errors']) { + data['errors'].forEach(function (err) { + appAPI.compilationMessage(err, $(errorContainer)) + }) + } + if (errorContainer.innerHTML === '') { + appAPI.compilationMessage('Compilation successful without warning', $(errorContainer), {type: 'success'}) + } + }) + + var el = yo` +
+ +
+
{ details() }}>Details
+
{ publish(appAPI) }}>Publish
+
+
+ ` + + // HELPERS + + // GET NAMES OF ALL THE CONTRACTS + function getContractNames (success, data) { + var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) + contractNames.innerHTML = '' + if (success) { + contractNames.removeAttribute('disabled') + for (var name in data.contracts) { + contractsDetails[name] = parseContracts(name, data.contracts[name], appAPI.currentCompiledSourceCode()) + var contractName = yo` + ` + contractNames.appendChild(contractName) + } + appAPI.resetDapp(contractsDetails) + } else { + contractNames.setAttribute('disabled', true) + appAPI.resetDapp({}) + } + } + + function details () { + var select = el.querySelector('select') + var contractName = select.children[select.selectedIndex].innerText + var details = JSON.stringify(contractsDetails[contractName], null, '\t') + var copyDetails = yo`
{ copy(details) }} aria-hidden="true">
` + var log = yo`
${details} ${copyDetails}
` + modalDialog(contractName, log, {label: 'OK'}, {label: ''}) + } + + function publish (appAPI) { + var selectContractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) + var contract = contractsDetails[selectContractNames.children[selectContractNames.selectedIndex].innerText] + publishOnSwarm(contract, appAPI, function (err) { + if (err) { + alert('Failed to publish metadata: ' + err) + } else { + alert('Metadata published successfully') + } + }) + } + return el + } +} diff --git a/src/app/run-tab.js b/src/app/run-tab.js new file mode 100644 index 0000000000..bf9cb478ab --- /dev/null +++ b/src/app/run-tab.js @@ -0,0 +1,384 @@ +/* global alert */ +var $ = require('jquery') + +var yo = require('yo-yo') +var helper = require('../lib/helper.js') +var txExecution = require('./execution/txExecution') +var txFormat = require('./execution/txFormat') +var txHelper = require('./execution/txHelper') +const copy = require('clipboard-copy') + +// -------------- styling ---------------------- +var csjs = require('csjs-inject') +var styleGuide = require('./style-guide') +var styles = styleGuide() + +var css = csjs` + .runTabView { + padding: 2%; + display: flex; + flex-direction: column; + } + .settings extends ${styles.displayBox} { + margin-bottom: 2%; + padding: 10px 15px 15px 15px; + } + .crow { + margin-top: .5em; + display: flex; + } + .col1 extends ${styles.titleL} { + width: 30%; + float: left; + align-self: center; + } + .col1_1 extends ${styles.titleM} { + font-size: 12px; + width: 25%; + min-width: 50px; + float: left; + align-self: center; + } + .col2 extends ${styles.inputField}{ + width: 75%; + float: left; + } + .select extends ${styles.dropdown} { + width: 75%; + float: left; + text-align: center; + } + .copyaddress { + color: #C6CFF7; + margin-left: 0.5em; + margin-top: 0.7em; + cursor: pointer; + opacity: .7; + } + .copyaddress:hover { + opacity: 1; + } + .selectAddress extends ${styles.dropdown} { + width: 70%; + float: left; + text-align: center; + } + .instanceContainer extends ${styles.displayBox} { + display: flex; + flex-direction: column; + background-color: ${styles.colors.lightBlue}; + margin-top: 2%; + } + .container extends ${styles.displayBox} { + margin-top: 2%; + } + .contractNames extends ${styles.dropdown} { + height: 32px; + font-size: 12px; + width: 100%; + font-weight: bold; + background-color: ${styles.colors.lightGrey} + } + .buttons { + display: flex; + cursor: pointer; + justify-content: center; + flex-direction: column; + text-align: center; + font-size: 12px; + } + .button { + display: flex; + align-items: flex-end; + margin-top: 2%; + } + .atAddress extends ${styles.button} { + background-color: ${styles.colors.green}; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .create extends ${styles.button} { + background-color: ${styles.colors.lightRed}; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .input extends ${styles.inputField} { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + width: 75%; + font-size: 10px; + padding-left: 10px; + } + .noInstancesText extends ${styles.displayBox} { + text-align: center; + color: ${styles.colors.lightGrey}; + font-style: italic; + } + .legend extends ${styles.displayBox} { + border-radius: 5px; + display: flex; + justify-content: center; + padding: 15px 8px; + word-break: normal; + flex-wrap: wrap; + } + .item { + margin-right: 1em; + display: flex; + align-items: center; + } + .transact { + color: ${styles.colors.lightRed}; + margin-right: .3em; + } + .payable { + color: ${styles.colors.red}; + margin-right: .3em; + } + .call { + color: #9DC1F5; + margin-right: .3em; + } +` + +module.exports = runTab + +var instanceContainer = yo`
` +var noInstancesText = yo`
No Contract Instances.
` + +function runTab (container, appAPI, appEvents, opts) { + var el = yo` +
+ ${settings(appAPI, appEvents)} + ${legend()} + ${contractDropdown(appAPI, appEvents, instanceContainer)} + ${instanceContainer} +
+ ` + container.appendChild(el) + + // DROPDOWN + var selectExEnv = el.querySelector('#selectExEnvOptions') + selectExEnv.addEventListener('change', function (event) { + if (!appAPI.executionContextChange(selectExEnv.options[selectExEnv.selectedIndex].value)) { + selectExEnv.value = appAPI.executionContextProvider() + } + fillAccountsList(appAPI, el) + instanceContainer.innerHTML = '' // clear the instances list + instanceContainer.appendChild(noInstancesText) + }) + selectExEnv.value = appAPI.executionContextProvider() + fillAccountsList(appAPI, el) + setInterval(() => { updateAccountBalances(container, appAPI) }, 1000) +} + + +function fillAccountsList (appAPI, container) { + var $txOrigin = $(container.querySelector('#txorigin')) + $txOrigin.empty() + appAPI.udapp().getAccounts((err, accounts) => { + if (err) { console.log(err) } + if (accounts && accounts[0]) { + for (var a in accounts) { $txOrigin.append($('`) + } + } else { + selectContractNames.setAttribute('disabled', true) + } + setInputParamsPlaceHolder() + } + + return el +} + +/* ------------------------------------------------ + section SETTINGS: Environment, Account, Gas, Value +------------------------------------------------ */ +function settings (appAPI, appEvents) { + // COPY ADDRESS + function copyAddress () { + copy(document.querySelector('#runTabView #txorigin').value) + } + + // SETTINGS HTML + var el = yo` +
+
+
+ Environment +
+ +
+
+
Account
+ + +
+
+
Gas limit
+ +
+
+
Gas Price
+ +
+
+
Value
+ +
+
+ ` + + // EVENTS + appEvents.udapp.register('transactionExecuted', (to, data, lookupOnly, txResult) => { + if (!lookupOnly) el.querySelector('#value').value = '0' + }) + + return el +} + +/* ------------------------------------------------ + section LEGEND +------------------------------------------------ */ +function legend () { + var el = + yo` +
+
Transact
+
Transact(Payable)
+
Call
+
+ ` + return el +}