diff --git a/apps/remix-ide/src/app/components/plugin-manager-component.js b/apps/remix-ide/src/app/components/plugin-manager-component.js index c0ee59c73f..f3f95bd568 100644 --- a/apps/remix-ide/src/app/components/plugin-manager-component.js +++ b/apps/remix-ide/src/app/components/plugin-manager-component.js @@ -102,7 +102,7 @@ class PluginManagerComponent extends ViewPlugin { // root: null, // items: {} // } - // this.localPlugin = new LocalPlugin() + this.localPlugin = new LocalPlugin() // this.filter = '' // this.appManager.event.on('activate', () => { this.reRender() }) // this.appManager.event.on('deactivate', () => { this.reRender() }) @@ -130,27 +130,12 @@ class PluginManagerComponent extends ViewPlugin { } renderComponent () { - // const props = this.reactProps() ReactDOM.render( - // , false} actives={[]} inactives={[]} @@ -172,81 +157,28 @@ class PluginManagerComponent extends ViewPlugin { // _paq.push(['trackEvent', 'manager', 'deactivate', name]) // } - // renderItem (profile) { - // const displayName = (profile.displayName) ? profile.displayName : profile.name - // const doclink = profile.documentation ? yo`` - // : yo`` - - // // Check version of the plugin - // let versionWarning - // // Alpha - // if (profile.version && profile.version.match(/\b(\w*alpha\w*)\b/g)) { - // versionWarning = yo`alpha` - // } - // // Beta - // if (profile.version && profile.version.match(/\b(\w*beta\w*)\b/g)) { - // versionWarning = yo`beta` - // } - - // const activationButton = this.isActive(profile.name) - // ? yo` - // - // ` - // : yo` - // ` - - // return yo` - //
- //
- //
- //
- // ${displayName} - // ${doclink} - // ${versionWarning} - //
- // ${activationButton} - //
- //
- //
- // - // ${profile.description} - //
- //
- // ` - // } - /*************** * SUB-COMPONENT */ /** * Add a local plugin to the list of plugins */ - // async openLocalPlugin () { - // try { - // const profile = await this.localPlugin.open(this.appManager.getAll()) - // if (!profile) return - // if (this.appManager.getIds().includes(profile.name)) { - // throw new Error('This name has already been used') - // } - // const plugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile) - // this.engine.register(plugin) - // await this.appManager.activatePlugin(plugin.name) - // } catch (err) { - // // TODO : Use an alert to handle this error instead of a console.log - // console.log(`Cannot create Plugin : ${err.message}`) - // addToolTip(`Cannot create Plugin : ${err.message}`) - // } - // } + async openLocalPlugin () { + try { + const profile = await this.localPlugin.open(this.appManager.getAll()) + if (!profile) return + if (this.appManager.getIds().includes(profile.name)) { + throw new Error('This name has already been used') + } + const plugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile) + this.engine.register(plugin) + await this.appManager.activatePlugin(plugin.name) + } catch (err) { + // TODO : Use an alert to handle this error instead of a console.log + console.log(`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) @@ -280,48 +212,6 @@ class PluginManagerComponent extends ViewPlugin { render () { // Filtering helpers - - // const activeTile = actives.length !== 0 - // ? yo` - // - // ` - // : '' - // const inactiveTile = inactives.length !== 0 - // ? yo` - // - // ` - // : '' - - // const settings = new PluginManagerSettings().render() - - // const rootView = yo` - //
- //
- // - // - //
- //
- // ${activeTile} - //
- // ${actives.map(profile => this.renderItem(profile))} - //
- // ${inactiveTile} - //
- // ${inactives.map(profile => this.renderItem(profile))} - //
- //
- // ${settings} - //
- // ` - // if (!this.views.root) this.views.root = rootView return this.htmlElement } diff --git a/libs/remix-ui/plugin-manager/src/lib/components/localPluginForm.tsx b/libs/remix-ui/plugin-manager/src/lib/components/localPluginForm.tsx new file mode 100644 index 0000000000..8ff0e3e39a --- /dev/null +++ b/libs/remix-ui/plugin-manager/src/lib/components/localPluginForm.tsx @@ -0,0 +1,155 @@ +import React, { FormEvent, MouseEvent, useState } from 'react' +import { FormStateProps } from '../../types' + +interface RadioSelectionformState { + pluginType: string + inputLabel: string + radioLabel: string + radioChecked?: boolean + updateProfile: (key: string, e: MouseEvent) => void +} + +interface LocalPluginFormProps { + formSubmitHandler: (event: FormEvent, formData: FormStateProps) => void +} + +const initialState: FormStateProps = { + name: '', + displayName: '', + url: '', + type: 'iframe', + hash: '', + methods: '', + location: 'sidePanel' +} + +function LocalPluginForm ({ formSubmitHandler }: LocalPluginFormProps) { + const [plugin, setPlugin] = useState(initialState) + // const [name, setName] = useState('') + // const [displayName, setDisplayName] = useState('') + // const [methods, setMethods] = useState('') + // const [url, setUrl] = useState('') + // const [type, setType] = useState() + // const [location, setLocation] = useState() + + function pluginChangeHandler

(formProps: P, value: FormStateProps[P]) { + setPlugin({ ...plugin, [formProps]: value }) + } + + // function handleSubmit (e) { + // console.log('Logging the form submit event', e) + // console.log('state of the plugin', plugin) + // } + + // const onValueChange = (event: any) => { + // const value = event.target.type === 'radio' ? event.target.checked : event.target.value + // const name = event.target.name + // if (name === 'name') { + // setName(value) + // } else if (name === 'displayName') { + // setDisplayName(value) + // } else if (name === 'methods') { + // setMethods(value) + // } else if (name === 'url') { + // setUrl(value) + // } else if (name === 'type') { + // setType(value) + // } else if (name === 'location') { + // setLocation(value) + // } + // } + return ( +

formSubmitHandler(e, plugin)}> +
+ + pluginChangeHandler('name', e.target.value)} value={plugin.name} id="plugin-name" data-id="localPluginName" placeholder="Should be camelCase"/> +
+
+ + pluginChangeHandler('displayName', e.target.value)} value={plugin.displayName} id="plugin-displayname" data-id="localPluginDisplayName" placeholder="Name in the header"/> +
+
+ + pluginChangeHandler('methods', e.target.value)} value={plugin.methods} id="plugin-methods" data-id="localPluginMethods" placeholder="Name in the header"/> +
+ +
+ + pluginChangeHandler('url', e.target.value)} value={plugin.url} id="plugin-url" data-id="localPluginUrl" placeholder="ex: https://localhost:8000" /> +
+
Type of connection (required)
+
+
+ pluginChangeHandler('type', e.target.value)} + /> + +
+
+ pluginChangeHandler('type', e.target.value)} + /> + +
+
+
Location in remix (required)
+
+
+ pluginChangeHandler('location', e.target.value)} + /> + +
+
+ pluginChangeHandler('location', e.target.value)} + /> + +
+
+ pluginChangeHandler('location', e.target.value)} + /> + +
+
+
+ ) +} + +export default LocalPluginForm diff --git a/libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx b/libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx index 491ab46689..e17ea7b594 100644 --- a/libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx +++ b/libs/remix-ui/plugin-manager/src/lib/components/pluginCard.tsx @@ -1,9 +1,10 @@ import React, { useContext, useState } from 'react' +import { Profile } from '../../types' import { PluginManagerContext } from '../contexts/pluginmanagercontext' import '../remix-ui-plugin-manager.css' import Button from './button' interface PluginCardProps { - profile: any + profile: Partial } // eslint-disable-next-line no-empty-pattern diff --git a/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx b/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx index ee52b5547b..8b9c19139b 100644 --- a/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx +++ b/libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx @@ -1,7 +1,10 @@ -import React, { Fragment, useContext } from 'react' +import React, { FormEvent, Fragment, useContext, useState } from 'react' import { PluginManagerContext } from '../contexts/pluginmanagercontext' import ModuleHeading from './moduleHeading' import PluginCard from './pluginCard' +import { ModalDialog } from '@remix-ui/modal-dialog' +import LocalPluginForm from './localPluginForm' +import { FormStateProps } from '../../types' interface RootViewProps { localPluginButtonText: string @@ -9,33 +12,62 @@ interface RootViewProps { function RootView ({ localPluginButtonText }: RootViewProps) { const { actives, inactives } = useContext(PluginManagerContext) + const [visible, setVisible] = useState(true) + + const openModal = () => { + setVisible(false) + } + + const closeModal = () => setVisible(true) + + const handleSubmit = (evt: FormEvent, formData: FormStateProps) => { + console.log('Data submitted from the form!!!: ', formData) + evt.preventDefault() + closeModal() + } + return ( -
-
- - -
-
- {actives.length === 0 ? ( - - - {actives.map((profile) => ( - - ))} - - ) : null } - {inactives.length === 0 ? ( - - - {inactives.map((profile) => ( - - ))} - - ) : null} -
-
+ + +
+ {actives.length === 0 ? ( + + + {actives.map((profile) => ( + + ))} + + ) : null } + {inactives.length === 0 ? ( + + + {inactives.map((profile) => ( + + ))} + + ) : null} +
+ + ) } diff --git a/libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx b/libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx index e5a8b17a1b..d98404b662 100644 --- a/libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx +++ b/libs/remix-ui/plugin-manager/src/lib/remix-ui-plugin-manager.tsx @@ -7,12 +7,25 @@ import './remix-ui-plugin-manager.css' export const RemixUiPluginManager = (props: RemixUiPluginManagerProps) => { console.log('current state of appmanager', props.appManager) console.log('The state of props ', props) + + // openLocalPlugin () { + // try { + // const profile = await props.localPlugin.open(props.appManager.getAll()) + // if (!profile) return + // if (props.appManager.getIds().includes(profile.name)) { + // throw new Error('This name has already been used') + // } + // const plugin = profile.type === 'iframe' ? new IframePlugin(profile) : new WebsocketPlugin(profile) + // props.engine.register(plugin) + // await props.appManager.activatePlugin(plugin.name) + // } catch (err) { + // // TODO : Use an alert to handle this error instead of a console.log + // console.log(`Cannot create Plugin : ${err.message}`) + // addToolTip(`Cannot create Plugin : ${err.message}`) + // } + // } + return ( - // - // - // diff --git a/libs/remix-ui/plugin-manager/src/types.d.ts b/libs/remix-ui/plugin-manager/src/types.d.ts index c436908d85..1a954bba74 100644 --- a/libs/remix-ui/plugin-manager/src/types.d.ts +++ b/libs/remix-ui/plugin-manager/src/types.d.ts @@ -4,6 +4,45 @@ import { EventEmitter } from 'events' import { Engine } from '@remixproject/engine/lib/engine' /* 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; @@ -74,14 +113,13 @@ export interface PluginManagerContextProviderProps { openLocalPlugin: () => Promise filterPlugins: () => void profile: Profile - inactivesCount: number - activesCount: number headingLabel: string } export interface RemixUiPluginManagerProps { appManager: RemixAppManager engine: RemixEngine + localPlugin: LocalPlugin _paq: _Paq filter: string actives: Profile[] @@ -92,8 +130,6 @@ export interface RemixUiPluginManagerProps { openLocalPlugin: () => Promise filterPlugins: () => void profile: Profile - inactivesCount: number - activesCount: number headingLabel: string } /** @class Reference loaders. @@ -108,4 +144,59 @@ declare class PluginLoader { set(plugin: any, actives: any): void; get(): any; } + +export type PluginManagerSettings = { + openDialog: () => void + onValidation: () => void + clearPermission: (from: any, to: any, method: any) => void + settings: () => HTMLElement + render: () => HTMLElement +} + +export type LocalPluginType = { + 'iframe', + 'ws' +} + +export type DefaultLocalPlugin = { + type: string + hash: string + methods: any + location: string +} + +export interface FormStateProps extends DefaultLocalPlugin { + name: string + displayName: string + url: string +} + +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 + type: 'iframe' | 'ws' + hash: string +} + +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 +} + export { }