diff --git a/apps/remix-ide/src/app/components/main-panel.js b/apps/remix-ide/src/app/components/main-panel.js deleted file mode 100644 index f1568228db..0000000000 --- a/apps/remix-ide/src/app/components/main-panel.js +++ /dev/null @@ -1,61 +0,0 @@ -/* global Node, requestAnimationFrame */ // eslint-disable-line -import React from 'react' // eslint-disable-line -import ReactDOM from 'react-dom' // eslint-disable-line -import { RemixUiMainPanel } from '@remix-ui/main-panel' // eslint-disable-line -import { AbstractPanel } from './panel' -import * as packageJson from '../../../../../package.json' - -const profile = { - name: 'mainPanel', - displayName: 'Main Panel', - description: '', - version: packageJson.version, - methods: ['addView', 'removeView'] -} - -export class MainPanel extends AbstractPanel { - constructor (config) { - super(profile) - this.mainelement = document.createElement('div') - this.mainelement.setAttribute('class', 'mainPanelPluginsContainer') - this.config = config - } - - onActivation () { - this.renderComponent() - } - - focus (name) { - this.emit('focusChanged', name) - super.focus(name) - this.renderComponent() - } - - addView (profile, view) { - super.addView(profile, view) - view.style.height = '100%' - this.renderComponent() - } - - removeView (profile) { - super.removeView(profile) - this.renderComponent() - } - - onActivation () { - this.renderComponent() - } - - render () { - return this.mainelement - } - - renderComponent () { - ReactDOM.render( - , - this.mainelement - ) - } -} diff --git a/apps/remix-ide/src/app/components/main-panel.tsx b/apps/remix-ide/src/app/components/main-panel.tsx new file mode 100644 index 0000000000..8dcf187fff --- /dev/null +++ b/apps/remix-ide/src/app/components/main-panel.tsx @@ -0,0 +1,56 @@ +import React from 'react' // eslint-disable-line +import { AbstractPanel } from './panel' +import ReactDOM from 'react-dom' // eslint-disable-line +import { RemixUiSidePanel } from '@remix-ui/side-panel' +import packageJson from '../../../../../package.json' + +const profile = { + name: 'mainPanel', + displayName: 'Main Panel', + description: '', + version: packageJson.version, + methods: ['addView', 'removeView'] +} + +export class MainPanel extends AbstractPanel { + element: HTMLDivElement + constructor (config) { + super(profile) + this.element = document.createElement('div') + this.element.setAttribute('class', 'mainPanelPluginsContainer') + // this.config = config + } + + onActivation () { + this.renderComponent() + } + + focus (name) { + this.emit('focusChanged', name) + super.focus(name) + this.renderComponent() + } + + addView (profile, view) { + super.addView(profile, view) + this.renderComponent() + } + + removeView (profile) { + super.removeView(profile) + this.renderComponent() + } + + async showContent (name) { + super.showContent(name) + this.renderComponent() + } + + render () { + return this.element + } + + renderComponent () { + ReactDOM.render(, this.element) + } +} diff --git a/apps/remix-ide/src/app/components/panel.js b/apps/remix-ide/src/app/components/panel.ts similarity index 56% rename from apps/remix-ide/src/app/components/panel.js rename to apps/remix-ide/src/app/components/panel.ts index 8ba0df1d1d..a84c0d5e99 100644 --- a/apps/remix-ide/src/app/components/panel.js +++ b/apps/remix-ide/src/app/components/panel.ts @@ -1,23 +1,44 @@ import React from 'react' // eslint-disable-line import { EventEmitter } from 'events' -const EventManager = require('../../lib/events') +import { VerticalIcons } from 'libs/remix-ui/vertical-icons-panel/types/vertical-icons-panel' import { HostPlugin } from '@remixproject/engine-web' // eslint-disable-line +import { Profile } from '@remixproject/plugin-utils' +const EventManager = require('../../lib/events') + /** Abstract class used for hosting the view of a plugin */ +type PluginRecord = { + profile: Profile + view: any + active: boolean +} export class AbstractPanel extends HostPlugin { + + events: EventEmitter + event: any + verticalIcons: VerticalIcons + public plugins: Record = {} constructor (profile) { super(profile) this.events = new EventEmitter() this.event = new EventManager() - this.contents = {} - this.active = undefined + } + + currentFocus (): string { + return Object.values(this.plugins).find(plugin => { + return plugin.active + }).profile.name } addView (profile, view) { console.log(profile, view) - if (this.contents[profile.name]) throw new Error(`Plugin ${profile.name} already rendered`) - this.contents[profile.name] = view - //this.contents[profile.name].style.display = 'none' + if (this.plugins[profile.name]) throw new Error(`Plugin ${profile.name} already rendered`) + this.plugins[profile.name] = { + profile: profile, + view: view, + active: false + } + console.log(this.plugins) } removeView (profile) { @@ -31,9 +52,7 @@ export class AbstractPanel extends HostPlugin { * @param {String} name The name of the plugin to remove */ remove (name) { - const el = this.contents[name] - delete this.contents[name] - if (name === this.active) this.active = undefined + delete this.plugins[name] } /** @@ -41,16 +60,21 @@ export class AbstractPanel extends HostPlugin { * @param {String} name The name of the plugin to display the content */ showContent (name) { - if (!this.contents[name]) throw new Error(`Plugin ${name} is not yet activated`) + if (!this.plugins[name]) throw new Error(`Plugin ${name} is not yet activated`) // hiding the current view and display the `moduleName` + /* if (this.active) { this.contents[this.active].style.display = 'none' } this.contents[name].style.display = 'flex' this.contents[name].style.paddingTop = '20%' this.contents[name].style.flexDirection = 'column' - - this.active = name + */ + Object.values(this.plugins).forEach(plugin => { + plugin.active = false + }) + this.plugins[name].active = true + console.log(this.plugins) } focus (name) { 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 f877e62e8e..e86a62da92 100644 --- a/apps/remix-ide/src/app/components/plugin-manager-component.js +++ b/apps/remix-ide/src/app/components/plugin-manager-component.js @@ -96,7 +96,7 @@ class PluginManagerComponent extends ViewPlugin { } render () { - return test + return this.htmlElement } getAndFilterPlugins (filter) { diff --git a/apps/remix-ide/src/app/components/side-panel.js b/apps/remix-ide/src/app/components/side-panel.tsx similarity index 73% rename from apps/remix-ide/src/app/components/side-panel.js rename to apps/remix-ide/src/app/components/side-panel.tsx index 1ec66c16cf..d3a800d8d1 100644 --- a/apps/remix-ide/src/app/components/side-panel.js +++ b/apps/remix-ide/src/app/components/side-panel.tsx @@ -1,8 +1,10 @@ import React from 'react' // eslint-disable-line import { AbstractPanel } from './panel' import ReactDOM from 'react-dom' // eslint-disable-line -import { RemixUiSidePanel } from '@remix-ui/side-panel' // eslint-disable-line -import * as packageJson from '../../../../../package.json' +import { RemixUiSidePanel } from '@remix-ui/side-panel' +import packageJson from '../../../../../package.json' +import { RemixAppManager } from '../../remixAppManager' +import { VerticalIcons } from 'libs/remix-ui/vertical-icons-panel/types/vertical-icons-panel' // const csjs = require('csjs-inject') const sidePanel = { @@ -15,16 +17,19 @@ const sidePanel = { // TODO merge with vertical-icons.js export class SidePanel extends AbstractPanel { - constructor (appManager, verticalIcons) { + appManager: RemixAppManager + sideelement: HTMLDivElement + verticalIcons: VerticalIcons; + constructor (appManager: RemixAppManager, verticalIcons: VerticalIcons) { super(sidePanel) this.appManager = appManager - this.sideelement = document.createElement('span') + this.sideelement = document.createElement('div') this.verticalIcons = verticalIcons // Toggle content verticalIcons.events.on('toggleContent', (name) => { - if (!this.contents[name]) return - if (this.active === name) { + if (!this.plugins[name]) return + if (this.plugins[name].active) { // TODO: Only keep `this.emit` (issue#2210) this.emit('toggle', name) this.events.emit('toggle', name) @@ -37,7 +42,7 @@ export class SidePanel extends AbstractPanel { }) // Force opening verticalIcons.events.on('showContent', (name) => { - if (!this.contents[name]) return + if (!this.plugins[name]) return this.showContent(name) // TODO: Only keep `this.emit` (issue#2210) this.emit('showing', name) @@ -74,6 +79,7 @@ export class SidePanel extends AbstractPanel { async showContent (name) { super.showContent(name) this.emit('focusChanged', name) + this.renderComponent() } render () { @@ -82,12 +88,6 @@ export class SidePanel extends AbstractPanel { renderComponent () { console.log('render side panel') - ReactDOM.render( - - , - this.sideelement - ) + ReactDOM.render(, this.sideelement) } } diff --git a/apps/remix-ide/tsconfig.json b/apps/remix-ide/tsconfig.json index b32eb87bd7..6a9d252c2d 100644 --- a/apps/remix-ide/tsconfig.json +++ b/apps/remix-ide/tsconfig.json @@ -4,6 +4,7 @@ "jsx": "react", "allowJs": true, "esModuleInterop": true, + "resolveJsonModule": true, "allowSyntheticDefaultImports": true, "types": ["node", "jest"] }, diff --git a/libs/remix-ui/main-panel/src/lib/remix-ui-main-panel.tsx b/libs/remix-ui/main-panel/src/lib/remix-ui-main-panel.tsx index dd3cd5820b..e52f84322a 100644 --- a/libs/remix-ui/main-panel/src/lib/remix-ui-main-panel.tsx +++ b/libs/remix-ui/main-panel/src/lib/remix-ui-main-panel.tsx @@ -1,7 +1,5 @@ import React, { useEffect, useState, useRef } from 'react' // eslint-disable-line import './remix-ui-main-panel.module.css'; - -/* eslint-disable-next-line */ export interface RemixUiMainPanelProps { plugin: any contents: [any] diff --git a/libs/remix-ui/side-panel/src/index.ts b/libs/remix-ui/side-panel/src/index.ts index d45ee2522b..b51d7e9428 100644 --- a/libs/remix-ui/side-panel/src/index.ts +++ b/libs/remix-ui/side-panel/src/index.ts @@ -1 +1 @@ -export * from './lib/remix-ui-side-panel'; +export { default as RemixUiSidePanel } from './lib/side/remix-ui-panel'; diff --git a/libs/remix-ui/side-panel/src/lib/panel-plugin.tsx b/libs/remix-ui/side-panel/src/lib/panel-plugin.tsx new file mode 100644 index 0000000000..7ca3da18bc --- /dev/null +++ b/libs/remix-ui/side-panel/src/lib/panel-plugin.tsx @@ -0,0 +1,26 @@ +import React, { useEffect, useRef, useState } from 'react' // eslint-disable-line +import { PluginRecord } from './types' +import './side/panel.css'; +interface panelPLuginProps { + pluginRecord: PluginRecord +} + +const PanelPlugin = (props: panelPLuginProps) => { + const sidePanelRef = useRef(null) + const [view, setView] = useState() + useEffect(() => { + if (sidePanelRef.current) { + if (props.pluginRecord.view) { + if (React.isValidElement(props.pluginRecord.view)) { + setView(props.pluginRecord.view) + }else{ + sidePanelRef.current.appendChild(props.pluginRecord.view) + } + } + } + }, []) + + return {view} +} + +export default PanelPlugin \ No newline at end of file diff --git a/libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.tsx b/libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.tsx deleted file mode 100644 index 797a510a58..0000000000 --- a/libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import React, { useEffect, useState } from 'react' // eslint-disable-line -import './remix-ui-side-panel.module.css'; -import SidePanelElement from './sidepanel-element'; - -/* eslint-disable-next-line */ -export interface RemixUiSidePanelProps { - plugin: any - contents: any -} - -export function RemixUiSidePanel(props: RemixUiSidePanelProps) { - const [view, setView] = useState('') - const [dockLink, setDockLink] = useState(false) - const [versionWarning, setVersionWarning] = useState(false) - const [versionWarningBeta, setVersionWarningBeta] = useState(false) - const [profile, setProfile] = useState('') - const [profileDocsLink, setProfileDocsLink] = useState('') - const [name, setName] = useState(' - ') - - useEffect(() => { - console.log('load') - }, []) - - const getProfile = async () => { - console.log({ active: props.plugin.active }) - if (props.plugin.active) { - const profile = await props.plugin.appManager.getProfile(props.plugin.active) - setProfileDocsLink(profile.documentation) - profile.displayName ? setName(profile.displayName) : setName(profile.name) - profile.documentation ? setDockLink(true) : setDockLink(false) - if (profile.version && profile.version.match(/\b(\w*alpha\w*)\b/g)) { - setVersionWarning(true) - } else { - setVersionWarning(false) - } - // Beta - if (profile.version && profile.version.match(/\b(\w*beta\w*)\b/g)) { - setVersionWarningBeta(true) - } else { - setVersionWarningBeta(false) - } - } - } - - const renderHeader = () => { - getProfile() - return ( - - {name} - {dockLink ? () : ''} - {versionWarning ? (alpha) : null} - {versionWarningBeta ? (beta) : null} - - ) - } - - return ( - - {renderHeader()} - - {Object.values(props.contents).map((x) => { - if (React.isValidElement(x)) { - return x - } else { - return - } - })} - - - - ); -} - -export default RemixUiSidePanel; diff --git a/libs/remix-ui/side-panel/src/lib/side/panel-header.tsx b/libs/remix-ui/side-panel/src/lib/side/panel-header.tsx new file mode 100644 index 0000000000..dc562b8fdd --- /dev/null +++ b/libs/remix-ui/side-panel/src/lib/side/panel-header.tsx @@ -0,0 +1,29 @@ +/* eslint-disable jsx-a11y/anchor-has-content */ +import React, { useEffect, useRef, useState } from 'react' // eslint-disable-line +import { PluginRecord } from '../types'; +import './panel.css'; + +export interface RemixUiSidePanelProps { + plugins: Record; + } +const SidePanelHeader = (props: RemixUiSidePanelProps) => { + const [plugin, setPlugin] = useState() + + useEffect(() => { + if (props.plugins) { + const p = Object.values(props.plugins).find((pluginRecord) => { + return pluginRecord.active === true + }) + setPlugin(p) + } + + + }, [props]) + + return ( + {plugin?.profile.displayName || plugin?.profile.name} + {plugin?.profile.documentation ? () : ''} + ) +} + +export default SidePanelHeader \ No newline at end of file diff --git a/libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.module.css b/libs/remix-ui/side-panel/src/lib/side/panel.css similarity index 57% rename from libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.module.css rename to libs/remix-ui/side-panel/src/lib/side/panel.css index 018a752156..54bef7aa84 100644 --- a/libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.module.css +++ b/libs/remix-ui/side-panel/src/lib/side/panel.css @@ -4,44 +4,79 @@ display: flex; flex-direction: column; flex: auto; - } - .swapitTitle { +} + +.swapitTitle { margin: 0; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - } - .swapitTitle i{ +} + +.swapitTitle i { padding-left: 6px; font-size: 14px; - } - .swapitHeader { +} + +.swapitHeader { display: flex; align-items: center; padding: 16px 24px 15px; justify-content: space-between; - } - .icons i { + text-transform: uppercase; +} + +.icons i { height: 80%; cursor: pointer; - } - .pluginsContainer { +} + +.pluginsContainer { height: 100%; overflow-y: auto; - } - .titleInfo { +} + +.titleInfo { padding-left: 10px; - } - .versionBadge { +} + +.versionBadge { background-color: var(--light); padding: 0 7px; font-weight: bolder; margin-left: 5px; text-transform: lowercase; cursor: default; - } - iframe { +} + +iframe { + height: 100%; + width: 100%; + border: 0; +} + +.plugins { + height: 100%; +} + +.plugItIn { + display: none; + height: 100%; +} + +.plugItIn>div { + overflow-y: auto; + overflow-x: hidden; height: 100%; - } + width: 100%; +} +.plugItIn.active { + display: block; +} + +.pluginsContainer { + height: 100%; + overflow-y: hidden; +} \ No newline at end of file diff --git a/libs/remix-ui/side-panel/src/lib/side/remix-ui-panel.tsx b/libs/remix-ui/side-panel/src/lib/side/remix-ui-panel.tsx new file mode 100644 index 0000000000..71d701e9eb --- /dev/null +++ b/libs/remix-ui/side-panel/src/lib/side/remix-ui-panel.tsx @@ -0,0 +1,27 @@ +import React, { useEffect, useState } from 'react' // eslint-disable-line +import './panel.css'; +import SidePanelHeader from './panel-header'; +import PanelPlugin from '../panel-plugin'; +import { PluginRecord } from '../types'; + +/* eslint-disable-next-line */ +export interface RemixUiSidePanelProps { + plugins: Record; +} + +export function RemixUiSidePanel(props: RemixUiSidePanelProps) { + + return ( + + + + {Object.values(props.plugins).map((pluginRecord) => { + return + })} + + + + ); +} + +export default RemixUiSidePanel; diff --git a/libs/remix-ui/side-panel/src/lib/sidepanel-element.tsx b/libs/remix-ui/side-panel/src/lib/sidepanel-element.tsx deleted file mode 100644 index 8b43d0f35c..0000000000 --- a/libs/remix-ui/side-panel/src/lib/sidepanel-element.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react' // eslint-disable-line - -const SidePanelElement = (props: any) => { - const sidePanelRef = useRef(null) - useEffect(() => { - if (sidePanelRef.current) { - if (props.render) { - sidePanelRef.current.appendChild(props.render) - } - } - }, []) - - return -} - -export default SidePanelElement \ No newline at end of file diff --git a/libs/remix-ui/side-panel/src/lib/types/index.ts b/libs/remix-ui/side-panel/src/lib/types/index.ts new file mode 100644 index 0000000000..ec4fd1456a --- /dev/null +++ b/libs/remix-ui/side-panel/src/lib/types/index.ts @@ -0,0 +1,7 @@ +import { Profile } from "@remixproject/plugin-utils"; + +export type PluginRecord = { + profile: Profile + view: any + active: boolean + } \ No newline at end of file