commit
58cfe7c7cb
@ -0,0 +1,45 @@ |
|||||||
|
# embark-remix |
||||||
|
An Embark plugin that allows Remix to connect to a local DApp via [`remixd`](https://github.com/ethereum/remixd). This plugin serves a local copy of Remix IDE from the machine running the plugin or alternatively allows connection from the public [Remix IDE](https://remix.ethereum.org). The URL of the Remix IDE can be specified in the Embark plugin options, specified below. |
||||||
|
|
||||||
|
## Options |
||||||
|
To configure options for the `embark-remix` plugin, modify the `plugins` property of `embark.json` in the DApp. |
||||||
|
|
||||||
|
### How to use default options |
||||||
|
To pass no options to the plugin and use the defaults, simply use an empty object: |
||||||
|
``` |
||||||
|
"plugins": { |
||||||
|
"embark-remix": {} |
||||||
|
} |
||||||
|
``` |
||||||
|
This will provide the default options to the plugin (shown below). |
||||||
|
|
||||||
|
### Available options |
||||||
|
The available options for this plugin are below. Default options are shown below. This is equivalent to passing an empty object `{}`. |
||||||
|
``` |
||||||
|
"plugins": { |
||||||
|
"embark-remix": { |
||||||
|
"readOnly": false, |
||||||
|
"remixIde": { |
||||||
|
"protocol": "http", |
||||||
|
"host": "localhost", |
||||||
|
"port": 8088 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
|
||||||
|
`readOnly` does not let Remix update the contents on the local filesystem. |
||||||
|
- Default: `false` |
||||||
|
|
||||||
|
`remixIde` specifies the URL that the Remix IDE will be served from. If this is a `localhost` URL, the plugin creates a server that is responsible for listening on this URL. |
||||||
|
- Default: `(see above)` |
||||||
|
|
||||||
|
If it is preferred to connect to the public Remix IDE at https://remix.ethereum.org, set the `remixIde` config to: |
||||||
|
``` |
||||||
|
"remixIde": { |
||||||
|
"protocol": "https", |
||||||
|
"host": "remix.ethereum.org", |
||||||
|
"port": false |
||||||
|
} |
||||||
|
``` |
@ -1,22 +1,66 @@ |
|||||||
/* global path */ |
const httpServer = require('http-server') |
||||||
var httpServer = require('http-server') |
const remixd = require('remixd') |
||||||
var remixd = require('remixd') |
const path = require('path') |
||||||
|
const merge = require('merge') |
||||||
|
const colors = require('colors') |
||||||
|
|
||||||
|
const DEFAULT_OPTIONS = { |
||||||
|
protocol: 'http', |
||||||
|
host: 'localhost', |
||||||
|
port: '8088' |
||||||
|
} |
||||||
|
|
||||||
module.exports = (embark) => { |
module.exports = (embark) => { |
||||||
var server = httpServer.createServer({ |
// plugin options
|
||||||
root: path.join(__dirname, '/node_modules/remix-ide') |
const readOnly = embark.pluginConfig.readOnly || false |
||||||
}) |
const {protocol, host, port} = merge.recursive(DEFAULT_OPTIONS, embark.pluginConfig.remixIde) |
||||||
|
|
||||||
|
// globals
|
||||||
|
const remixIdeUrl = `${protocol}://${host}` + `${port ? `:${port}` : ''}` |
||||||
|
const sharedFolder = path.join(__dirname, '../../') |
||||||
|
const sharedFolderService = remixd.services.sharedFolder |
||||||
|
let server |
||||||
|
|
||||||
|
// setup HTTP server
|
||||||
|
if (['localhost', '127.0.0.1', '0.0.0.0'].includes(host)) { |
||||||
|
server = httpServer.createServer({ |
||||||
|
root: path.join(__dirname, '../../node_modules/remix-ide') |
||||||
|
}) |
||||||
|
server.listen(port, '127.0.0.1', function () { |
||||||
|
embark.logger.info('Remix IDE (via embark-remix plugin) available at ' + colors.underline(remixIdeUrl)) |
||||||
|
}) |
||||||
|
} else { |
||||||
|
embark.logger.info('embark-remix is set to connect to a Remix IDE at ' + colors.underline(remixIdeUrl)) |
||||||
|
} |
||||||
|
|
||||||
|
// setup Embark service check
|
||||||
embark.registerServiceCheck('Remix IDE', (cb) => { |
embark.registerServiceCheck('Remix IDE', (cb) => { |
||||||
return cb({name: 'Remix IDE (localhost:8080)', status: 'on'}) |
return cb({ name: `Remix IDE ${host}:${port}`, status: 'on' }) |
||||||
}) |
}) |
||||||
|
|
||||||
server.listen(8080, '127.0.0.1', function () {}) |
// setup remixd shared folder service
|
||||||
var router = new remixd.Router(65520, remixd.services.sharedFolder, (webSocket) => { |
const sharedFolderRouter = new remixd.Router(65520, sharedFolderService, { remixIdeUrl }, (webSocket) => { |
||||||
remixd.services.sharedFolder.setWebSocket(webSocket) |
sharedFolderService.setWebSocket(webSocket) |
||||||
var sharedFolder = path.join(__dirname, '/../../') |
sharedFolderService.setupNotifications(sharedFolder) |
||||||
remixd.services.sharedFolder.setupNotifications(sharedFolder) |
sharedFolderService.sharedFolder(sharedFolder, readOnly) |
||||||
remixd.services.sharedFolder.sharedFolder(sharedFolder) |
|
||||||
}) |
}) |
||||||
router.start() |
const killRemixD = sharedFolderRouter.start() |
||||||
|
const kill = () => { |
||||||
|
if (server) server.close() |
||||||
|
embark.logger.info(colors.red('embark-remix stopped')) |
||||||
|
process.exit() |
||||||
|
} |
||||||
|
|
||||||
|
if (process.platform === 'win32') { |
||||||
|
require('readline').createInterface({ |
||||||
|
input: process.stdin, |
||||||
|
output: process.stdout |
||||||
|
}).on('SIGINT', function () { |
||||||
|
process.emit('SIGINT') |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
process.on('SIGINT', kill) // catch ctrl-c
|
||||||
|
process.on('SIGTERM', kill) // catch kill
|
||||||
|
process.on('exit', killRemixD) |
||||||
} |
} |
||||||
|
@ -0,0 +1,23 @@ |
|||||||
|
import { AbstractPanel } from './panel' |
||||||
|
const csjs = require('csjs-inject') |
||||||
|
const yo = require('yo-yo') |
||||||
|
|
||||||
|
const css = csjs` |
||||||
|
.pluginsContainer { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export class HiddenPanel extends AbstractPanel { |
||||||
|
|
||||||
|
constructor (appStore) { |
||||||
|
super('hiddenPanel', appStore) |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
return yo` |
||||||
|
<div class=${css.pluginsContainer}> |
||||||
|
${this.view} |
||||||
|
</div>` |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
import { AbstractPanel } from './panel' |
||||||
|
const yo = require('yo-yo') |
||||||
|
const csjs = require('csjs-inject') |
||||||
|
|
||||||
|
const css = csjs` |
||||||
|
.pluginsContainer { |
||||||
|
height: 100%; |
||||||
|
display: flex; |
||||||
|
overflow-y: hidden; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export class MainPanel extends AbstractPanel { |
||||||
|
constructor (appStore, options) { |
||||||
|
super('mainPanel', appStore, options) |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
return yo` |
||||||
|
<div class=${css.pluginsContainer}> |
||||||
|
${this.view} |
||||||
|
</div>` |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,111 @@ |
|||||||
|
import { EventEmitter } from 'events' |
||||||
|
const registry = require('../../global/registry') |
||||||
|
const csjs = require('csjs-inject') |
||||||
|
const yo = require('yo-yo') |
||||||
|
|
||||||
|
const css = csjs` |
||||||
|
.plugins { |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
.plugItIn { |
||||||
|
display : none; |
||||||
|
height : 100%; |
||||||
|
} |
||||||
|
.plugItIn > div { |
||||||
|
overflow-y : auto; |
||||||
|
height : 100%; |
||||||
|
width : 100%; |
||||||
|
} |
||||||
|
.plugItIn.active { |
||||||
|
display : block; |
||||||
|
} |
||||||
|
.pluginsContainer { |
||||||
|
height: 100%; |
||||||
|
overflow-y: hidden; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
// Events are : 'toggle' | 'showing'
|
||||||
|
|
||||||
|
/** Abstract class used for hosting the view of a plugin */ |
||||||
|
export class AbstractPanel { |
||||||
|
|
||||||
|
constructor (panelName, appStore, opts) { |
||||||
|
this.events = new EventEmitter() |
||||||
|
this.contents = {} |
||||||
|
this.active = undefined |
||||||
|
|
||||||
|
// View where the plugin HTMLElement leaves
|
||||||
|
this.view = yo`<div id="plugins" class="${css.plugins}"></div>` |
||||||
|
|
||||||
|
appStore.event.on('activate', (name) => { |
||||||
|
const api = appStore.getOne(name) |
||||||
|
const profile = api.profile |
||||||
|
if (profile.location !== panelName) return |
||||||
|
if (!profile.location && !opts.default) return |
||||||
|
if (profile.icon && api.render && typeof api.render === 'function') { |
||||||
|
this.add(name, api.render()) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
appStore.event.on('deactivate', (name) => { |
||||||
|
if (this.contents[name]) this.remove(name) |
||||||
|
}) |
||||||
|
|
||||||
|
const verticalIcon = registry.get('verticalicon').api |
||||||
|
// Toggle content
|
||||||
|
verticalIcon.events.on('toggleContent', (name) => { |
||||||
|
if (!this.contents[name]) return |
||||||
|
if (this.active === name) { |
||||||
|
this.events.emit('toggle', name) |
||||||
|
} |
||||||
|
this.showContent(name) |
||||||
|
this.events.emit('showing', name) |
||||||
|
}) |
||||||
|
// Force opening
|
||||||
|
verticalIcon.events.on('showContent', (name) => { |
||||||
|
if (!this.contents[name]) return |
||||||
|
this.showContent(name) |
||||||
|
this.events.emit('showing', name) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add the plugin to the panel |
||||||
|
* @param {String} name the name of the plugin |
||||||
|
* @param {HTMLElement} content the HTMLContent of the plugin |
||||||
|
*/ |
||||||
|
add (name, content) { |
||||||
|
if (this.contents[name]) throw new Error(`Plugin ${name} already rendered`) |
||||||
|
content.style.height = '100%' |
||||||
|
content.style.width = '100%' |
||||||
|
content.style.border = '0' |
||||||
|
this.contents[name] = yo`<div class="${css.plugItIn}" >${content}</div>` |
||||||
|
this.view.appendChild(this.contents[name]) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Remove a plugin from the panel |
||||||
|
* @param {String} name The name of the plugin to remove |
||||||
|
*/ |
||||||
|
remove (name) { |
||||||
|
const el = this.contents[name] |
||||||
|
delete this.contents[name] |
||||||
|
if (el) el.parentElement.removeChild(el) |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Display the content of this specific plugin |
||||||
|
* @param {String} name The name of the plugin to display the content |
||||||
|
*/ |
||||||
|
showContent (name) { |
||||||
|
if (!this.contents[name]) throw new Error(`Plugin ${name} is not yet activated`) |
||||||
|
// hiding the current view and display the `moduleName`
|
||||||
|
if (this.active) { |
||||||
|
this.contents[this.active].style.display = 'none' |
||||||
|
} |
||||||
|
this.contents[name].style.display = 'block' |
||||||
|
this.active = name |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,102 @@ |
|||||||
|
const yo = require('yo-yo') |
||||||
|
const csjs = require('csjs-inject') |
||||||
|
const modalDialog = require('../ui/modaldialog') |
||||||
|
|
||||||
|
const css = csjs`
|
||||||
|
.permissions { |
||||||
|
position: sticky; |
||||||
|
bottom: 0; |
||||||
|
display: flex; |
||||||
|
justify-content: flex-end; |
||||||
|
align-items: center; |
||||||
|
padding: 5px 20px; |
||||||
|
} |
||||||
|
.permissions button { |
||||||
|
padding: 2px 5px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.permissionForm h4 { |
||||||
|
font-size: 1.3rem; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.permissionForm h6 { |
||||||
|
font-size: 1.1rem; |
||||||
|
} |
||||||
|
.permissionForm hr { |
||||||
|
width: 80%; |
||||||
|
} |
||||||
|
.checkbox { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.checkbox label { |
||||||
|
margin: 0; |
||||||
|
font-size: 1rem; |
||||||
|
}` |
||||||
|
|
||||||
|
export class PluginManagerSettings { |
||||||
|
|
||||||
|
openDialog () { |
||||||
|
const fromLocal = window.localStorage.getItem('plugins/permissions') |
||||||
|
this.permissions = JSON.parse(fromLocal || '{}') |
||||||
|
modalDialog('Plugin Manager Settings', this.settings(), |
||||||
|
{ fn: () => this.onValidation() }, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
onValidation () { |
||||||
|
const permissions = JSON.stringify(this.permissions) |
||||||
|
window.localStorage.setItem('plugins/permissions', permissions) |
||||||
|
} |
||||||
|
|
||||||
|
settings () { |
||||||
|
const permissionByModule = (key, permission) => { |
||||||
|
const permissionByPlugin = (name, plugin) => { |
||||||
|
function updatePermission () { |
||||||
|
plugin.allow = !plugin.allow |
||||||
|
} |
||||||
|
const checkbox = plugin.allow |
||||||
|
? yo`<input onchange="${updatePermission}" type="checkbox" checked id="permission-${name}" aria-describedby="module ${key} ask permission for ${name}" />` |
||||||
|
: yo`<input onchange="${updatePermission}" type="checkbox" id="permission-${name}" aria-describedby="module ${key} ask permission for ${name}" />` |
||||||
|
|
||||||
|
return yo` |
||||||
|
<div class="form-group ${css.checkbox}"> |
||||||
|
${checkbox} |
||||||
|
<label for="permission-${name}">Allow plugin ${name} to write on ${key}</label> |
||||||
|
</div>` |
||||||
|
} |
||||||
|
|
||||||
|
const byModule = Object |
||||||
|
.keys(permission) |
||||||
|
.map(name => permissionByPlugin(name, permission[name])) |
||||||
|
|
||||||
|
return yo` |
||||||
|
<div> |
||||||
|
<h6>${key} :</h6> |
||||||
|
${byModule} |
||||||
|
</div>` |
||||||
|
} |
||||||
|
|
||||||
|
const permissions = Object |
||||||
|
.keys(this.permissions) |
||||||
|
.map(key => permissionByModule(key, this.permissions[key])) |
||||||
|
|
||||||
|
const title = permissions.length === 0 |
||||||
|
? yo`<h4>No Permission requested yet.</h4>` |
||||||
|
: yo`<h4>Current Permission settings</h4>` |
||||||
|
|
||||||
|
return yo`<form class="${css.permissionForm}">
|
||||||
|
${title} |
||||||
|
<hr/> |
||||||
|
${permissions} |
||||||
|
</form>` |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
return yo` |
||||||
|
<footer class="navbar navbar-light bg-light ${css.permissions}"> |
||||||
|
<button onclick="${() => this.openDialog()}" class="btn btn-info">Settings</button> |
||||||
|
</footer>` |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,43 +0,0 @@ |
|||||||
import EventEmmitter from 'events' |
|
||||||
|
|
||||||
class SwapPanelApi { |
|
||||||
constructor (swapPanelComponent, verticalIconsComponent) { |
|
||||||
this.event = new EventEmmitter() |
|
||||||
this.component = swapPanelComponent |
|
||||||
this.currentContent |
|
||||||
verticalIconsComponent.events.on('toggleContent', (moduleName) => { |
|
||||||
if (!swapPanelComponent.contents[moduleName]) return |
|
||||||
if (this.currentContent === moduleName) { |
|
||||||
this.event.emit('toggle', moduleName) |
|
||||||
return |
|
||||||
} |
|
||||||
this.showContent(moduleName) |
|
||||||
this.event.emit('showing', moduleName) |
|
||||||
}) |
|
||||||
|
|
||||||
verticalIconsComponent.events.on('showContent', (moduleName) => { |
|
||||||
if (!swapPanelComponent.contents[moduleName]) return |
|
||||||
this.showContent(moduleName) |
|
||||||
this.event.emit('showing', moduleName) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
showContent (moduleName) { |
|
||||||
this.component.showContent(moduleName) |
|
||||||
this.currentContent = moduleName |
|
||||||
} |
|
||||||
|
|
||||||
/* |
|
||||||
content: DOM element |
|
||||||
by appManager |
|
||||||
*/ |
|
||||||
add (profile, content) { |
|
||||||
return this.component.add(profile.name, content) |
|
||||||
} |
|
||||||
|
|
||||||
remove (profile) { |
|
||||||
return this.component.remove(profile.name) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = SwapPanelApi |
|
@ -1,102 +0,0 @@ |
|||||||
var yo = require('yo-yo') |
|
||||||
var csjs = require('csjs-inject') |
|
||||||
|
|
||||||
class SwapPanelComponent { |
|
||||||
constructor (name, appStore, appManager, opt) { |
|
||||||
this.name = name |
|
||||||
this.opt = opt |
|
||||||
this.store = appStore |
|
||||||
// list of contents
|
|
||||||
this.contents = {} |
|
||||||
// name of the current displayed content
|
|
||||||
this.currentNode |
|
||||||
|
|
||||||
this.store.event.on('activate', (name) => { |
|
||||||
const api = this.store.getOne(name) |
|
||||||
const profile = api.profile |
|
||||||
if (((profile.location === this.name) || (!profile.location && opt.default)) && |
|
||||||
profile.icon && api.render && typeof api.render === 'function') { |
|
||||||
this.add(name, api.render()) |
|
||||||
} |
|
||||||
}) |
|
||||||
|
|
||||||
this.store.event.on('deactivate', (name) => { |
|
||||||
if (this.contents[name]) this.remove(name) |
|
||||||
}) |
|
||||||
this.store.event.on('add', (api) => { }) |
|
||||||
this.store.event.on('remove', (api) => { }) |
|
||||||
} |
|
||||||
|
|
||||||
showContent (moduleName) { |
|
||||||
// hiding the current view and display the `moduleName`
|
|
||||||
if (this.contents[moduleName]) { |
|
||||||
if (this.currentNode) { |
|
||||||
this.contents[this.currentNode].style.display = 'none' |
|
||||||
} |
|
||||||
this.contents[moduleName].style.display = 'block' |
|
||||||
this.currentNode = moduleName |
|
||||||
var api = this.store.getOne(moduleName) |
|
||||||
this.header.querySelector('h6').innerHTML = api.profile ? api.profile.displayName : ' - ' |
|
||||||
return |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
add (moduleName, content) { |
|
||||||
content.style.height = '100%' |
|
||||||
content.style.width = '100%' |
|
||||||
content.style.border = '0' |
|
||||||
this.contents[moduleName] = yo`<div class=${css.plugItIn} >${content}</div>` |
|
||||||
this.view.appendChild(this.contents[moduleName]) |
|
||||||
} |
|
||||||
|
|
||||||
remove (moduleName) { |
|
||||||
let el = this.contents[moduleName] |
|
||||||
if (el) el.parentElement.removeChild(el) |
|
||||||
} |
|
||||||
|
|
||||||
render () { |
|
||||||
this.view = yo` |
|
||||||
<div id='plugins' class=${css.plugins}> |
|
||||||
</div> |
|
||||||
` |
|
||||||
this.header = yo`<header class="${css.swapitHeader}"><h6 class="${css.swapitTitle}"></h6></header>` |
|
||||||
if (!this.opt.displayHeader) this.header.style.display = 'none' |
|
||||||
|
|
||||||
return yo`<div class=${css.pluginsContainer}>
|
|
||||||
${this.header} |
|
||||||
${this.view} |
|
||||||
</div>` |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = SwapPanelComponent |
|
||||||
|
|
||||||
const css = csjs` |
|
||||||
.plugins { |
|
||||||
height : 95%; |
|
||||||
} |
|
||||||
.plugItIn { |
|
||||||
display : none; |
|
||||||
height : 100%; |
|
||||||
} |
|
||||||
.plugItIn > div { |
|
||||||
overflow-y : auto; |
|
||||||
height : 100%; |
|
||||||
width : 100%; |
|
||||||
} |
|
||||||
.plugItIn.active { |
|
||||||
display : block; |
|
||||||
} |
|
||||||
.pluginsContainer { |
|
||||||
height: 100%; |
|
||||||
overflow-y: hidden; |
|
||||||
} |
|
||||||
.swapitTitle { |
|
||||||
text-transform: uppercase; |
|
||||||
} |
|
||||||
.swapitHeader { |
|
||||||
height: 35px; |
|
||||||
padding-top: 10px; |
|
||||||
padding-left: 27px; |
|
||||||
} |
|
||||||
` |
|
@ -0,0 +1,77 @@ |
|||||||
|
import { AbstractPanel } from './panel' |
||||||
|
const csjs = require('csjs-inject') |
||||||
|
const yo = require('yo-yo') |
||||||
|
|
||||||
|
const css = csjs` |
||||||
|
.panel { |
||||||
|
height: 100%; |
||||||
|
overflow-y: hidden;
|
||||||
|
} |
||||||
|
.swapitTitle { |
||||||
|
text-transform: uppercase; |
||||||
|
} |
||||||
|
.swapitHeader { |
||||||
|
height: 35px; |
||||||
|
padding: 0 20px; |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
.swapitHeader h6 { |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
.icons i { |
||||||
|
height: 80%; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.pluginsContainer { |
||||||
|
height: calc(100% - 35px); |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
const options = { |
||||||
|
default: true |
||||||
|
} |
||||||
|
|
||||||
|
export class SwapPanel extends AbstractPanel { |
||||||
|
|
||||||
|
constructor (appStore) { |
||||||
|
super('swapPanel', appStore, options) |
||||||
|
this.header = this.renderHeader() |
||||||
|
this.store = appStore |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Display content and update the header |
||||||
|
* @param {String} name The name of the plugin to display |
||||||
|
*/ |
||||||
|
showContent (name) { |
||||||
|
super.showContent(name) |
||||||
|
yo.update(this.header, this.renderHeader()) |
||||||
|
} |
||||||
|
|
||||||
|
/** The header of the swap panel */ |
||||||
|
renderHeader () { |
||||||
|
let name = ' - ' |
||||||
|
if (this.active) { |
||||||
|
const { profile } = this.store.getOne(this.active) |
||||||
|
name = profile.displayName ? profile.displayName : profile.name |
||||||
|
} |
||||||
|
return yo` |
||||||
|
<header class="${css.swapitHeader}"> |
||||||
|
<h6 class="${css.swapitTitle}">${name}</h6> |
||||||
|
</div> |
||||||
|
</header>` |
||||||
|
} |
||||||
|
|
||||||
|
render () { |
||||||
|
return yo` |
||||||
|
<section class="${css.panel}"> |
||||||
|
${this.header} |
||||||
|
<div class="${css.pluginsContainer}"> |
||||||
|
${this.view} |
||||||
|
</div> |
||||||
|
</section>` |
||||||
|
} |
||||||
|
} |
@ -1,20 +0,0 @@ |
|||||||
// API
|
|
||||||
class VerticalIconsApi { |
|
||||||
|
|
||||||
constructor (verticalIconsComponent) { |
|
||||||
this.component = verticalIconsComponent |
|
||||||
} |
|
||||||
|
|
||||||
addIcon (mod) { |
|
||||||
this.component.addIcon(mod) |
|
||||||
} |
|
||||||
|
|
||||||
removeIcon (mod) { |
|
||||||
this.component.removeIcon(mod) |
|
||||||
} |
|
||||||
|
|
||||||
select (moduleName) { |
|
||||||
this.component.select(moduleName) |
|
||||||
} |
|
||||||
} |
|
||||||
module.exports = VerticalIconsApi |
|
Loading…
Reference in new issue