Add card.js, move pending to terminal and restructure recorder

pull/1/head
ninabreznik 7 years ago committed by yann300
parent 0de36c54de
commit f5758d8a85
  1. 3
      src/app.js
  2. 1
      src/app/panels/editor-panel.js
  3. 27
      src/app/panels/styles/terminal-styles.js
  4. 32
      src/app/panels/terminal.js
  5. 197
      src/app/tabs/run-tab.js
  6. 32
      src/app/tabs/styles/run-tab-styles.js
  7. 93
      src/app/ui/card.js
  8. 13
      src/app/ui/styles-guide/style-guide.js
  9. 1
      src/app/ui/styles/dropdown-styles.js
  10. 1
      src/recorder.js
  11. 11
      src/universal-dapp-styles.js
  12. 5
      src/universal-dapp-ui.js

@ -523,7 +523,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
editor: self._components.editor, editor: self._components.editor,
config: self._api.config, config: self._api.config,
txListener: txlistener, txListener: txlistener,
contextview: self._components.contextView contextview: self._components.contextView,
udapp: () => { return udapp }
} }
}) })
this._components.editorpanel.event.register('resize', direction => self._adjustLayout(direction)) this._components.editorpanel.event.register('resize', direction => self._adjustLayout(direction))

@ -28,6 +28,7 @@ class EditorPanel {
terminal: new Terminal({ terminal: new Terminal({
api: { api: {
cmdInterpreter: self._api.cmdInterpreter, cmdInterpreter: self._api.cmdInterpreter,
udapp: self._api.udapp,
getPosition (event) { getPosition (event) {
var limitUp = 36 var limitUp = 36
var limitDown = 20 var limitDown = 20

@ -27,20 +27,20 @@ var css = csjs`
display : flex; display : flex;
align-items : center; align-items : center;
width : 100%; width : 100%;
padding : 5px;
} }
.clear { .clear {
margin-left : 10px; margin-right : 20px;
margin-right : 10px;
width : 10px; width : 10px;
cursor : pointer; cursor : pointer;
color : ${styles.terminal.icon_Color_TogglePanel}; color : ${styles.terminal.icon_Color_TogglePanel};
display : flex;
} }
.clear:hover { .clear:hover {
color : ${styles.terminal.icon_HoverColor_Menu}; color : ${styles.terminal.icon_HoverColor_Menu};
} }
.toggleTerminal { .toggleTerminal {
margin-right : 10px; margin-right : 20px;
margin-left : 20px;
font-size : 14px; font-size : 14px;
font-weight : bold; font-weight : bold;
cursor : pointer; cursor : pointer;
@ -56,6 +56,7 @@ var css = csjs`
height : 100%; height : 100%;
overflow-y : auto; overflow-y : auto;
font-family : monospace; font-family : monospace;
margin : 0px;
} }
.terminal_bg { .terminal_bg {
display : flex; display : flex;
@ -137,9 +138,21 @@ var css = csjs`
align-items : center; align-items : center;
justify-content : center; justify-content : center;
} }
.listen { .listen {}
min-width : 120px; .verticalLine {
display : flex; border-left : 1px solid ${styles.colors.veryLightGrey};
height : 65%;
margin-right : 30px; }
.pendingTx {
border : 1px solid ${styles.terminal.icon_HoverColor_Menu};
border-radius: 50%;
margin-right: 30px;
min-width: 13px;
height: 13px;
display: flex;
justify-content: center;
align-items: center;
font-size: 10px;
} }
.dragbarHorizontal { .dragbarHorizontal {
position : absolute; position : absolute;

@ -105,23 +105,40 @@ class Terminal {
${self._view.input} ${self._view.input}
</div> </div>
` `
self._view.icon = yo`<i onmouseenter=${hover} onmouseleave=${hover} onmousedown=${minimize} class="${css.toggleTerminal} fa fa-angle-double-down"></i>` self._view.icon = yo`
self._view.dragbar = yo`<div onmousedown=${mousedown} class=${css.dragbarHorizontal}></div>` <i onmouseenter=${hover} onmouseleave=${hover} onmousedown=${minimize}
class="${css.toggleTerminal} fa fa-angle-double-down"></i>`
self._view.dragbar = yo`
<div onmousedown=${mousedown} class=${css.dragbarHorizontal}></div>`
self._view.dropdown = self._components.dropdown.render() self._view.dropdown = self._components.dropdown.render()
self._view.pendingTxCount = yo`<div class=${css.pendingTx}>${self._view.pendingTxCount}</div>`
self._view.bar = yo` self._view.bar = yo`
<div class=${css.bar}> <div class=${css.bar}>
${self._view.dragbar} ${self._view.dragbar}
<div class=${css.menu}> <div class=${css.menu}>
${self._view.icon} ${self._view.icon}
<div class=${css.clear} onclick=${clear}> <div class=${css.clear} onclick=${clear}>
<i class="fa fa-ban" aria-hidden="true" onmouseenter=${hover} onmouseleave=${hover}></i> <i class="fa fa-ban" aria-hidden="true" title="Clear console"
onmouseenter=${hover} onmouseleave=${hover}></i>
</div>
${self._view.pendingTxCount}
<div class=${css.verticalLine}></div>
<div class=${css.listen}>
<input onchange=${listenOnNetwork} type="checkbox"
title="If checked Remix will listen on all transactions mined in the current environment and not only transactions created by you">
</div> </div>
${self._view.dropdown} ${self._view.dropdown}
<div class=${css.search}><i class="fa fa-search ${css.searchIcon}" aria-hidden="true"></i><input type="text" class=${css.filter} onkeydown=${filter} placeholder="Search transactions"></div> <div class=${css.search}>
<div class=${css.listen}><input onchange=${listenOnNetwork} type="checkbox"><label title="If checked Remix will listen on all transactions mined in the current environment and not only transactions created from the GUI">Listen on network</label></div> <i class="fa fa-search ${css.searchIcon}" aria-hidden="true"></i>
<input type="text" class=${css.filter} onkeydown=${filter} placeholder="Search transactions">
</div>
</div> </div>
</div> </div>
` `
setInterval(() => {
updatePendingTxs(self._api, self._view.pendingTxCount)
}, 5000)
function listenOnNetwork (ev) { function listenOnNetwork (ev) {
self.event.trigger('listenOnNetWork', [ev.currentTarget.checked]) self.event.trigger('listenOnNetWork', [ev.currentTarget.checked])
} }
@ -563,5 +580,10 @@ function domTerminalFeatures (self, scopedCommands) {
} }
function blockify (el) { return yo`<div class=${css.block}>${el}</div>` } function blockify (el) { return yo`<div class=${css.block}>${el}</div>` }
// PENDING TX
function updatePendingTxs (api, el) {
var count = Object.keys(api.udapp().pendingTransactions()).length
el.innerText = count
}
module.exports = Terminal module.exports = Terminal

@ -1,76 +1,116 @@
'use strict' 'use strict'
var $ = require('jquery') var $ = require('jquery')
var yo = require('yo-yo') var yo = require('yo-yo')
var helper = require('../../lib/helper.js')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var ethJSUtil = require('ethereumjs-util')
var csjs = require('csjs-inject')
var txExecution = remixLib.execution.txExecution var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat var txFormat = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var EventManager = remixLib.EventManager
var helper = require('../../lib/helper.js')
var executionContext = require('../../execution-context') var executionContext = require('../../execution-context')
var modalDialogCustom = require('../ui/modal-dialog-custom') var modalDialogCustom = require('../ui/modal-dialog-custom')
var copyToClipboard = require('../ui/copy-to-clipboard') var copyToClipboard = require('../ui/copy-to-clipboard')
var Card = require('../ui/card')
var Recorder = require('../../recorder') var Recorder = require('../../recorder')
var EventManager = remixLib.EventManager
var addTooltip = require('../ui/tooltip') var addTooltip = require('../ui/tooltip')
var ethJSUtil = require('ethereumjs-util')
var MultiParamManager = require('../../multiParamManager')
var csjs = require('csjs-inject')
var css = require('./styles/run-tab-styles') var css = require('./styles/run-tab-styles')
var MultiParamManager = require('../../multiParamManager')
var instanceContainer = yo`<div class="${css.instanceContainer}"></div>`
var instanceContainerTitle = yo`
<div class=${css.instanceContainerTitle}>UDapps of deployed contracts</div>`
var noInstancesText = yo`
<div class="${css.noInstancesText}">Currently you have no contract instances.</div>`
var pendingTxsText = yo`<span>0 pending transactions</span>`
function runTab (appAPI = {}, appEvents = {}, opts = {}) { function runTab (appAPI = {}, appEvents = {}, opts = {}) {
var container = yo`<div class="${css.runTabView}" id="runTabView" ></div>` /* -------------------------
VARIABLES
--------------------------- */
var self = this
var event = new EventManager() var event = new EventManager()
var clearInstanceElement = yo` self._view = {}
<i class="${css.clearinstance} ${css.icon} fa fa-trash" self.data = {
onclick=${() => { event.trigger('clearInstance', []) }} count: 0,
title="Clear Instances List" aria-hidden="true"> text: `All transactions (deployed contracts and function executions)
in this environment can be saved and replayed in
another environment. i.e. Transactions created in
Javascript VM can be replayed in the Ropsten network.`
}
self._view.recorderCount = yo`<span>0</span>`
self._view.instanceContainer = yo`<div class="${css.instanceContainer}"></div>`
self._view.clearInstanceElement = yo`
<i class="${css.clearinstance} ${css.icon} fa fa-trash" onclick=${() => clearInstanceList(self)}
title="Clear instances list and reset recorder" aria-hidden="true">
</i>` </i>`
self._view.instanceContainerTitle = yo`
<div class=${css.instanceContainerTitle}
title="Autogenerated generic user interfaces for interaction with deployed contracts">
UI for Deployed Contracts
${self._view.clearInstanceElement}
</div>`
self._view.noInstancesText = yo`
<div class="${css.noInstancesText}">
Currently you have no contract instances to interact with.
</div>`
clearInstanceElement.addEventListener('click', () => { var container = yo`<div class="${css.runTabView}" id="runTabView" ></div>`
event.trigger('clearInstance', []) var recorderInterface = makeRecorder(event, appAPI, appEvents, opts, self)
})
var recorderInterface = makeRecorder(event, appAPI, appEvents, opts) self._view.collapsedView = yo`
var pendingTxsContainer = yo` <div class=${css.recorderCollapsedView}>
<div class="${css.pendingTxsContainer}"> <div class=${css.recorderCount}>${self._view.recorderCount}</div>
<div class="${css.pendingTxsText}"> </div>`
${pendingTxsText}
<span class="${css.transactionActions}"> self._view.expandedView = yo`
<div class=${css.recorderExpandedView}>
<div class=${css.recorderDescription}>
${self.data.text}
</div>
<div class="${css.transactionActions}">
${recorderInterface.recordButton} ${recorderInterface.recordButton}
${recorderInterface.runButton} ${recorderInterface.runButton}
${clearInstanceElement} </div>
</span>
</div> </div>
</div>` </div>`
self.recorderOpts = {
title: 'Events recorded:',
collapsedView: self._view.collapsedView
}
var recorderCard = new Card({}, {}, self.recorderOpts)
recorderCard.event.register('expandCollapseCard', (arrow, body, status) => {
body.innerHTML = ''
status.innerHTML = ''
if (arrow === 'up') {
status.appendChild(self._view.collapsedView)
body.appendChild(self._view.expandedView)
} else if (arrow === 'down') {
status.appendChild(self._view.collapsedView)
}
})
/* -------------------------
MAIN HTML ELEMENT
--------------------------- */
var el = yo` var el = yo`
<div> <div>
${settings(container, appAPI, appEvents, opts)} ${settings(container, appAPI, appEvents, opts)}
${contractDropdown(event, appAPI, appEvents, opts, instanceContainer)} ${contractDropdown(event, appAPI, appEvents, opts, self)}
${pendingTxsContainer} ${recorderCard.render()}
${instanceContainer} ${self._view.instanceContainer}
</div> </div>
` `
container.appendChild(el) container.appendChild(el)
// PENDING transactions /* -------------------------
function updatePendingTxs (container, appAPI) { HELPER FUNCTIONS
var pendingCount = Object.keys(opts.udapp.pendingTransactions()).length --------------------------- */
pendingTxsText.innerText = pendingCount + ' pending transactions'
}
// DROPDOWN // DROPDOWN
var selectExEnv = el.querySelector('#selectExEnvOptions') var selectExEnv = el.querySelector('#selectExEnvOptions')
function clearInstanceList (self) {
event.trigger('clearInstance', [])
self._view.recorderCount.innerText = 0
}
function setFinalContext () { function setFinalContext () {
// set the final context. Cause it is possible that this is not the one we've originaly selected // set the final context. Cause it is possible that this is not the one we've originaly selected
selectExEnv.value = executionContext.getProvider() selectExEnv.value = executionContext.getProvider()
@ -95,20 +135,23 @@ function runTab (appAPI = {}, appEvents = {}, opts = {}) {
modalDialogCustom.alert(alertMsg) modalDialogCustom.alert(alertMsg)
}, setFinalContext) }, setFinalContext)
}) })
selectExEnv.value = executionContext.getProvider() selectExEnv.value = executionContext.getProvider()
executionContext.event.register('contextChanged', (context, silent) => { executionContext.event.register('contextChanged', (context, silent) => {
setFinalContext() setFinalContext()
}) })
fillAccountsList(appAPI, opts, el) fillAccountsList(appAPI, opts, el)
setInterval(() => { setInterval(() => {
updateAccountBalances(container, appAPI) updateAccountBalances(container, appAPI)
updatePendingTxs(container, appAPI)
}, 10000) }, 10000)
event.register('clearInstance', () => { event.register('clearInstance', () => {
var instanceContainer = self._view.instanceContainer
var instanceContainerTitle = self._view.instanceContainerTitle
instanceContainer.innerHTML = '' // clear the instances list instanceContainer.innerHTML = '' // clear the instances list
instanceContainer.appendChild(instanceContainerTitle) instanceContainer.appendChild(instanceContainerTitle)
instanceContainer.appendChild(noInstancesText) instanceContainer.appendChild(self._view.noInstancesText)
}) })
return { render () { return container } } return { render () { return container } }
} }
@ -143,7 +186,7 @@ function updateAccountBalances (container, appAPI) {
/* ------------------------------------------------ /* ------------------------------------------------
RECORDER RECORDER
------------------------------------------------ */ ------------------------------------------------ */
function makeRecorder (events, appAPI, appEvents, opts) { function makeRecorder (events, appAPI, appEvents, opts, self) {
var recorder = new Recorder(opts.compiler, { var recorder = new Recorder(opts.compiler, {
events: { events: {
udapp: appEvents.udapp, udapp: appEvents.udapp,
@ -152,23 +195,26 @@ function makeRecorder (events, appAPI, appEvents, opts) {
}, },
api: appAPI api: appAPI
}) })
recorder.event.register('newTxRecorded', (count) => {
self.data.count = count
self._view.recorderCount.innerText = count
})
var css2 = csjs` var css2 = csjs`
.container, .container {}
.runTxs, .runTxs {}
.recorder { .recorder {}
}
` `
var runButton = yo`<i class="fa fa-play runtransaction ${css2.runTxs} ${css.icon}" title="Run Transactions" aria-hidden="true"></i>`
var recordButton = yo` var recordButton = yo`
<i class="fa fa-floppy-o savetransaction ${css2.recorder} ${css.icon}" <i class="fa fa-floppy-o savetransaction ${css2.recorder} ${css.icon}"
onclick=${triggerRecordButton} title="Save Transactions" aria-hidden="true"> onclick=${triggerRecordButton} title="Save Transactions" aria-hidden="true">
</i>` </i>`
var runButton = yo`<i class="fa fa-play runtransaction ${css2.runTxs} ${css.icon}" title="Run Transactions" aria-hidden="true"></i>`
function triggerRecordButton () { function triggerRecordButton () {
var txJSON = JSON.stringify(recorder.getAll(), null, 2) var txJSON = JSON.stringify(recorder.getAll(), null, 2)
var path = appAPI.currentPath() var path = appAPI.currentPath()
modalDialogCustom.prompt(null, 'save ran transactions to file (e.g. `scenario.json`). The file is going to be saved under ' + path, 'scenario.json', input => { modalDialogCustom.prompt(null, 'Transactions will be saved in a file under ' + path, 'scenario.json', input => {
var fileProvider = appAPI.fileProviderOf(path) var fileProvider = appAPI.fileProviderOf(path)
if (fileProvider) { if (fileProvider) {
var newFile = path + input var newFile = path + input
@ -183,6 +229,7 @@ function makeRecorder (events, appAPI, appEvents, opts) {
} }
}) })
} }
runButton.onclick = () => { runButton.onclick = () => {
var currentFile = appAPI.config.get('currentFile') var currentFile = appAPI.config.get('currentFile')
appAPI.fileProviderOf(currentFile).get(currentFile, (error, json) => { appAPI.fileProviderOf(currentFile).get(currentFile, (error, json) => {
@ -201,9 +248,10 @@ function makeRecorder (events, appAPI, appEvents, opts) {
return modalDialogCustom.alert('Invalid Scenario File, please try again') return modalDialogCustom.alert('Invalid Scenario File, please try again')
} }
if (txArray.length) { if (txArray.length) {
var noInstancesText = self._view.noInstancesText
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) } if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) }
recorder.run(txArray, accounts, options, abis, linkReferences, opts.udapp, (abi, address, contractName) => { recorder.run(txArray, accounts, options, abis, linkReferences, (abi, address, contractName) => {
instanceContainer.appendChild(opts.udappUI.renderInstanceFromABI(abi, address, contractName)) self._view.instanceContainer.appendChild(opts.udappUI.renderInstanceFromABI(abi, address, contractName))
}) })
} }
} else { } else {
@ -212,15 +260,18 @@ function makeRecorder (events, appAPI, appEvents, opts) {
} }
}) })
} }
return { recordButton, runButton } return { recordButton, runButton }
} }
/* ------------------------------------------------ /* ------------------------------------------------
CONTRACT (deploy or access deployed) CONTRACT (deploy or access deployed)
------------------------------------------------ */ ------------------------------------------------ */
function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) { function contractDropdown (events, appAPI, appEvents, opts, self) {
var instanceContainer = self._view.instanceContainer
var instanceContainerTitle = self._view.instanceContainerTitle
instanceContainer.appendChild(instanceContainerTitle) instanceContainer.appendChild(instanceContainerTitle)
instanceContainer.appendChild(noInstancesText) instanceContainer.appendChild(self._view.noInstancesText)
var compFails = yo`<i title="Contract compilation failed. Please check the compile tab for more information." class="fa fa-times-circle ${css.errorIcon}" ></i>` var compFails = yo`<i title="Contract compilation failed. Please check the compile tab for more information." class="fa fa-times-circle ${css.errorIcon}" ></i>`
appEvents.compiler.register('compilationFinished', function (success, data, source) { appEvents.compiler.register('compilationFinished', function (success, data, source) {
getContractNames(success, data) getContractNames(success, data)
@ -234,7 +285,6 @@ function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) {
}) })
var atAddressButtonInput = yo`<input class="${css.input} ataddressinput" placeholder="Load contract from Address" title="atAddress" />` var atAddressButtonInput = yo`<input class="${css.input} ataddressinput" placeholder="Load contract from Address" title="atAddress" />`
var selectContractNames = yo`<select class="${css.contractNames}" disabled></select>` var selectContractNames = yo`<select class="${css.contractNames}" disabled></select>`
function getSelectedContract () { function getSelectedContract () {
@ -248,6 +298,7 @@ function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) {
return null return null
} }
appAPI.getSelectedContract = getSelectedContract appAPI.getSelectedContract = getSelectedContract
var createPanel = yo`<div class="${css.button}"></div>` var createPanel = yo`<div class="${css.button}"></div>`
var el = yo` var el = yo`
@ -281,7 +332,7 @@ function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) {
selectContractNames.addEventListener('change', setInputParamsPlaceHolder) selectContractNames.addEventListener('change', setInputParamsPlaceHolder)
// ADD BUTTONS AT ADDRESS AND CREATE // DEPLOY INSTANCE
function createInstance (args) { function createInstance (args) {
var selectedContract = getSelectedContract() var selectedContract = getSelectedContract()
@ -304,7 +355,7 @@ function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) {
return return
} }
} }
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) } self._view.noInstancesText.style.display = 'none'
var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress
instanceContainer.appendChild(opts.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value)) instanceContainer.appendChild(opts.udappUI.renderInstance(selectedContract.contract.object, address, selectContractNames.value))
} else { } else {
@ -322,8 +373,9 @@ function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) {
}) })
} }
// ACCESS DEPLOYED INSTANCE
function loadFromAddress (appAPI) { function loadFromAddress (appAPI) {
if (noInstancesText.parentNode) { noInstancesText.parentNode.removeChild(noInstancesText) } self._view.noInstancesText.style.display = 'none'
var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`)
var address = atAddressButtonInput.value var address = atAddressButtonInput.value
if (!ethJSUtil.isValidAddress(address)) { if (!ethJSUtil.isValidAddress(address)) {
@ -365,12 +417,11 @@ function contractDropdown (events, appAPI, appEvents, opts, instanceContainer) {
return el return el
} }
/* ------------------------------------------------ /* ------------------------------------------------
section SETTINGS: Environment, Account, Gas, Value section SETTINGS: Environment, Account, Gas, Value
------------------------------------------------ */ ------------------------------------------------ */
function settings (container, appAPI, appEvents, opts) { function settings (container, appAPI, appEvents, opts) {
// SETTINGS HTML // VARIABLES
var net = yo`<span class=${css.network}></span>` var net = yo`<span class=${css.network}></span>`
const updateNetwork = () => { const updateNetwork = () => {
executionContext.detectNetwork((err, { id, name } = {}) => { executionContext.detectNetwork((err, { id, name } = {}) => {
@ -382,18 +433,6 @@ function settings (container, appAPI, appEvents, opts) {
} }
}) })
} }
setInterval(updateNetwork, 5000)
function newAccount () {
opts.udapp.newAccount('', (error, address) => {
if (!error) {
container.querySelector('#txorigin').appendChild(yo`<option value=${address}>${address}</option>`)
addTooltip(`account ${address} created`)
} else {
addTooltip('Cannot create an account: ' + error)
}
})
}
var environmentEl = yo` var environmentEl = yo`
<div class="${css.crow}"> <div class="${css.crow}">
<div id="selectExEnv" class="${css.col1_1}"> <div id="selectExEnv" class="${css.col1_1}">
@ -446,6 +485,7 @@ function settings (container, appAPI, appEvents, opts) {
</select> </select>
</div> </div>
` `
// DOM ELEMENT
var el = yo` var el = yo`
<div class="${css.settings}"> <div class="${css.settings}">
${environmentEl} ${environmentEl}
@ -453,15 +493,26 @@ function settings (container, appAPI, appEvents, opts) {
${gasPriceEl} ${gasPriceEl}
${valueEl} ${valueEl}
</div> </div>
` `
// HELPER FUNCTIONS AND EVENTS
// EVENTS
appEvents.udapp.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => { appEvents.udapp.register('transactionExecuted', (error, from, to, data, lookupOnly, txResult) => {
if (error) return if (error) return
if (!lookupOnly) el.querySelector('#value').value = '0' if (!lookupOnly) el.querySelector('#value').value = '0'
updateAccountBalances(container, appAPI) updateAccountBalances(container, appAPI)
}) })
setInterval(updateNetwork, 5000)
function newAccount () {
appAPI.newAccount('', (error, address) => {
if (!error) {
container.querySelector('#txorigin').appendChild(yo`<option value=${address}>${address}</option>`)
addTooltip(`account ${address} created`)
} else {
addTooltip('Cannot create an account: ' + error)
}
})
}
return el return el
} }

@ -9,8 +9,11 @@ var css = csjs`
flex-direction: column; flex-direction: column;
} }
.instanceContainerTitle { .instanceContainerTitle {
font-size: 20px;
font-weight: bold; font-weight: bold;
margin-bottom: 5%;
font-size: 12px;
display: flex;
justify-content: space-between;
} }
.settings { .settings {
${styles.rightPanel.runTab.box_RunTab} ${styles.rightPanel.runTab.box_RunTab}
@ -58,11 +61,13 @@ var css = csjs`
width: 250px; width: 250px;
} }
.instanceContainer { .instanceContainer {
${styles.rightPanel.runTab.box_Instance}
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-top: 2%; margin-bottom: 2%;
border: none; border: none;
text-align: center; text-align: center;
padding: 10px 0px 15px 15px;
} }
.pendingTxsContainer { .pendingTxsContainer {
${styles.rightPanel.runTab.box_Instance} ${styles.rightPanel.runTab.box_Instance}
@ -74,7 +79,15 @@ var css = csjs`
} }
.container { .container {
${styles.rightPanel.runTab.box_RunTab} ${styles.rightPanel.runTab.box_RunTab}
margin-top: 2%; margin-bottom: 2%;
}
.recorderCollapsedView,
.recorderExpandedView {
display: flex;
flex-direction: column;
}
.recorderDescription {
margin: 0 15px 15px 0;
} }
.contractNames { .contractNames {
${styles.rightPanel.runTab.dropdown_RunTab} ${styles.rightPanel.runTab.dropdown_RunTab}
@ -109,6 +122,7 @@ var css = csjs`
.noInstancesText { .noInstancesText {
${styles.rightPanel.runTab.box_Instance} ${styles.rightPanel.runTab.box_Instance}
font-style: italic; font-style: italic;
text-align: left;
} }
.pendingTxsText { .pendingTxsText {
${styles.rightPanel.runTab.borderBox_Instance} ${styles.rightPanel.runTab.borderBox_Instance}
@ -180,14 +194,14 @@ var css = csjs`
.networkItem { .networkItem {
margin-right: 5px; margin-right: 5px;
} }
.clearinstance {} .clearinstance {
margin-right: 15px;
}
.transactionActions { .transactionActions {
display: flex; display: flex;
width: 70px; justify-content: space-evenly;
justify-content: space-between; ${styles.rightPanel.runTab.box_Info_RunTab};
border: 1px solid ${styles.rightPanel.runTab.additionalText_Color}; width: 145px;
padding: 5px;
border-radius: 3px;
} }
` `

@ -0,0 +1,93 @@
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var styleGuide = require('./styles-guide/theme-chooser')
var styles = styleGuide.chooser()
var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager
module.exports = class Card {
constructor (api, events, opts) {
const self = this
self._api = api
self._events = events
self._opts = opts
self._view = {}
self.event = new EventManager()
}
render () {
const self = this
if (self._view.el) return self._view.el
self._view.cardBody = yo`<div class=${css.cardBody}></div>`
self._view.arrow = yo`<i class="${css.arrow} fa fa-angle-up"
onclick=${(ev) => trigger(ev.target)}></i>`
self._view.expandCollapseButton = yo`
<div class=${css.expandCollapseButton}>${self._view.arrow}</div>`
self._view.statusBar = yo`<div class=${css.statusBar}>${self._opts.collapsedView}</div>`
self._view.cardHeader = yo`
<div class=${css.cardHeader}>
<div class=${css.cardTitles}>
<div class=${css.cardTitle}>${self._opts.title}</div>
${self._view.statusBar}
</div>
<div class=${css.expandCollapseButton}>${self._view.expandCollapseButton}</div>
</div>`
function trigger (el) {
var body = self._view.cardBody
var status = self._view.statusBar
el.classList.toggle('fa-angle-down')
var arrow = el.classList.toggle('fa-angle-up') ? 'down' : 'up'
self.event.trigger('expandCollapseCard', [arrow, body, status])
}
// HTML
self._view.el = yo`
<div class=${css.cardContainer}>
${self._view.cardHeader}
${self._view.cardBody}
</div>`
return self._view.el
}
}
const css = csjs`
.cardContainer {
${styles.remix.solidBox};
margin-bottom : 2%;
}
.cardHeader {
display : flex;
justify-content : space-between;
}
.statusBar {}
.cardBody {}
.cardTitles {
display : flex;
flex-direction : row;
align-items : center;
}
.cardTitle {
font-size : 13px;
font-weight : bold;
color : ${styles.appProperties.mainText_Color};
margin-right : 5px;
}
.expandCollapseButton {}
.arrow {
margin-right : 15px;
color : ${styles.appProperties.icon_Color};
font-weight : bold;
cursor : pointer;
font-size : 14px;
}
.arrow:hover {
color : ${styles.appProperties.icon_HoverColor};
}
`

@ -390,7 +390,12 @@ function styleGuide () {
tooltip_CopyToClipboard_Color: appProperties.tooltip_Color, tooltip_CopyToClipboard_Color: appProperties.tooltip_Color,
icon_Color_CopyToClipboard: appProperties.icon_Color, icon_Color_CopyToClipboard: appProperties.icon_Color,
icon_HoverColor_CopyToClipboard: appProperties.icon_HoverColor icon_HoverColor_CopyToClipboard: appProperties.icon_HoverColor,
solidBox: appProperties.uiElements.solidBorderBox({
BackgroundColor: appProperties.solidBox_BackgroundColor,
Color: appProperties.solidBox_TextColor
})
}, },
/* ------------------------------------------------------ /* ------------------------------------------------------
@ -569,6 +574,12 @@ function styleGuide () {
Color: appProperties.solidBox_TextColor Color: appProperties.solidBox_TextColor
}), }),
box_Info_RunTab: appProperties.uiElements.dottedBorderBox({
BackgroundColor: appProperties.solidBorderBox_BackgroundColor,
BorderColor: appProperties.solidBorderBox_BorderColor,
Color: appProperties.solidBorderBox_TextColor
}),
dropdown_RunTab: appProperties.uiElements.dropdown({ dropdown_RunTab: appProperties.uiElements.dropdown({
BackgroundColor: appProperties.dropdown_BackgroundColor, BackgroundColor: appProperties.dropdown_BackgroundColor,
BorderColor: appProperties.dropdown_BorderColor, BorderColor: appProperties.dropdown_BorderColor,

@ -10,6 +10,7 @@ var css = csjs`
display : flex; display : flex;
flex-direction : column; flex-direction : column;
margin-right : 10px; margin-right : 10px;
width : auto;
} }
.selectbox { .selectbox {
display : flex; display : flex;

@ -131,6 +131,7 @@ class Recorder {
append (timestamp, record) { append (timestamp, record) {
var self = this var self = this
self.data.journal.push({ timestamp, record }) self.data.journal.push({ timestamp, record })
self.event.trigger('newTxRecorded', [self.data.journal.length])
} }
/** /**

@ -10,7 +10,7 @@ var css = csjs`
.title { .title {
${styles.rightPanel.runTab.titlebox_RunTab} ${styles.rightPanel.runTab.titlebox_RunTab}
display: flex; display: flex;
justify-content: end; justify-content: space-between;
align-items: center; align-items: center;
font-size: 11px; font-size: 11px;
height: 30px; height: 30px;
@ -35,11 +35,9 @@ var css = csjs`
color: ${styles.rightPanel.runTab.icon_AltColor_Instance_CopyToClipboard}; color: ${styles.rightPanel.runTab.icon_AltColor_Instance_CopyToClipboard};
} }
.instance { .instance {
${styles.rightPanel.runTab.box_Instance}; min-width: 310px;
margin-bottom: 10px; display: flex;
padding: 10px 15px 15px 15px; flex-direction: column;
position: relative;
overflow: visible;
} }
.instance .title:before { .instance .title:before {
content: "\\25BE"; content: "\\25BE";
@ -81,6 +79,7 @@ var css = csjs`
.closeIcon { .closeIcon {
font-size: 12px; font-size: 12px;
cursor: pointer; cursor: pointer;
margin-left: 5px;
} }
.udappClose { .udappClose {
display: flex; display: flex;

@ -34,9 +34,8 @@ UniversalDAppUI.prototype.renderInstance = function (contract, address, contract
UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address, contractName) { UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address, contractName) {
var self = this var self = this
address = (address.slice(0, 2) === '0x' ? '' : '0x') + address.toString('hex') address = (address.slice(0, 2) === '0x' ? '' : '0x') + address.toString('hex')
var instance = yo`<div class="instance ${css.instance}" id="instance${address}"></div>` var instance = yo`<div class="instance ${css.instance} ${css.hidesub}" id="instance${address}"></div>`
var context = self.udapp.context() var context = self.udapp.context()
var shortAddress = helper.shortenAddress(address) var shortAddress = helper.shortenAddress(address)
@ -48,7 +47,7 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address
if (self.udapp.removable_instances) { if (self.udapp.removable_instances) {
var close = yo`<div class="${css.udappClose}" onclick=${remove}><i class="${css.closeIcon} fa fa-close" aria-hidden="true"></i></div>` var close = yo`<div class="${css.udappClose}" onclick=${remove}><i class="${css.closeIcon} fa fa-close" aria-hidden="true"></i></div>`
instance.appendChild(close) title.appendChild(close)
} }
function remove () { function remove () {

Loading…
Cancel
Save