Fix components and plug props at provider level

pull/1344/head
joseph izang 4 years ago
parent 9f516a8467
commit 4c05461e58
  1. 157
      apps/remix-ide/src/app/components/plugin-manager-component.js
  2. 19
      libs/remix-ui/plugin-manager/src/lib/components/activeTile.tsx
  3. 12
      libs/remix-ui/plugin-manager/src/lib/components/listGroupItem.tsx
  4. 28
      libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx
  5. 77
      libs/remix-ui/plugin-manager/src/lib/components/renderItem.tsx
  6. 37
      libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx
  7. 14
      libs/remix-ui/plugin-manager/src/lib/contexts/pluginmanagercontext.tsx
  8. 95
      libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx
  9. 36
      libs/remix-ui/plugin-manager/src/types.d.ts

@ -92,11 +92,12 @@ const profile = {
class PluginManagerComponent extends ViewPlugin { class PluginManagerComponent extends ViewPlugin {
constructor (appManager, engine) { constructor (appManager, engine) {
super(profile) 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.appManager = appManager
// this.engine = engine this.engine = engine
this.htmlElement = document.createElement('div') this.htmlElement = document.createElement('div')
this.htmlElement.setAttribute('id', 'pluginManager') this.htmlElement.setAttribute('id', 'pluginManager')
this.props = {}
// this.views = { // this.views = {
// root: null, // root: null,
// items: {} // items: {}
@ -106,6 +107,22 @@ class PluginManagerComponent extends ViewPlugin {
// this.appManager.event.on('activate', () => { this.reRender() }) // this.appManager.event.on('activate', () => { this.reRender() })
// this.appManager.event.on('deactivate', () => { this.reRender() }) // this.appManager.event.on('deactivate', () => { this.reRender() })
// this.engine.event.on('onRegistration', () => { this.reRender() }) // this.engine.event.on('onRegistration', () => { this.reRender() })
// const { actives, inactives } = this.getAllPlugins()
}
reactProps () {
return {
views: this.views,
filter: this.filter,
localPlugin: this.localPlugin,
isActive: this.isActive,
activatePlugin: this.activateP,
deactivePlugin: this.deactivateP,
openLocalPlugin: this.openLocalPlugin,
profile: this.profile
// actives: actives,
// inactives: inactives
}
} }
onActivation () { onActivation () {
@ -113,22 +130,46 @@ class PluginManagerComponent extends ViewPlugin {
} }
renderComponent () { renderComponent () {
ReactDOM.render(<RemixUiPluginManager />, document.getElementById('pluginManager')) // const props = this.reactProps()
ReactDOM.render(
// <RemixUiPluginManager
// activatePlugin={this.activateP}
// deActivatePlugin={this.deactivate}
// filter={this.filter}
// appManager={this.appManager}
// engine={this.engine}
// profile={this.profile}
// isActive={this.isActive}
// openLocalPlugin={this.openLocalPlugin}
// tileLabel
// _paq={_paq}
// {...props}
// />,
<RemixUiPluginManager
profile={profile}
appManager={this.appManager}
engine={this.engine}
activesCount={3}
inactivesCount={4}
actives={[]}
inactives={[]}
/>,
document.getElementById('pluginManager'))
} }
isActive (name) { // isActive (name) {
return this.appManager.actives.includes(name) // return this.appManager.actives.includes(name)
} // }
activateP (name) { // activateP (name) {
this.appManager.activatePlugin(name) // this.appManager.activatePlugin(name)
_paq.push(['trackEvent', 'manager', 'activate', name]) // _paq.push(['trackEvent', 'manager', 'activate', name])
} // }
deactivateP (name) { // deactivateP (name) {
this.call('manager', 'deactivatePlugin', name) // this.call('manager', 'deactivatePlugin', name)
_paq.push(['trackEvent', 'manager', 'deactivate', name]) // _paq.push(['trackEvent', 'manager', 'deactivate', name])
} // }
// renderItem (profile) { // renderItem (profile) {
// const displayName = (profile.displayName) ? profile.displayName : profile.name // const displayName = (profile.displayName) ? profile.displayName : profile.name
@ -189,47 +230,55 @@ class PluginManagerComponent extends ViewPlugin {
/** /**
* Add a local plugin to the list of plugins * Add a local plugin to the list of plugins
*/ */
async openLocalPlugin () { // async openLocalPlugin () {
try { // try {
const profile = await this.localPlugin.open(this.appManager.getAll()) // const profile = await this.localPlugin.open(this.appManager.getAll())
if (!profile) return // if (!profile) return
if (this.appManager.getIds().includes(profile.name)) { // if (this.appManager.getIds().includes(profile.name)) {
throw new Error('This name has already been used') // throw new Error('This name has already been used')
} // }
const plugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile) // const plugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile)
this.engine.register(plugin) // this.engine.register(plugin)
await this.appManager.activatePlugin(plugin.name) // await this.appManager.activatePlugin(plugin.name)
} catch (err) { // } catch (err) {
// TODO : Use an alert to handle this error instead of a console.log // // TODO : Use an alert to handle this error instead of a console.log
console.log(`Cannot create Plugin : ${err.message}`) // console.log(`Cannot create Plugin : ${err.message}`)
addToolTip(`Cannot create Plugin : ${err.message}`) // addToolTip(`Cannot create Plugin : ${err.message}`)
} // }
} // }
// filterHelper () {
// 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
// }
// return (isFiltered, isNotRequired, isNotDependent, isNotHome, sortByName)
// }
// getAllPlugins () {
// // // Filter all active and inactive modules that are not required
// const [isFiltered, isNotRequired, isNotDependent, isNotHome, sortByName] = this.filterHelper()
// 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: [] })
// return (actives, inactives)
// }
render () { render () {
// Filtering helpers // 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
}
// // 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 // const activeTile = actives.length !== 0
// ? yo` // ? yo`
@ -275,7 +324,7 @@ class PluginManagerComponent extends ViewPlugin {
return this.htmlElement return this.htmlElement
} }
// reRender () { --> no needed possibly // reRender () {
// if (this.views.root) { // if (this.views.root) {
// yo.update(this.views.root, this.render()) // yo.update(this.views.root, this.render())
// } // }

@ -1,21 +1,20 @@
import React from 'react' import React, { useContext } from 'react'
import { TileLabel } from '../../customTypes' import { PluginManagerContext } from '../contexts/pluginmanagercontext'
interface ActiveTileProps { interface ModuleHeadingProps {
inactivesCount?: number headingLabel: string
activesCount?: number
tileLabel?: TileLabel
} }
function ActiveTile ({ inactivesCount, activesCount, tileLabel }: ActiveTileProps) { function ModuleHeading ({ headingLabel }: ModuleHeadingProps) {
const { inactivesCount, activesCount } = useContext(PluginManagerContext)
return ( return (
<nav className="plugins-list-header justify-content-between navbar navbar-expand-lg bg-light navbar-light align-items-center"> <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">{tileLabel.label}</span> <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"> <span className="badge badge-primary" style={{ cursor: 'default' }} data-id="pluginManagerComponentInactiveTilesCount">
{tileLabel.label === 'Active Module' ? activesCount : tileLabel.label === 'Inactive Modules' ? inactivesCount : '-' } {headingLabel === 'Active Modules' ? activesCount : inactivesCount}
</span> </span>
</nav> </nav>
) )
} }
export default ActiveTile export default ModuleHeading

@ -3,21 +3,23 @@ import { Profile } from '../../customTypes'
import RenderItem from './renderItem' import RenderItem from './renderItem'
interface ListGroupItemProps { interface ListGroupItemProps {
activeProfiles: Profile[] activeProfiles?: Profile[]
inactiveProfiles: Profile[] inactiveProfiles?: Profile[]
} }
function ListGroupItem ({ activeProfiles, inactiveProfiles }: ListGroupItemProps) { function ListGroupItem () {
return ( return (
<div className="list-group list-group-flush plugins-list-group" data-id="pluginManagerComponentActiveTile"> <div className="list-group list-group-flush plugins-list-group" data-id="pluginManagerComponentActiveTile">
{ activeProfiles.length > 0 {/* { activeProfiles.length > 0
? activeProfiles.map(profile => ( ? activeProfiles.map(profile => (
<RenderItem profile={profile} /> <RenderItem profile={profile} />
)) ))
: inactiveProfiles.map(profile => ( : inactiveProfiles.map(profile => (
<RenderItem profile={profile}/> <RenderItem profile={profile}/>
)) ))
} } */}
<RenderItem />
<h6 className="h6">List Group Item Component</h6>
</div> </div>
) )
} }

@ -1,4 +1,5 @@
import React from 'react' import React, { useContext } from 'react'
import { PluginManagerContext } from '../contexts/pluginmanagercontext'
import '../remix-ui-plugin-manager.css' import '../remix-ui-plugin-manager.css'
import Button from './button' import Button from './button'
interface PluginCardProps { interface PluginCardProps {
@ -10,32 +11,27 @@ interface PluginCardProps {
profileDescription: string profileDescription: string
} }
function PluginCard ({ // eslint-disable-next-line no-empty-pattern
profileName, function PluginCard () {
displayName, const { profile } = useContext(PluginManagerContext)
docLink,
versionWarning,
profileIcon,
profileDescription
}: PluginCardProps) {
return ( return (
<article className="list-group-item py-1 mb-1 plugins-list-group-item" title={displayName}> <article className="list-group-item py-1 mb-1 plugins-list-group-item" title="PLuginCardTitle">
<div className="row justify-content-between align-items-center mb-2"> <div className="row justify-content-between align-items-center mb-2">
<h6 className="displayName plugin-name"> <h6 className="displayName plugin-name">
<div> <div>
{displayName} {profile.displayName}
{docLink} {profile.docLink}
{versionWarning} {profile.versionWarning}
</div> </div>
<Button <Button
profileName={profileName} profileName="Sample Profile"
isActive isActive
/> />
</h6> </h6>
</div> </div>
<div className="description d-flex text-body plugin-text mb-2"> <div className="description d-flex text-body plugin-text mb-2">
<img src={profileIcon} className="mr-1 mt-1 pluginIcon" alt="profile icon"/> <img src="" className="mr-1 mt-1 pluginIcon" alt="profile icon"/>
<span className="descriptiontext">{profileDescription}</span> <span className="descriptiontext">{profile.description}</span>
</div> </div>
</article> </article>
) )

@ -1,52 +1,55 @@
import React, { useEffect, useState } from 'react' import React, { useContext } from 'react'
import { Profile } from '../../customTypes' import { Profile } from '../../customTypes'
import { PluginManagerContext } from '../contexts/pluginmanagercontext'
import PluginCard from './pluginCard' import PluginCard from './pluginCard'
interface RenderItemProps { interface RenderItemProps {
profile: Profile profile: Profile
} }
function RenderItem ({ profile }: RenderItemProps) { function RenderItem () {
const [displayName, setDisplayName] = useState('') const { profile } = useContext(PluginManagerContext)
const [docLink, setDocLink] = useState<any>() // const [displayName, setDisplayName] = useState('')
const [versionWarning, setVersionWarning] = useState<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>>() // const [docLink, setDocLink] = useState<any>()
// const [versionWarning, setVersionWarning] = useState<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>>()
useEffect(() => { // useEffect(() => {
const checkPluginVersion = (version: string) => { // const checkPluginVersion = (version: string) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // // eslint-disable-next-line @typescript-eslint/no-unused-vars
let versionWarning: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> // let versionWarning: React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>
if (version && version.match(/\b(\w*alpha\w*)\b/g)) { // if (version && version.match(/\b(\w*alpha\w*)\b/g)) {
versionWarning = <small title="Version Alpha" className="remixui_versionWarning plugin-version">alpha</small> // versionWarning = <small title="Version Alpha" className="remixui_versionWarning plugin-version">alpha</small>
} // }
// Beta // // Beta
if (version && version.match(/\b(\w*beta\w*)\b/g)) { // if (version && version.match(/\b(\w*beta\w*)\b/g)) {
versionWarning = <small title="Version Beta" className="remixui_versionWarning plugin-version">beta</small> // versionWarning = <small title="Version Beta" className="remixui_versionWarning plugin-version">beta</small>
} // }
return versionWarning // return versionWarning
} // }
setDisplayName((profile.displayName) ? profile.displayName : profile.name) // setDisplayName((profile.displayName) ? profile.displayName : profile.name)
setDocLink( // setDocLink(
profile.documentation ? ( // profile.documentation ? (
<a href={profile.documentation} // <a href={profile.documentation}
className="px-1" // className="px-1"
title="link to documentation" // title="link to documentation"
// eslint-disable-next-line react/jsx-no-target-blank // // eslint-disable-next-line react/jsx-no-target-blank
target="_blank"> // target="_blank">
<i aria-hidden="true" className="fas fa-book"></i> // <i aria-hidden="true" className="fas fa-book"></i>
</a> // </a>
) : '') // ) : '')
setVersionWarning(checkPluginVersion(profile.version)) // setVersionWarning(checkPluginVersion(profile.version))
}, [profile.displayName, profile.documentation, profile.name, profile.version, versionWarning]) // }, [profile.displayName, profile.documentation, profile.name, profile.version, versionWarning])
console.log('Profile object from render item component', profile)
return ( return (
<PluginCard <PluginCard
displayName={displayName} // displayName={displayName}
docLink={docLink} // docLink={docLink}
versionWarning={versionWarning} // versionWarning={versionWarning}
profileDescription={profile.description} // profileDescription={profile.description}
profileIcon={profile.icon} // profileIcon={profile.icon}
profileName={profile.name} // profileName={profile.name}
/> />
) )
} }

@ -1,5 +1,4 @@
import React, { useContext } from 'react' import React from 'react'
import { PluginManagerContext } from '../remix-ui-plugin-manager'
import ActiveTile from './activeTile' import ActiveTile from './activeTile'
import ListGroupItem from './listGroupItem' import ListGroupItem from './listGroupItem'
@ -8,23 +7,35 @@ interface RootViewProps {
} }
function RootView ({ localPluginButtonText }: RootViewProps) { function RootView ({ localPluginButtonText }: RootViewProps) {
const { actives, inactives, tileLabel } = useContext(PluginManagerContext) // const { actives, inactives, tileLabel } = useContext(PluginManagerContext)
return ( return (
// <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" />
// <button className="btn btn-secondary text-dark border-0" data-id="pluginManagerComponentPluginSearchButton">{localPluginButtonText}</button>
// </header>
// <section data-id="pluginManagerComponentPluginManagerSection">
// <ActiveTile
// activesCount={actives.length}
// inactivesCount={inactives.length}
// tileLabel={tileLabel}
// />
// <ListGroupItem
// activeProfiles={actives}
// inactiveProfiles={inactives}
// />
// </section>
// </div>
<div id="pluginManager" data-id="pluginManagerComponentPluginManager"> <div id="pluginManager" data-id="pluginManagerComponentPluginManager">
<header className="form-group remixui_pluginSearch plugins-header py-3 px-4 border-bottom" data-id="pluginManagerComponentPluginManagerHeader"> <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" className="form-control" placeholder="Search" data-id="pluginManagerComponentSearchInput" />
<button className="btn btn-secondary text-dark border-0" data-id="pluginManagerComponentPluginSearchButton">{localPluginButtonText}</button> <button className="btn btn-secondary text-dark border-0" data-id="pluginManagerComponentPluginSearchButton">Connect to a local Plugin</button>
</header> </header>
<section data-id="pluginManagerComponentPluginManagerSection"> <section data-id="pluginManagerComponentPluginManagerSection">
<ActiveTile <ActiveTile headingLabel="Active Modules"/>
activesCount={actives.length} <ActiveTile headingLabel="Inactive Modules"/>
inactivesCount={inactives.length} <ListGroupItem />
tileLabel={tileLabel}
/>
<ListGroupItem
activeProfiles={actives}
inactiveProfiles={inactives}
/>
</section> </section>
</div> </div>
) )

@ -0,0 +1,14 @@
import React, { createContext } from 'react'
import { PluginManagerContextProviderProps } from '../../types'
export const PluginManagerContext = createContext<Partial<PluginManagerContextProviderProps>>({})
function PluginManagerContextProvider ({ children, props }) {
return (
<PluginManagerContext.Provider value={props}>
{children}
</PluginManagerContext.Provider>
)
}
export default PluginManagerContextProvider

@ -1,91 +1,20 @@
import React, { createContext, useEffect, useState } from 'react' import React from 'react'
import { Profile, TileLabel } from '../customTypes' import { RemixUiPluginManagerProps } from '../types'
import { RemixAppManager, RemixEngine, _Paq } from '../types'
import RootView from './components/rootView' import RootView from './components/rootView'
import PluginManagerContextProvider from './contexts/pluginmanagercontext'
import './remix-ui-plugin-manager.css' import './remix-ui-plugin-manager.css'
/* eslint-disable-next-line */
export interface PluginManagerContextProviderProps {
appManager: RemixAppManager
engine: RemixEngine
_paq: _Paq
filter: string
actives: Profile[]
inactives: Profile[]
activatePlugin: (name: string) => void
deActivatePlugin: (name: string) => void
isActive: (name: string) => any
openLocalPlugin: () => Promise<void>
filterPlugins: () => void
profile: Profile
tileLabel: TileLabel
}
export interface RemixUiPluginManagerProps {
appManager: RemixAppManager
engine: RemixEngine
_paq: _Paq
filter: string
actives: Profile[]
inactives: Profile[]
activatePlugin: (name: string) => void
deActivatePlugin: (name: string) => void
isActive: (name: string) => any
openLocalPlugin: () => Promise<void>
filterPlugins: () => void
profile: Profile
tileLabel: TileLabel
}
export const PluginManagerContext = createContext<Partial<PluginManagerContextProviderProps>>({})
function PluginManagerContextProvider ({ children, props }) {
const [isFiltered] = useState((profile) =>
(profile.displayName ? profile.displayName : profile.name).toLowerCase().includes(props.filter))
const [isNotRequired, setIsNotRequired] = useState<any>()
const [isNotDependent, setIsNotDependent] = useState<any>()
const [isNotHome, setIsNotHome] = useState<any>()
const [sortByName, setSortByName] = useState<any>()
const { actives, inactives } = props.appManager.getAll()
.filter(isFiltered)
.filter(isNotRequired)
.filter(isNotDependent)
.filter(isNotHome)
.sort(sortByName)
.reduce(({ actives, inactives }, profile) => {
return props.isActive(profile.name)
? { actives: [...actives, profile], inactives }
: { inactives: [...inactives, profile], actives }
}, { actives: [], inactives: [] })
props.actives = actives
props.inactives = inactives
useEffect(() => {
const notRequired = (profile: Profile) => !props.appManager.isRequired(profile.name)
const notDependent = (profile) => !props.appManager.isDependent(profile.name)
const notHome = (profile) => profile.name !== 'home'
const sortedByName = (profileA: Profile, profileB: Profile) => {
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
}
setIsNotRequired(notRequired(props.profile))
setIsNotDependent(notDependent(notDependent))
setIsNotHome(notHome)
setSortByName(sortedByName)
}, [props.appManager, props.profile])
return (
<PluginManagerContext.Provider value={...props}>
{children}
</PluginManagerContext.Provider>
)
}
export const RemixUiPluginManager = (props: RemixUiPluginManagerProps) => { export const RemixUiPluginManager = (props: RemixUiPluginManagerProps) => {
console.log('current state of appmanager', props.appManager)
return ( return (
<PluginManagerContextProvider props> // <PluginManagerContextProvider props={props}>
<RootView // <RootView
localPluginButtonText="Connect to a Local Plugin" // localPluginButtonText="Connect to a Local Plugin"
/> // />
// </PluginManagerContextProvider>
<PluginManagerContextProvider props={props}>
<h3 className="h3">Remix UI Plugin Manager React</h3>
<RootView localPluginButtonText="Local Plugin"/>
</PluginManagerContextProvider> </PluginManagerContextProvider>
) )
} }

@ -60,6 +60,42 @@ export class RemixAppManager extends PluginManager {
isRequired(name: any): any; isRequired(name: any): any;
registeredPlugins(): Promise<any>; registeredPlugins(): Promise<any>;
} }
export interface PluginManagerContextProviderProps {
appManager: RemixAppManager
engine: RemixEngine
_paq: _Paq
filter: string
actives: Profile[]
inactives: Profile[]
activatePlugin: (name: string) => void
deActivatePlugin: (name: string) => void
isActive: (name: string) => any
openLocalPlugin: () => Promise<void>
filterPlugins: () => void
profile: Profile
inactivesCount: number
activesCount: number
headingLabel: string
}
export interface RemixUiPluginManagerProps {
appManager: RemixAppManager
engine: RemixEngine
_paq: _Paq
filter: string
actives: Profile[]
inactives: Profile[]
activatePlugin: (name: string) => void
deActivatePlugin: (name: string) => void
isActive: (name: string) => any
openLocalPlugin: () => Promise<void>
filterPlugins: () => void
profile: Profile
inactivesCount: number
activesCount: number
headingLabel: string
}
/** @class Reference loaders. /** @class Reference loaders.
* A loader is a get,set based object which load a workspace from a defined sources. * A loader is a get,set based object which load a workspace from a defined sources.
* (localStorage, queryParams) * (localStorage, queryParams)

Loading…
Cancel
Save