basic react component to show in plugin manager

pull/1344/head
joseph izang 4 years ago
parent e95ec46b20
commit 5836abdd6e
  1. 315
      apps/remix-ide/src/app/components/plugin-manager-component.js
  2. 2
      apps/remix-ide/src/app/components/plugin-manager-settings.js
  3. 2
      libs/remix-ui/plugin-manager/src/index.ts
  4. 36
      libs/remix-ui/plugin-manager/src/lib/components/pluginManagerProvider.tsx
  5. 61
      libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.css
  6. 2
      libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx

@ -1,13 +1,18 @@
import { IframePlugin, ViewPlugin, WebsocketPlugin } from '@remixproject/engine-web' /* eslint-disable no-unused-vars */
import {
IframePlugin,
ViewPlugin,
WebsocketPlugin
} from '@remixproject/engine-web'
import { PluginManagerSettings } from './plugin-manager-settings' import { PluginManagerSettings } from './plugin-manager-settings'
import React from 'react' import React from 'react' // eslint-disable-line
import { ReactDOM } from 'react-dom' import ReactDOM from 'react-dom'
import { RemixUIPluginManager } from '@remix-ui/plugin-manager' import {RemixUiPluginManager} from '@remix-ui/plugin-manager' // eslint-disable-line
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
const yo = require('yo-yo') const yo = require('yo-yo')
const csjs = require('csjs-inject') const csjs = require('csjs-inject')
const EventEmitter = require('events') const EventEmitter = require('events')
const LocalPlugin = require('./local-plugin') const LocalPlugin = require('./local-plugin') // eslint-disable-line
const addToolTip = require('../ui/tooltip') const addToolTip = require('../ui/tooltip')
const _paq = window._paq = window._paq || [] const _paq = window._paq = window._paq || []
@ -87,92 +92,96 @@ const profile = {
class PluginManagerComponent extends ViewPlugin { class PluginManagerComponent extends ViewPlugin {
constructor (appManager, engine) { constructor (appManager, engine) {
super(profile) super(profile)
this.event = new EventEmitter() // this.event = new EventEmitter()
this.appManager = appManager // this.appManager = appManager
this.views = { // this.engine = engine
root: null,
items: {}
}
this.localPlugin = new LocalPlugin()
this.filter = ''
this.appManager.event.on('activate', () => { this.reRender() })
this.appManager.event.on('deactivate', () => { this.reRender() })
this.engine = engine
this.engine.event.on('onRegistration', () => { this.reRender() })
this.htmlElement = document.createElement('div') this.htmlElement = document.createElement('div')
this.htmlElement.setAttribute('id', 'pluginManager') this.htmlElement.setAttribute('id', 'pluginManager')
// this.views = {
// root: null,
// items: {}
// }
// this.localPlugin = new LocalPlugin()
// this.filter = ''
// this.appManager.event.on('activate', () => { this.reRender() })
// this.appManager.event.on('deactivate', () => { this.reRender() })
// this.engine.event.on('onRegistration', () => { this.reRender() })
} }
onActivation () { onActivation () {
this.renderComponent() this.renderComponent()
} }
isActive (name) { renderComponent () {
return this.appManager.actives.includes(name) ReactDOM.render(<RemixUiPluginManager />, document.getElementById('pluginManager'))
} }
activateP (name) { // isActive (name) {
this.appManager.activatePlugin(name) // return this.appManager.actives.includes(name)
_paq.push(['trackEvent', 'manager', 'activate', name]) // }
}
deactivateP (name) { // activateP (name) {
this.call('manager', 'deactivatePlugin', name) // this.appManager.activatePlugin(name)
_paq.push(['trackEvent', 'manager', 'deactivate', name]) // _paq.push(['trackEvent', 'manager', 'activate', name])
} // }
renderItem (profile) { // deactivateP (name) {
const displayName = (profile.displayName) ? profile.displayName : profile.name // this.call('manager', 'deactivatePlugin', name)
const doclink = profile.documentation ? yo`<a href="${profile.documentation}" class="px-1" title="link to documentation" target="_blank"><i aria-hidden="true" class="fas fa-book"></i></a>` // _paq.push(['trackEvent', 'manager', 'deactivate', name])
: yo`` // }
// Check version of the plugin // renderItem (profile) {
let versionWarning // const displayName = (profile.displayName) ? profile.displayName : profile.name
// Alpha // const doclink = profile.documentation ? yo`<a href="${profile.documentation}" class="px-1" title="link to documentation" target="_blank"><i aria-hidden="true" class="fas fa-book"></i></a>`
if (profile.version && profile.version.match(/\b(\w*alpha\w*)\b/g)) { // : yo``
versionWarning = yo`<small title="Version Alpha" class="${css.versionWarning} plugin-version">alpha</small>`
}
// Beta
if (profile.version && profile.version.match(/\b(\w*beta\w*)\b/g)) {
versionWarning = yo`<small title="Version Beta" class="${css.versionWarning} plugin-version">beta</small>`
}
const activationButton = this.isActive(profile.name) // // Check version of the plugin
? yo` // let versionWarning
<button // // Alpha
onclick="${() => this.deactivateP(profile.name)}" // if (profile.version && profile.version.match(/\b(\w*alpha\w*)\b/g)) {
class="btn btn-secondary btn-sm" data-id="pluginManagerComponentDeactivateButton${profile.name}" // versionWarning = yo`<small title="Version Alpha" class="${css.versionWarning} plugin-version">alpha</small>`
> // }
Deactivate // // Beta
</button> // if (profile.version && profile.version.match(/\b(\w*beta\w*)\b/g)) {
` // versionWarning = yo`<small title="Version Beta" class="${css.versionWarning} plugin-version">beta</small>`
: yo` // }
<button
onclick="${() => this.activateP(profile.name)}"
class="btn btn-success btn-sm" data-id="pluginManagerComponentActivateButton${profile.name}"
>
Activate
</button>`
return yo` // const activationButton = this.isActive(profile.name)
<article id="remixPluginManagerListItem_${profile.name}" class="list-group-item py-1 mb-1 plugins-list-group-item" title="${displayName}" > // ? yo`
<div class="${css.row} justify-content-between align-items-center mb-2"> // <button
<h6 class="${css.displayName} plugin-name"> // onclick="${() => this.deactivateP(profile.name)}"
<div> // class="btn btn-secondary btn-sm" data-id="pluginManagerComponentDeactivateButton${profile.name}"
${displayName} // >
${doclink} // Deactivate
${versionWarning} // </button>
</div> // `
${activationButton} // : yo`
</h6> // <button
</div> // onclick="${() => this.activateP(profile.name)}"
<div class="${css.description} d-flex text-body plugin-text mb-2"> // class="btn btn-success btn-sm" data-id="pluginManagerComponentActivateButton${profile.name}"
<img src="${profile.icon}" class="mr-1 mt-1 ${css.pluginIcon}" /> // >
<span class="${css.descriptiontext}">${profile.description}</span> // Activate
</div> // </button>`
</article>
` // return yo`
} // <article id="remixPluginManagerListItem_${profile.name}" class="list-group-item py-1 mb-1 plugins-list-group-item" title="${displayName}" >
// <div class="${css.row} justify-content-between align-items-center mb-2">
// <h6 class="${css.displayName} plugin-name">
// <div>
// ${displayName}
// ${doclink}
// ${versionWarning}
// </div>
// ${activationButton}
// </h6>
// </div>
// <div class="${css.description} d-flex text-body plugin-text mb-2">
// <img src="${profile.icon}" class="mr-1 mt-1 ${css.pluginIcon}" />
// <span class="${css.descriptiontext}">${profile.description}</span>
// </div>
// </article>
// `
// }
/*************** /***************
* SUB-COMPONENT * SUB-COMPONENT
@ -197,95 +206,91 @@ class PluginManagerComponent extends ViewPlugin {
} }
} }
// return this.htmlElement() // // return this.htmlElement()
// render () { // // render () {
// return this.htmlElement() // // return this.htmlElement()
// } // // }
render () { render () {
// Filtering helpers // // Filtering helpers
const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(this.filter) // const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(this.filter)
const isNotRequired = (profile) => !this.appManager.isRequired(profile.name) // const isNotRequired = (profile) => !this.appManager.isRequired(profile.name)
const isNotDependent = (profile) => !this.appManager.isDependent(profile.name) // const isNotDependent = (profile) => !this.appManager.isDependent(profile.name)
const isNotHome = (profile) => profile.name !== 'home' // const isNotHome = (profile) => profile.name !== 'home'
const sortByName = (profileA, profileB) => { // const sortByName = (profileA, profileB) => {
const nameA = ((profileA.displayName) ? profileA.displayName : profileA.name).toUpperCase() // const nameA = ((profileA.displayName) ? profileA.displayName : profileA.name).toUpperCase()
const nameB = ((profileB.displayName) ? profileB.displayName : profileB.name).toUpperCase() // const nameB = ((profileB.displayName) ? profileB.displayName : profileB.name).toUpperCase()
return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0 // return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0
} // }
// Filter all active and inactive modules that are not required
const { actives, inactives } = this.appManager.getAll()
.filter(isFiltered)
.filter(isNotRequired)
.filter(isNotDependent)
.filter(isNotHome)
.sort(sortByName)
.reduce(({ actives, inactives }, profile) => {
return this.isActive(profile.name)
? { actives: [...actives, profile], inactives }
: { inactives: [...inactives, profile], actives }
}, { actives: [], inactives: [] })
const activeTile = actives.length !== 0 // // Filter all active and inactive modules that are not required
? yo` // const { actives, inactives } = this.appManager.getAll()
<nav class="plugins-list-header justify-content-between navbar navbar-expand-lg bg-light navbar-light align-items-center"> // .filter(isFiltered)
<span class="navbar-brand plugins-list-title">Active Modules</span> // .filter(isNotRequired)
<span class="badge badge-primary" data-id="pluginManagerComponentActiveTilesCount">${actives.length}</span> // .filter(isNotDependent)
</nav> // .filter(isNotHome)
` // .sort(sortByName)
: '' // .reduce(({ actives, inactives }, profile) => {
const inactiveTile = inactives.length !== 0 // return this.isActive(profile.name)
? yo` // ? { actives: [...actives, profile], inactives }
<nav class="plugins-list-header justify-content-between navbar navbar-expand-lg bg-light navbar-light align-items-center"> // : { inactives: [...inactives, profile], actives }
<span class="navbar-brand plugins-list-title h6 mb-0 mr-2">Inactive Modules</span> // }, { actives: [], inactives: [] })
<span class="badge badge-primary" style = "cursor: default;" data-id="pluginManagerComponentInactiveTilesCount">${inactives.length}</span>
</nav>
`
: ''
const settings = new PluginManagerSettings().render() // const activeTile = actives.length !== 0
// ? yo`
// <nav class="plugins-list-header justify-content-between navbar navbar-expand-lg bg-light navbar-light align-items-center">
// <span class="navbar-brand plugins-list-title">Active Modules</span>
// <span class="badge badge-primary" data-id="pluginManagerComponentActiveTilesCount">${actives.length}</span>
// </nav>
// `
// : ''
// const inactiveTile = inactives.length !== 0
// ? yo`
// <nav class="plugins-list-header justify-content-between navbar navbar-expand-lg bg-light navbar-light align-items-center">
// <span class="navbar-brand plugins-list-title h6 mb-0 mr-2">Inactive Modules</span>
// <span class="badge badge-primary" style = "cursor: default;" data-id="pluginManagerComponentInactiveTilesCount">${inactives.length}</span>
// </nav>
// `
// : ''
const rootView = yo` // const settings = new PluginManagerSettings().render()
<div id='pluginManager' data-id="pluginManagerComponentPluginManager">
<header class="form-group ${css.pluginSearch} plugins-header py-3 px-4 border-bottom" data-id="pluginManagerComponentPluginManagerHeader">
<input onkeyup="${e => this.filterPlugins(e)}" class="${css.pluginSearchInput} form-control" placeholder="Search" data-id="pluginManagerComponentSearchInput">
<button onclick="${_ => this.openLocalPlugin()}" class="${css.pluginSearchButton} btn bg-transparent text-dark border-0 mt-2 text-underline" data-id="pluginManagerComponentPluginSearchButton">
Connect to a Local Plugin
</button>
</header>
<section data-id="pluginManagerComponentPluginManagerSection">
${activeTile}
<div class="list-group list-group-flush plugins-list-group" data-id="pluginManagerComponentActiveTile">
${actives.map(profile => this.renderItem(profile))}
</div>
${inactiveTile}
<div class="list-group list-group-flush plugins-list-group" data-id="pluginManagerComponentInactiveTile">
${inactives.map(profile => this.renderItem(profile))}
</div>
</section>
${settings}
</div>
`
if (!this.views.root) this.views.root = rootView
return rootView
}
renderComponent () { // const rootView = yo`
ReactDOM.render(<RemixUIPluginManager />, this.htmElement) // <div id='pluginManager' data-id="pluginManagerComponentPluginManager">
// <header class="form-group ${css.pluginSearch} plugins-header py-3 px-4 border-bottom" data-id="pluginManagerComponentPluginManagerHeader">
// <input onkeyup="${e => this.filterPlugins(e)}" class="${css.pluginSearchInput} form-control" placeholder="Search" data-id="pluginManagerComponentSearchInput">
// <button onclick="${_ => this.openLocalPlugin()}" class="${css.pluginSearchButton} btn bg-transparent text-dark border-0 mt-2 text-underline" data-id="pluginManagerComponentPluginSearchButton">
// Connect to a Local Plugin
// </button>
// </header>
// <section data-id="pluginManagerComponentPluginManagerSection">
// ${activeTile}
// <div class="list-group list-group-flush plugins-list-group" data-id="pluginManagerComponentActiveTile">
// ${actives.map(profile => this.renderItem(profile))}
// </div>
// ${inactiveTile}
// <div class="list-group list-group-flush plugins-list-group" data-id="pluginManagerComponentInactiveTile">
// ${inactives.map(profile => this.renderItem(profile))}
// </div>
// </section>
// ${settings}
// </div>
// `
// if (!this.views.root) this.views.root = rootView
return this.htmlElement
} }
reRender () { // reRender () { --> no needed possibly
if (this.views.root) { // if (this.views.root) {
yo.update(this.views.root, this.render()) // yo.update(this.views.root, this.render())
} // }
} // }
filterPlugins ({ target }) { // filterPlugins ({ target }) {
this.filter = target.value.toLowerCase() // this.filter = target.value.toLowerCase()
this.reRender() // this.reRender()
} // }
} }
module.exports = PluginManagerComponent module.exports = PluginManagerComponent

@ -3,7 +3,7 @@ const csjs = require('csjs-inject')
const modalDialog = require('../ui/modaldialog') const modalDialog = require('../ui/modaldialog')
const css = csjs` const css = csjs`
.permissions { .remixui_permissions {
position: sticky; position: sticky;
bottom: 0; bottom: 0;
display: flex; display: flex;

@ -1 +1 @@
export * from './lib/remix-ui-plugin-manager'; export * from './lib/remix-ui-plugin-manager'

@ -0,0 +1,36 @@
import React, { createContext, useState } from 'react'
import { Profile } from '../../customTypes'
import * as packageJson from '../../../../../../package.json'
// export interface RemixUiPluginManagerProps {
// activatePlugin: (name: string) => void
// deActivatePlugin: (name: string) => void
// isActive: () => void
// openLocalPlugin: () => Promise<void>
// filterPlugins: () => void
// reRender: () => void
// profile: Profile
// }
export const PluginManagerContext = createContext({})
function PluginManagerContextProvider ({ children }) {
const [profile] = useState<Profile>({
name: 'pluginManager',
displayName: 'Plugin manager',
methods: [],
events: [],
icon: 'assets/img/pluginManager.webp',
description: 'Start/stop services, modules and plugins',
kind: 'settings',
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/plugin_manager.html',
version: packageJson.version
})
return (
<PluginManagerContext.Provider value={profile}>
{children}
</PluginManagerContext.Provider>
)
}
export default PluginManagerContextProvider

@ -1,4 +1,4 @@
.pluginSearch { .remixui_pluginSearch {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -9,42 +9,42 @@
z-index: 2; z-index: 2;
margin-bottom: 0px; margin-bottom: 0px;
} }
.pluginSearchInput { .remixui_pluginSearchInput {
height: 38px; height: 38px;
} }
.pluginSearchButton { .remixui_pluginSearchButton {
font-size: 13px; font-size: 13px;
} }
.displayName { .remixui_displayName {
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
.pluginIcon { .remixui_pluginIcon {
height: 0.7rem; height: 0.7rem;
width: 0.7rem; width: 0.7rem;
filter: invert(0.5); filter: invert(0.5);
} }
.description { .remixui_description {
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
} }
.descriptiontext { .remixui_descriptiontext {
display: block; display: block;
} }
.descriptiontext:first-letter { .remixui_descriptiontext:first-letter {
text-transform: uppercase; text-transform: uppercase;
} }
.row { .remixui_row {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
.isStuck { .remixui_isStuck {
background-color: var(--primary); background-color: var(--primary);
/* color: */ /* color: */
} }
.versionWarning { .remixui_versionWarning {
padding: 4px; padding: 4px;
margin: 0 8px; margin: 0 8px;
font-weight: 700; font-weight: 700;
@ -55,3 +55,42 @@
border: 1px solid; border: 1px solid;
border-radius: 2px; border-radius: 2px;
} }
.remixui_permissions {
position: sticky;
bottom: 0;
display: flex;
justify-content: flex-end;
align-items: center;
padding: 5px 20px;
}
.remixui_permissions button {
padding: 2px 5px;
cursor: pointer;
}
.remixui_permissionForm h4 {
font-size: 1.3rem;
text-align: center;
}
.remixui_permissionForm h6 {
font-size: 1.1rem;
}
.remixui_permissionForm hr {
width: 80%;
}
.remixui_permissionKey {
display: flex;
justify-content: space-between;
align-items: center;
}
.remixui_permissionKey i {
cursor: pointer;
}
.remixui_checkbox {
display: flex;
align-items: center;
}
.remixui_checkbox label {
margin: 0;
font-size: 1rem;
}

@ -20,5 +20,3 @@ export const RemixUiPluginManager = (props: RemixUiPluginManagerProps) => {
</div> </div>
) )
} }
export default RemixUiPluginManager

Loading…
Cancel
Save