Effect changes as advised by IOE Developer. Remove logic from button component and make it an SFC.

pull/1344/head
joseph izang 3 years ago
parent 3c9448735e
commit 77cd0472dd
  1. 97
      apps/remix-ide/src/app/components/plugin-manager-component.js
  2. 33
      libs/remix-ui/plugin-manager/src/customTypes.ts
  3. 29
      libs/remix-ui/plugin-manager/src/lib/components/ActivateButton.tsx
  4. 34
      libs/remix-ui/plugin-manager/src/lib/components/button.tsx
  5. 28
      libs/remix-ui/plugin-manager/src/lib/components/deactivateButton.tsx
  6. 8
      libs/remix-ui/plugin-manager/src/lib/components/moduleHeading.tsx
  7. 50
      libs/remix-ui/plugin-manager/src/lib/components/permissions/permissionsSettings.tsx
  8. 23
      libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx
  9. 106
      libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx
  10. 42
      libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx
  11. 1
      libs/remix-ui/plugin-manager/src/types.d.ts

@ -92,7 +92,7 @@ const profile = {
class PluginManagerComponent extends ViewPlugin {
constructor (appManager, engine) {
super(profile)
this.event = new EventEmitter() // already exists in engine so not needed here
// this.event = new EventEmitter() // already exists in engine so not needed here
this.appManager = appManager
this.engine = engine
this.pluginManagerSettings = new PluginManagerSettings()
@ -105,42 +105,53 @@ class PluginManagerComponent extends ViewPlugin {
this.localPlugin = new LocalPlugin()
this.filter = ''
this.pluginNames = this.appManager.actives
// this.pluginManagerSettings.
// this.appManager.event.on('activate', () => { this.renderComponent() })
// this.appManager.event.on('deactivate', () => { this.renderComponent() })
// this.engine.event.on('onRegistration', () => { this.renderComponent() })
this.activePlugins = []
this.inactivePlugins = []
}
/**
* Checks and returns true or false if plugin name
* passed in exists in the actives string array in
* RemixAppManager
* @param {string} name name of Plugin
*/
isActive (name) {
this.appManager.actives.includes(name)
}
/**
* Delegates to method activatePlugin in
* RemixAppManager to enable plugin activation
* @param {string} name name of Plugin
*/
activateP (name) {
this.appManager.activatePlugin(name)
this.appManager.event.on('activate', () => {
this.renderComponent()
console.log('activateP method reached. And activation of method was successful')
this.getAndFilterPlugins()
})
_paq.push(['trackEvent', 'manager', 'activate', name])
console.log('activation was logged in _paq and renderComponent has been called.')
}
/**
* Calls and triggers the event deactivatePlugin
* with with manager permission passing in the name
* of the plugin
* @param {string} name name of Plugin
*/
deactivateP (name) {
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.')
this.getAndFilterPlugins()
}
onActivation () {
// this.getAndFilterPlugins()
this.renderComponent()
}
renderComponent () {
ReactDOM.render(
<RemixUiPluginManager
profile={profile}
pluginComponent={this}
appManager={this.appManager}
engine={this.engine}
@ -176,41 +187,41 @@ 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 { 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
}
// reRender () {
// if (this.views.root) {
// yo.update(this.views.root, this.render())
// }
// }
getAndFilterPlugins (filter) {
this.filter = filter ? filter.toLowerCase() : this.filter
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 activatedPlugins = []
const deactivatedPlugins = []
const tempArray = this.appManager.getAll()
.filter(isFiltered)
.filter(isNotRequired)
.filter(isNotDependent)
.filter(isNotHome)
.sort(sortByName)
// eslint-disable-next-line no-debugger
// debugger
tempArray.forEach(profile => {
if (this.appManager.actives.includes(profile.name)) {
activatedPlugins.push(profile)
} else {
deactivatedPlugins.push(profile)
}
})
this.activePlugins = activatedPlugins
this.inactivePlugins = deactivatedPlugins
filterPlugins ({ target }) {
this.filter = target.value.toLowerCase()
this.renderComponent()
}
}

@ -1,33 +0,0 @@
export type PluginManagerSettings = {
openDialog: () => void
onValidation: () => void
clearPermission: (from: any, to: any, method: any) => void
settings: () => HTMLElement
render: () => HTMLElement
}
export type 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: any
}
export type TileLabel = {
label: 'Active Module' | 'Inactive Modules'
}
export type LocalPlugin = {
create: () => Profile
updateName: (target: string) => void
updateDisplayName: (displayName: string) => void
updateProfile: (key: string, e: Event) => void
updateMethods: (target: any) => void
form: () => HTMLElement
}

@ -0,0 +1,29 @@
import React from 'react'
import { PluginManagerComponent } from '../../types'
interface ActivateButtonProps {
buttonText: string
pluginName: string
pluginComponent: PluginManagerComponent
}
function ActivateButton ({
buttonText,
pluginName,
pluginComponent
}: ActivateButtonProps) {
const dataId = `pluginManagerComponent${buttonText}Button${pluginName}`
return (
<button
onClick={() => {
pluginComponent.activateP(pluginName)
}}
className={buttonText === 'Activate' ? 'btn btn-success btn-sm' : 'btn btn-secondary btn-sm'}
data-id={dataId}
>
{buttonText}
</button>
)
}
export default ActivateButton

@ -1,34 +0,0 @@
import React, { useState } from 'react'
import { PluginManagerComponent } from '../../types'
interface ButtonProps {
buttonText: 'Activate' | 'Deactivate'
pluginName: string
pluginComponent: PluginManagerComponent
}
function Button ({
buttonText,
pluginName,
pluginComponent
}: ButtonProps) {
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' ? () => {
pluginComponent.activateP(pluginName)
buttonText = 'Deactivate'
} : () => {
pluginComponent.deactivateP(pluginName)
buttonText = 'Activate'
}}
className={buttonText === 'Activate' ? needToActivate : needToDeactivate}
data-id={dataId}
>
{buttonText}
</button>
)
}
export default Button

@ -0,0 +1,28 @@
import React from 'react'
import { PluginManagerComponent } from '../../types'
interface DeactivateButtonProps {
buttonText: string
pluginName: string
pluginComponent: PluginManagerComponent
}
function DeactivateButton ({
buttonText,
pluginName,
pluginComponent
}: DeactivateButtonProps) {
const dataId = `pluginManagerComponent${buttonText}Button${pluginName}`
return (
<button
onClick={() => {
pluginComponent.deactivateP(pluginName)
}}
className={buttonText === 'Deactivate' ? 'btn btn-secondary btn-sm' : ''}
data-id={dataId}
>
{buttonText}
</button>
)
}
export default DeactivateButton

@ -1,18 +1,16 @@
import React from 'react'
import { PluginManagerProfile } from '../../types'
interface ModuleHeadingProps {
headingLabel: string
actives: Partial<PluginManagerProfile>[]
inactives: Partial<PluginManagerProfile>[]
count: number
}
function ModuleHeading ({ headingLabel, actives, inactives }: ModuleHeadingProps) {
function ModuleHeading ({ headingLabel, count }: 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>
<span className="badge badge-primary" style={{ cursor: 'default' }} data-id="pluginManagerComponentInactiveTilesCount">
{headingLabel === 'Active Modules' ? actives.length : inactives.length}
{count}
</span>
</nav>
)

@ -12,37 +12,20 @@ interface PermissionSettingsProps {
}
// <div className="form-group remixui_permissionKey">
// <div className="remixui_checkbox">
// {fromPluginPermission.allow
// ? <span className="mr-2">
// <RemixUiCheckbox
// checked
// onClick={() => togglePermission(fromName, toPlugin, methodName)}
// inputType="checkbox"
// id={`permission-checkbox-${toPlugin}-${methodName}-${toPlugin}`}
// aria-describedby={`module ${fromPluginPermission} asks permission for ${methodName}`}
// />
// </span>
// : <span className="mr-2">
// <RemixUiCheckbox
// checked={false}
// onClick={() => togglePermission(fromName, toPlugin, methodName)}
// inputType="checkbox"
// id={`permission-checkbox-${toPlugin}-${methodName}-${toPlugin}`}
// aria-describedby={`module ${fromPluginPermission} asks permission for ${methodName}`}
// />
// </span>
// }
// <label
// htmlFor={`permission-checkbox-${toPlugin}-${methodName}-${toPlugin}`}
// data-id={`permission-label-${toPlugin}-${methodName}-${toPlugin}`}
// >
// Allow <u>{fromName}</u> to call <u>{methodName}</u>
// </label>
// </div>
// <i onClick={() => pluginSettings.clearPersmission(fromName, toPlugin, methodName)} className="fa fa-trash-alt" data-id={`pluginManagerSettingsRemovePermission-${toPlugin}-${methodName}-${toPlugin}`}></i>
// </div>
interface ShowPermissionsByMethodProps {
methodName: string
fromPlugins: any
toPlugin: string
togglePermission: (fromName: string, methodName: string, toPlugin: string) => void
pluginSettings: PluginManagerSettings
}
function ShowPermissionsByMethod (fromPlugins) {
const checkBoxes = Object.keys(fromPlugins).map(fromName => {
return fromPlugins[fromName]
})
return checkBoxes
}
function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
/**
@ -52,7 +35,6 @@ function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
const toPluginP = ''
const fromName = ''
const methodName = ''
const openModal = () => setModalVisibility(false)
const closeModal = () => setModalVisibility(true)
const togglePermission = (fromPlugin: string, toPlugin: string, methodName: string) => {
@ -75,7 +57,9 @@ function PermisssionsSettings ({ pluginSettings }: PermissionSettingsProps) {
<h4>No Permission requested yet.</h4>
<div className="form-group remixui_permissionKey">
<div className="remixui_checkbox">
{/* ${checkbox} */}
{/* { ShowPermissionsByMethod(pluginSettings.permissions).map(fromPluginPermissions => {
}) } */}
<label htmlFor="permission-checkbox-{toPlugin}-{methodName}-{toPlugin}" data-id="permission-label-{toPlugin}-{methodName}-{toPlugin}">Allow <u>{fromName}</u> to call <u>{methodName}</u></label>
</div>
<i onClick={() => pluginSettings.clearPersmission(fromName, toPluginP, methodName)} className="fa fa-trash-alt" data-id={`pluginManagerSettingsRemovePermission-${toPluginP}-${methodName}-${toPluginP}`}></i>

@ -1,16 +1,22 @@
import { Profile } from '@remixproject/plugin-utils'
import React, { useState } from 'react'
import { PluginManagerComponent, PluginManagerProfile } from '../../types'
import { PluginManagerComponent } from '../../types'
import '../remix-ui-plugin-manager.css'
import Button from './button'
import ActivateButton from './ActivateButton'
import DeactivateButton from './deactivateButton'
interface PluginCardProps {
profile: Partial<PluginManagerProfile>
profile: Profile & {
icon?: string
}
pluginComponent: PluginManagerComponent
buttonText: string
}
// eslint-disable-next-line no-empty-pattern
function PluginCard ({
profile,
pluginComponent
pluginComponent,
buttonText
}: PluginCardProps) {
const [displayName] = useState<string>((profile.displayName) ? profile.displayName : profile.name)
const [docLink] = useState<JSX.Element>((profile.documentation) ? (
@ -18,6 +24,7 @@ function PluginCard ({
<i aria-hidden="true" className="fas fa-book"/>
</a>
) : null)
const [versionWarning] = useState<JSX.Element>((profile.version && profile.version.match(/\b(\w*alpha\w*)\b/g)) ? (
<small title="Version Alpha" className="remixui_versionWarning plugin-version">alpha</small>
) : (profile.version && profile.version.match(/\b(\w*beta\w*)\b/g)) ? (
@ -34,13 +41,13 @@ function PluginCard ({
{versionWarning}
</div>
{ pluginComponent.isActive(profile.name) ? (
<Button
buttonText="Deactivate"
<DeactivateButton
buttonText={buttonText}
pluginName={profile.name}
pluginComponent={pluginComponent}
/>)
: <Button
buttonText="Activate"
: <ActivateButton
buttonText={buttonText}
pluginName={profile.name}
pluginComponent={pluginComponent}
/>

@ -3,10 +3,10 @@ import React, { Fragment, useEffect, useState } from 'react'
import ModuleHeading from './moduleHeading'
import PluginCard from './pluginCard'
import { ModalDialog } from '@remix-ui/modal-dialog'
import { FormStateProps, PluginManagerComponent, PluginManagerProfile, PluginManagerSettings } from '../../types'
import { FormStateProps, PluginManagerComponent } from '../../types'
import { IframePlugin, WebsocketPlugin } from '@remixproject/engine-web'
import { Profile } from '@remixproject/plugin-utils'
import PermisssionsSettings from './permissions/permissionsSettings'
import { Profile } from '@remixproject/plugin-utils'
const initialState: FormStateProps = {
name: 'test',
@ -29,8 +29,8 @@ function RootView ({ pluginComponent }: RootViewProps) {
const [visible, setVisible] = useState<boolean>(true)
const [plugin, setPlugin] = useState(initialState)
const [filterPlugins, setFilterPlugin] = useState('')
const [activeP, setActiveP] = useState<Partial<PluginManagerProfile>[]>()
const [inactiveP, setInactiveP] = useState<Partial<PluginManagerProfile>[]>()
const [activeP, setActiveP] = useState<Profile[]>([])
const [inactiveP, setInactiveP] = useState<Profile[]>([])
function pluginChangeHandler<P extends keyof FormStateProps> (formProps: P, value: FormStateProps[P]) {
setPlugin({ ...plugin, [formProps]: value })
@ -45,46 +45,19 @@ function RootView ({ pluginComponent }: RootViewProps) {
const closeModal = () => setVisible(true)
// <-- End Modal Visibility States -->
/**
* Plugins list filtering and Sorting based on search input field state change
*/
const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(filterPlugins)
const isNotRequired = (profile) => !pluginComponent.appManager.isRequired(profile.name)
const isNotDependent = (profile) => !pluginComponent.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 } = pluginComponent.appManager.getAll()
.filter(isFiltered)
.filter(isNotRequired)
.filter(isNotDependent)
.filter(isNotHome)
.sort(sortByName)
.reduce(({ actives, inactives }, profile) => {
return pluginComponent.isActive(profile.name)
? { actives: [...actives, profile], inactives }
: { inactives: [...inactives, profile], actives }
}, { actives: [], inactives: [] })
setActiveP(actives)
console.log('profile property on appmanager', pluginComponent.appManager.profile)
setInactiveP(inactives)
}
// <-- End Filtering and Sorting based on search input field
useEffect(() => {
getAndFilterPlugins()
pluginComponent.getAndFilterPlugins(filterPlugins)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [filterPlugins])
useEffect(() => {
}, [activeP, inactiveP])
if (pluginComponent.activePlugins && pluginComponent.activePlugins.length) {
setActiveP(pluginComponent.activePlugins)
}
if (pluginComponent.inactivePlugins && pluginComponent.inactivePlugins.length) {
setInactiveP(pluginComponent.inactivePlugins)
}
}, [pluginComponent.activePlugins, pluginComponent.inactivePlugins])
return (
<Fragment>
@ -99,9 +72,9 @@ function RootView ({ pluginComponent }: RootViewProps) {
if (pluginComponent.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)
pluginComponent.engine.register(lPlugin)
pluginComponent.appManager.activatePlugin(lPlugin.name)
const localPlugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile)
pluginComponent.engine.register(localPlugin)
pluginComponent.appManager.activatePlugin(localPlugin.name)
} }
cancelLabel="Cancel"
cancelFn={closeModal}
@ -209,33 +182,30 @@ function RootView ({ pluginComponent }: RootViewProps) {
</button>
</header>
<section data-id="pluginManagerComponentPluginManagerSection">
{activeP !== undefined
? (
<Fragment>
<ModuleHeading headingLabel="Active Modules" actives={activeP} inactives={inactiveP} />
{activeP.map((profile) => (
<PluginCard
key={profile.name}
profile={profile}
pluginComponent={pluginComponent}
/>
))}
</Fragment>
)
: null
{activeP && <Fragment>
<ModuleHeading headingLabel="Active Modules" count={activeP.length} />
{activeP.map((profile) => (
<PluginCard
buttonText="Deactivate"
key={profile.name}
profile={profile}
pluginComponent={pluginComponent}
/>
))}
</Fragment>
}
{inactiveP && <Fragment>
<ModuleHeading headingLabel="Inactive Modules" count={inactiveP.length} />
{inactiveP.map((profile) => (
<PluginCard
buttonText="Activate"
key={profile.name}
profile={profile}
pluginComponent={pluginComponent}
/>
))}
</Fragment>
}
{inactiveP !== undefined ? (
<Fragment>
<ModuleHeading headingLabel="Inactive Modules" inactives={inactiveP} actives={activeP} />
{inactiveP.map((profile) => (
<PluginCard
key={profile.name}
profile={profile}
pluginComponent={pluginComponent}
/>
))}
</Fragment>
) : null}
</section>
<PermisssionsSettings pluginSettings={pluginComponent.pluginSettings}/>
</div>

@ -3,6 +3,48 @@ import { RemixUiPluginManagerProps } from '../types'
import RootView from './components/rootView'
import './remix-ui-plugin-manager.css'
// const test = () => {
// const appManager = new RemixAppManager()
// const activePlugins: Profile<any>[] = new Array<Profile<any>>()
// const inactivePlugins: Profile<any>[] = new Array<Profile<any>>()
// const isFiltered = (profile) => (profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(this.filter)
// 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 { finalActives, finalInactives } =
// const tempArray = appManager.getAll()
// .filter(isFiltered)
// .filter(isNotRequired)
// .filter(isNotDependent)
// .filter(isNotHome)
// .sort(sortByName)
// tempArray.forEach(profile => {
// if (appManager.actives.includes(profile.name)) {
// activePlugins.push(profile)
// } else {
// inactivePlugins.push(profile)
// }
// })
// return { activePlugins, inactivePlugins }
// // .reduce(({ actives, inactives }, profile) => {
// // return isActive(profile.name)
// // ? { actives: [...actives, profile], inactives }
// // : { inactives: [...inactives, profile], actives }
// // }, { actives: [], inactives: [] })
// // // eslint-disable-next-line no-debugger
// // // debugger
// // activePlugins = finalActives
// // inactivePlugins = finalInactives
// }
export const RemixUiPluginManager = (props: RemixUiPluginManagerProps) => {
return (
<RootView pluginComponent={props.pluginComponent}/>

@ -93,6 +93,7 @@ export class PluginManagerComponent extends ViewPlugin extends Plugin implements
openLocalPlugin(): Promise<void>
render(): HTMLDivElement
filterPlugins({ target }: { target: any }) : void
getAndFilterPlugins: (filter?: string) => void
}
// eslint-disable-next-line no-use-before-define

Loading…
Cancel
Save