pass one large prop pluginComponent to maintain context

pull/1344/head
joseph izang 3 years ago
parent e04206b826
commit 6d2083b8e3
  1. 1
      .gitignore
  2. 79
      apps/remix-ide/src/app/components/plugin-manager-component.js
  3. 8
      libs/remix-ui/plugin-manager/src/lib/components/button.tsx
  4. 9
      libs/remix-ui/plugin-manager/src/lib/components/moduleHeading.tsx
  5. 4
      libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx
  6. 133
      libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx
  7. 2
      libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx
  8. 130
      libs/remix-ui/plugin-manager/src/types.d.ts

1
.gitignore vendored

@ -52,3 +52,4 @@ testem.log
# System Files
.DS_Store
Thumbs.db
.vscode/settings.json

@ -97,7 +97,6 @@ class PluginManagerComponent extends ViewPlugin {
this.engine = engine
this.htmlElement = document.createElement('div')
this.htmlElement.setAttribute('id', 'pluginManager')
this.props = {}
this.views = {
root: null,
items: {}
@ -106,12 +105,10 @@ class PluginManagerComponent extends ViewPlugin {
this.filter = ''
this.activePlugins = []
this.inactivePlugins = []
this.activePluginNames = this.appManager.actives
// this.appManager.event.on('activate', () => { this.reRender() })
// this.appManager.event.on('deactivate', () => { this.reRender() })
// this.engine.event.on('onRegistration', () => { this.reRender() })
// const { actives, inactives } = this.getAllPlugins()
console.log('views property contents', this.views)
this.pluginNames = this.appManager.actives
// this.appManager.event.on('activate', () => { this.renderComponent() })
// this.appManager.event.on('deactivate', () => { this.renderComponent() })
// this.engine.event.on('onRegistration', () => { this.renderComponent() })
}
isActive (name) {
@ -119,15 +116,19 @@ class PluginManagerComponent extends ViewPlugin {
}
activateP (name) {
// console.log(this.appManager)
this.appManager.turnPluginOn(name)
console.log('activateP method reached. And activation of method was successful')
_paq.push(['trackEvent', 'manager', 'activate', name])
this.renderComponent()
console.log('activation was logged in _paq and renderComponent has been called.')
}
deactivateP (name) {
// console.log(this.appManager)
this.call('manager', 'deactivatePlugin', name)
console.log('deactivateP has been called successfully')
_paq.push(['trackEvent', 'manager', 'deactivate', name])
this.renderComponent()
console.log('deactivation was logged and renderComponent has has been called.')
}
onActivation () {
@ -138,15 +139,17 @@ class PluginManagerComponent extends ViewPlugin {
ReactDOM.render(
<RemixUiPluginManager
profile={profile}
pluginComponent={this}
appManager={this.appManager}
engine={this.engine}
localPlugin={this.localPlugin}
activePluginNames={this.activePluginsNames}
activePluginNames={this.pluginNames}
actives={this.activePlugins}
inactives={this.inactivePlugins}
activatePlugin={this.activateP}
deActivatePlugin={this.deactivateP}
// activatePlugin={this.activateP}
// deActivatePlugin={this.deactivateP}
_paq={_paq}
filter={this.filter}
/>,
document.getElementById('pluginManager'))
}
@ -176,29 +179,29 @@ class PluginManagerComponent extends ViewPlugin {
render () {
// Filtering helpers
const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(this.filter)
const isNotRequired = (profile) => !this.appManager.isRequired(profile.name)
const isNotDependent = (profile) => !this.appManager.isDependent(profile.name)
const isNotHome = (profile) => profile.name !== 'home'
const sortByName = (profileA, profileB) => {
const nameA = ((profileA.displayName) ? profileA.displayName : profileA.name).toUpperCase()
const nameB = ((profileB.displayName) ? profileB.displayName : profileB.name).toUpperCase()
return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0
}
// const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(this.filter)
// const isNotRequired = (profile) => !this.appManager.isRequired(profile.name)
// const isNotDependent = (profile) => !this.appManager.isDependent(profile.name)
// const isNotHome = (profile) => profile.name !== 'home'
// const sortByName = (profileA, profileB) => {
// const nameA = ((profileA.displayName) ? profileA.displayName : profileA.name).toUpperCase()
// const nameB = ((profileB.displayName) ? profileB.displayName : profileB.name).toUpperCase()
// return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0
// }
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: [] })
this.activePlugins = actives
this.inactivePlugins = inactives
// 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: [] })
// this.activePlugins = actives
// this.inactivePlugins = inactives
return this.htmlElement
}
@ -208,10 +211,10 @@ class PluginManagerComponent extends ViewPlugin {
// }
// }
// filterPlugins ({ target }) {
// this.filter = target.value.toLowerCase()
// this.reRender()
// }
filterPlugins ({ target }) {
this.filter = target.value.toLowerCase()
this.renderComponent()
}
}
module.exports = PluginManagerComponent

@ -7,19 +7,17 @@ interface ButtonProps {
}
function Button ({ buttonText, pluginName }: ButtonProps) {
const { appManager, _paq } = useContext(PluginManagerContext)
const { pluginComponent } = useContext(PluginManagerContext)
const dataId = `pluginManagerComponentDeactivateButton${pluginName}`
const [needToDeactivate] = useState('btn btn-secondary btn-sm')
const [needToActivate] = useState('btn btn-success btn-sm')
return (
<button
onClick={buttonText === 'Activate' ? () => {
appManager.turnPluginOn(pluginName)
_paq.push(['trackEvent', 'manager', 'activate', pluginName])
pluginComponent.activateP(pluginName)
buttonText = 'Deactivate'
} : () => {
appManager.turnPluginOff(pluginName)
_paq.push(['trackEvent', 'manager', 'deactivate', pluginName])
pluginComponent.deactivateP(pluginName)
buttonText = 'Activate'
}}
className={buttonText === 'Activate' ? needToActivate : needToDeactivate}

@ -1,12 +1,13 @@
import React, { useContext } from 'react'
import { PluginManagerContext } from '../contexts/pluginmanagercontext'
import React from 'react'
import { PluginManagerProfile } from '../../types'
interface ModuleHeadingProps {
headingLabel: string
actives: Partial<PluginManagerProfile>[]
inactives: Partial<PluginManagerProfile>[]
}
function ModuleHeading ({ headingLabel }: ModuleHeadingProps) {
const { actives, inactives } = useContext(PluginManagerContext)
function ModuleHeading ({ headingLabel, actives, inactives }: ModuleHeadingProps) {
return (
<nav className="plugins-list-header justify-content-between navbar navbar-expand-lg bg-light navbar-light align-items-center">
<span className="navbar-brand plugins-list-title h6 mb-0 mr-2">{headingLabel}</span>

@ -9,7 +9,7 @@ interface PluginCardProps {
// eslint-disable-next-line no-empty-pattern
function PluginCard ({ profile }: PluginCardProps) {
const { activePluginNames } = useContext(PluginManagerContext)
const { pluginComponent } = useContext(PluginManagerContext)
const [displayName] = useState<string>((profile.displayName) ? profile.displayName : profile.name)
const [docLink] = useState<JSX.Element>((profile.documentation) ? (
<a href={profile.documentation} className="px-1" title="link to documentation" target="_blank" rel="noreferrer">
@ -31,7 +31,7 @@ function PluginCard ({ profile }: PluginCardProps) {
{docLink}
{versionWarning}
</div>
{ activePluginNames.includes(profile.name) ? (
{ pluginComponent.isActive(profile.name) ? (
<Button
buttonText="Deactivate"
pluginName={profile.name}

@ -4,10 +4,7 @@ import { PluginManagerContext } from '../contexts/pluginmanagercontext'
import ModuleHeading from './moduleHeading'
import PluginCard from './pluginCard'
import { ModalDialog } from '@remix-ui/modal-dialog'
import { FormStateProps, PluginManagerProfile, RemixAppManager } from '../../types'
import { IframePlugin, WebsocketPlugin } from '@remixproject/engine-web'
import { Profile } from '@remixproject/plugin-utils'
import * as lo from 'lodash'
import { FormStateProps, PluginManagerProfile } from '../../types'
const initialState: FormStateProps = {
name: 'test',
@ -19,49 +16,60 @@ const initialState: FormStateProps = {
location: 'sidePanel'
}
interface ShowInactivesProps {
inactives: Partial<PluginManagerProfile>[]
headinglabel: string
}
function ShowInactives ({ inactives, headinglabel }: ShowInactivesProps) {
return (
<Fragment>
<ModuleHeading headingLabel={headinglabel} />
{inactives.map((profile) => (
<PluginCard key={profile.name} profile={profile} />
))}
</Fragment>
)
}
function ShowActives ({ inactives, headinglabel }: ShowInactivesProps) {
console.log('actived plugins are :', inactives)
return (
<Fragment>
<ModuleHeading headingLabel={headinglabel} />
{inactives.map((profile) => (
<PluginCard key={profile.name} profile={profile} />
))}
</Fragment>
)
}
function RootView () {
const { appManager, actives, engine, inactives, localPlugin } = useContext(PluginManagerContext)
const { appManager, pluginComponent, activePluginNames } = useContext(PluginManagerContext)
const [visible, setVisible] = useState<boolean>(true)
const [plugin, setPlugin] = useState(initialState)
const [filterPlugins, setFilterPlugin] = useState('')
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, setGetAndFilter] = useState<any>()
const [activeP, setActiveP] = useState<any[]>()
const [inactiveP, setInactiveP] = useState<any[]>()
function pluginChangeHandler<P extends keyof FormStateProps> (formProps: P, value: FormStateProps[P]) {
setPlugin({ ...plugin, [formProps]: value })
appManager.activatePlugin('')
}
const openModal = () => {
setVisible(false)
}
const closeModal = () => setVisible(true)
const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(filterPlugins)
const isNotRequired = (profile) => !appManager.isRequired(profile.name)
const isNotDependent = (profile) => !appManager.isDependent(profile.name)
const isNotHome = (profile) => profile.name !== 'home'
const sortByName = (profileA, profileB) => {
const nameA = ((profileA.displayName) ? profileA.displayName : profileA.name).toUpperCase()
const nameB = ((profileB.displayName) ? profileB.displayName : profileB.name).toUpperCase()
return (nameA < nameB) ? -1 : (nameA > nameB) ? 1 : 0
}
const getAndFilterPlugins = () => {
const { actives, inactives } = appManager.getAll()
.filter(isFiltered)
.filter(isNotRequired)
.filter(isNotDependent)
.filter(isNotHome)
.sort(sortByName)
.reduce(({ actives, inactives }, profile) => {
return activePluginNames.includes(profile.name)
? { actives: [...actives, profile], inactives }
: { inactives: [...inactives, profile], actives }
}, { actives: [], inactives: [] })
setActiveP(actives)
setInactiveP(inactives)
}
useEffect(() => {
setGetAndFilter(getAndFilterPlugins())
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filterPlugins])
useEffect(() => {
// engine.event.on('onRegistration', () => )
})
console.log('This is the result of getting and filtering all plugins from app manager :', inactiveP)
return (
<Fragment>
<form id="local-plugin-form">
@ -71,19 +79,20 @@ function RootView () {
title="Local Plugin"
okLabel="OK"
okFn={async () => {
const plugins = appManager.getActiveProfiles()
console.log('There are the active plugins from appManager :', plugins)
const profile: any = await localPlugin.open(appManager.getAll())
if (appManager.getIds().includes(profile.name)) {
throw new Error('This name has already been used')
}
const lPlugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile)
console.log('handle submit local plugin', lPlugin)
console.log('Local PLugin type from legacy as props', localPlugin)
engine.register(lPlugin)
console.log('engine has registered lPlugin')
await appManager.activatePlugin(lPlugin.name)
console.log('appManager has activated lPlugin')
// const plugins = appManager.getActiveProfiles()
// console.log('There are the active plugins from appManager :', plugins)
// const profile: any = await localPlugin.open(appManager.getAll())
// if (appManager.getIds().includes(profile.name)) {
// throw new Error('This name has already been used')
// }
// const lPlugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile)
// console.log('handle submit local plugin', lPlugin)
// console.log('Local PLugin type from legacy as props', localPlugin)
// engine.register(lPlugin)
// console.log('engine has registered lPlugin')
// await appManager.activatePlugin(lPlugin.name)
// console.log('appManager has activated lPlugin')
await pluginComponent.openLocalPlugin()
} }
cancelLabel="Cancel"
cancelFn={closeModal}
@ -176,17 +185,39 @@ function RootView () {
</ModalDialog>
</form><div id="pluginManager" data-id="pluginManagerComponentPluginManager">
<header className="form-group remixui_pluginSearch plugins-header py-3 px-4 border-bottom" data-id="pluginManagerComponentPluginManagerHeader">
<input type="text" className="form-control" placeholder="Search" data-id="pluginManagerComponentSearchInput" />
<input
type="text"
onChange={(event) => {
setFilterPlugin(event.target.value.toLowerCase())
}}
className="form-control"
placeholder="Search"
data-id="pluginManagerComponentSearchInput"
/>
<button onClick={openModal} className="remixui_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">
{actives !== undefined
? (<ShowActives headinglabel="Active Modules" inactives={actives} />)
: (<ShowActives headinglabel="Active Modules" inactives={actives}/>)
{activeP !== undefined
? (
<Fragment>
<ModuleHeading headingLabel="Active Modules" actives={activeP} inactives={inactiveP} />
{activeP.map((profile) => (
<PluginCard key={profile.name} profile={profile} />
))}
</Fragment>
)
: null
}
{inactives !== undefined ? (<ShowInactives inactives={inactives} headinglabel="Inactive Modules" />) : <ShowInactives inactives={inactives} headinglabel="Inactive Modules" />}
{inactiveP !== undefined ? (
<Fragment>
<ModuleHeading headingLabel="Inactive Modules" inactives={inactiveP} actives={activeP} />
{inactiveP.map((profile) => (
<PluginCard key={profile.name} profile={profile} />
))}
</Fragment>
) : null}
</section>
</div>
</Fragment>

@ -5,7 +5,7 @@ import PluginManagerContextProvider from './contexts/pluginmanagercontext'
import './remix-ui-plugin-manager.css'
export const RemixUiPluginManager = (props: RemixUiPluginManagerProps) => {
console.log('current state of appmanager', props.appManager)
console.log('current state of appmanager', props.pluginComponent)
console.log('The state of props ', props)
return (

@ -2,48 +2,9 @@ import { PermissionHandler } from './app/ui/persmission-handler'
import { PluginManager } from '@remixproject/engine/lib/manager'
import { EventEmitter } from 'events'
import { Engine } from '@remixproject/engine/lib/engine'
import { Profile } from '@remixproject/plugin-utils'
import { PluginBase, Profile } from '@remixproject/plugin-utils'
import { ViewPlugin } from '@remixproject/engine-web'
/* eslint-disable camelcase */
// eslint-disable-next-line no-use-before-define
export = LocalPlugin;
declare class LocalPlugin {
/**
* Open a modal to create a local plugin
* @param {Profile[]} plugins The list of the plugins in the store
* @returns {Promise<{api: any, profile: any}>} A promise with the new plugin profile
*/
open(plugins: any[]): Promise<{
api: any;
profile: any;
}>;
profile: any;
/**
* Create the object to add to the plugin-list
*/
create(): any;
updateName({ target }: {
target: any;
}): void;
updateUrl({ target }: {
target: any;
}): void;
updateDisplayName({ target }: {
target: any;
}): void;
updateProfile(key: any, e: any): void;
updateMethods({ target }: {
target: any;
}): void;
/** The form to create a local plugin */
form(): any;
}
declare module 'yo-yo'{
interface yo_yo {
(strings:string[], ...values:any[]):HTMLElement;
@ -99,17 +60,86 @@ export class RemixAppManager extends PluginManager {
turnPluginOff(name: string);
}
export interface PluginManagerContextProviderProps {
export class PluginManagerSettings {
openDialog(): void;
permissions: any;
currentSetting: any;
onValidation(): void;
/** Clear one permission from a plugin */
clearPersmission(from: any, to: any, method: any): void;
/** Clear all persmissions from a plugin */
clearAllPersmission(to: any): void;
settings(): any;
render(): any;
}
export class PluginManagerComponent extends ViewPlugin extends Plugin implements PluginBase {
constructor(appManager: RemixAppManager, engine: Engine)
appManager: RemixAppManager
engine: RemixEngine
engine: Engine
htmlElement: HTMLDivElement
views: { root: null, items: {} }
localPlugin: LocalPlugin
_paq: any
pluginNames: string[]
inactivePlugins: Profile[]
activePlugins: Profile[]
filter: string
isActive(name: string): boolean
activateP(name: string): void
deactivateP(name: string): void
onActivation(): void
renderComponent(): void
openLocalPlugin(): Promise<void>
render(): HTMLDivElement
filterPlugins({ target }: { target: any }) : void
}
// eslint-disable-next-line no-use-before-define
export = LocalPlugin;
declare class LocalPlugin {
/**
* Open a modal to create a local plugin
* @param {Profile[]} plugins The list of the plugins in the store
* @returns {Promise<{api: any, profile: any}>} A promise with the new plugin profile
*/
open(plugins: any[]): Promise<{
api: any;
profile: any;
}>;
profile: any;
/**
* Create the object to add to the plugin-list
*/
create(): any;
updateName({ target }: {
target: any;
}): void;
updateUrl({ target }: {
target: any;
}): void;
updateDisplayName({ target }: {
target: any;
}): void;
updateProfile(key: any, e: any): void;
updateMethods({ target }: {
target: any;
}): void;
/** The form to create a local plugin */
form(): any;
}
export interface PluginManagerContextProviderProps {
appManager: RemixAppManager
pluginComponent: PluginManagerComponent
pluginSettings: PluginManagerSettings
activePluginNames: string[]
actives: Partial<PluginManagerProfile>[]
inactives: Partial<PluginManagerProfile>[]
activatePlugin: (name: string) => void
deActivatePlugin: (name: string) => void
isActive?: (name: string) => boolean
filterPlugins: () => void
profile: Partial<PluginManagerProfile>
@ -119,15 +149,11 @@ export interface PluginManagerContextProviderProps {
export interface RemixUiPluginManagerProps {
appManager: RemixAppManager
engine: RemixEngine
localPlugin: LocalPlugin
_paq: any // Window & typeof globalThis | []
filter: string
pluginComponent: PluginManagerComponent
pluginSettings: PluginManagerSettings // Window & typeof globalThis | []
activePluginNames: string[]
actives: Partial<PluginManagerProfile>[]
inactives: Partial<PluginManagerProfile>[]
activatePlugin: (name: string) => void
deActivatePlugin: (name: string) => void
isActive?: (name: string) => boolean
filterPlugins: () => void
profile: Partial<PluginManagerProfile>

Loading…
Cancel
Save