fixing panels

pull/1857/head
filip mertens 3 years ago
parent 7796641e81
commit 31349c9410
  1. 61
      apps/remix-ide/src/app/components/main-panel.js
  2. 56
      apps/remix-ide/src/app/components/main-panel.tsx
  3. 48
      apps/remix-ide/src/app/components/panel.ts
  4. 2
      apps/remix-ide/src/app/components/plugin-manager-component.js
  5. 28
      apps/remix-ide/src/app/components/side-panel.tsx
  6. 1
      apps/remix-ide/tsconfig.json
  7. 2
      libs/remix-ui/main-panel/src/lib/remix-ui-main-panel.tsx
  8. 2
      libs/remix-ui/side-panel/src/index.ts
  9. 26
      libs/remix-ui/side-panel/src/lib/panel-plugin.tsx
  10. 74
      libs/remix-ui/side-panel/src/lib/remix-ui-side-panel.tsx
  11. 29
      libs/remix-ui/side-panel/src/lib/side/panel-header.tsx
  12. 35
      libs/remix-ui/side-panel/src/lib/side/panel.css
  13. 27
      libs/remix-ui/side-panel/src/lib/side/remix-ui-panel.tsx
  14. 16
      libs/remix-ui/side-panel/src/lib/sidepanel-element.tsx
  15. 7
      libs/remix-ui/side-panel/src/lib/types/index.ts

@ -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(
<RemixUiMainPanel
plugin={this} contents={this.contents}
/>,
this.mainelement
)
}
}

@ -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(<RemixUiSidePanel plugins={this.plugins}/>, this.element)
}
}

@ -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<string, PluginRecord> = {}
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) {

@ -96,7 +96,7 @@ class PluginManagerComponent extends ViewPlugin {
}
render () {
return <div>test</div>
return this.htmlElement
}
getAndFilterPlugins (filter) {

@ -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(
<RemixUiSidePanel
plugin={this} contents={this.contents}
/>
,
this.sideelement
)
ReactDOM.render(<RemixUiSidePanel plugins={this.plugins}/>, this.sideelement)
}
}

@ -4,6 +4,7 @@
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"]
},

@ -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]

@ -1 +1 @@
export * from './lib/remix-ui-side-panel';
export { default as RemixUiSidePanel } from './lib/side/remix-ui-panel';

@ -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<JSX.Element | HTMLDivElement>()
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 <div className={props.pluginRecord.active? 'plugItIn active':'d-none'} ref={sidePanelRef}>{view}</div>
}
export default PanelPlugin

@ -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<boolean>(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 (
<header className='swapitHeader'>
<h6 className="swapitTitle" data-id="sidePanelSwapitTitle">{name}</h6>
{dockLink ? (<a href={profileDocsLink} className="titleInfo" title="link to documentation" target="_blank" rel="noreferrer"><i aria-hidden="true" className="fas fa-book"></i></a>) : ''}
{versionWarning ? (<small title="Version Alpha" className="badge-light versionBadge">alpha</small>) : null}
{versionWarningBeta ? (<small title="Version Beta" className="badge-light versionBadge">beta</small>) : null}
</header>
)
}
return (
<section className='panel plugin-manager'>
{renderHeader()}
<div className="pluginsContainer">
{Object.values(props.contents).map((x) => {
if (React.isValidElement(x)) {
return x
} else {
return <SidePanelElement render={x} />
}
})}
</div>
</section>
);
}
export default RemixUiSidePanel;

@ -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<string, PluginRecord>;
}
const SidePanelHeader = (props: RemixUiSidePanelProps) => {
const [plugin, setPlugin] = useState<PluginRecord>()
useEffect(() => {
if (props.plugins) {
const p = Object.values(props.plugins).find((pluginRecord) => {
return pluginRecord.active === true
})
setPlugin(p)
}
}, [props])
return (
<header data-id='sidePanelSwapitTitle' className='swapitHeader'><h6>{plugin?.profile.displayName || plugin?.profile.name}</h6>
{plugin?.profile.documentation ? (<a href={plugin.profile.documentation} className="titleInfo" title="link to documentation" target="_blank" rel="noreferrer"><i aria-hidden="true" className="fas fa-book"></i></a>) : ''}
</header>)
}
export default SidePanelHeader

@ -5,6 +5,7 @@
flex-direction: column;
flex: auto;
}
.swapitTitle {
margin: 0;
text-transform: uppercase;
@ -12,27 +13,34 @@
overflow: hidden;
text-overflow: ellipsis;
}
.swapitTitle i {
padding-left: 6px;
font-size: 14px;
}
.swapitHeader {
display: flex;
align-items: center;
padding: 16px 24px 15px;
justify-content: space-between;
text-transform: uppercase;
}
.icons i {
height: 80%;
cursor: pointer;
}
.pluginsContainer {
height: 100%;
overflow-y: auto;
}
.titleInfo {
padding-left: 10px;
}
.versionBadge {
background-color: var(--light);
padding: 0 7px;
@ -41,7 +49,34 @@
text-transform: lowercase;
cursor: default;
}
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;
}

@ -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<string, PluginRecord>;
}
export function RemixUiSidePanel(props: RemixUiSidePanelProps) {
return (
<div className='panel plugin-manager'>
<SidePanelHeader plugins={props.plugins}></SidePanelHeader>
<div className="pluginsContainer">
{Object.values(props.plugins).map((pluginRecord) => {
return <PanelPlugin pluginRecord={pluginRecord} />
})}
</div>
</div>
);
}
export default RemixUiSidePanel;

@ -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 <div ref={sidePanelRef}></div>
}
export default SidePanelElement

@ -0,0 +1,7 @@
import { Profile } from "@remixproject/plugin-utils";
export type PluginRecord = {
profile: Profile
view: any
active: boolean
}
Loading…
Cancel
Save