refactor icon component for statusChanged event

pull/1671/head
Joseph Izang 3 years ago
parent 1bb408779e
commit f07d4db897
  1. 2
      apps/remix-ide-e2e/src/tests/debugger.test.ts
  2. 31
      apps/remix-ide/src/app/components/vertical-icons.js
  3. 14
      libs/remix-ui/vertical-icons-panel/src/lib/components/Debugger.tsx
  4. 14
      libs/remix-ui/vertical-icons-panel/src/lib/components/FilePanel.tsx
  5. 125
      libs/remix-ui/vertical-icons-panel/src/lib/components/Icon.tsx
  6. 13
      libs/remix-ui/vertical-icons-panel/src/lib/components/OtherIcons.tsx
  7. 21
      libs/remix-ui/vertical-icons-panel/src/lib/components/PluginManager.tsx
  8. 21
      libs/remix-ui/vertical-icons-panel/src/lib/components/Settings.tsx
  9. 14
      libs/remix-ui/vertical-icons-panel/src/lib/components/Solidity.tsx
  10. 14
      libs/remix-ui/vertical-icons-panel/src/lib/components/SolidityStaticAnalysis.tsx
  11. 14
      libs/remix-ui/vertical-icons-panel/src/lib/components/Udapp.tsx
  12. 10
      libs/remix-ui/vertical-icons-panel/src/lib/reducers/iconReducers.ts
  13. 2
      libs/remix-ui/vertical-icons-panel/types/vertical-icons-panel.d.ts

@ -200,7 +200,7 @@ module.exports = {
browser browser
.addFile('test_jsGetTrace.js', { content: jsGetTrace }) .addFile('test_jsGetTrace.js', { content: jsGetTrace })
.executeScript('remix.exeCurrent()') .executeScript('remix.exeCurrent()')
.pause(1000) .pause(3000)
.waitForElementContainsText('*[data-id="terminalJournal"]', '{"gas":"0x575f","return":"0x0000000000000000000000000000000000000000000000000000000000000000","structLogs":', 60000) .waitForElementContainsText('*[data-id="terminalJournal"]', '{"gas":"0x575f","return":"0x0000000000000000000000000000000000000000000000000000000000000000","structLogs":', 60000)
}, },
// depends on Should debug using generated sources // depends on Should debug using generated sources

@ -33,6 +33,8 @@ export class VerticalIcons extends Plugin {
this.targetProfileForChange = {} this.targetProfileForChange = {}
this.targetProfileForRemoval = {} this.targetProfileForRemoval = {}
this.registry = globalRegistry this.registry = globalRegistry
this.keys = ['succeed', 'edited', 'none', 'loading', 'failed']
this.types = ['error', 'warning', 'success', 'info', '']
} }
renderComponent () { renderComponent () {
@ -62,19 +64,19 @@ export class VerticalIcons extends Plugin {
listenOnStatus (profile) { listenOnStatus (profile) {
// the list of supported keys. 'none' will remove the status // the list of supported keys. 'none' will remove the status
const keys = ['edited', 'succeed', 'none', 'loading', 'failed'] // const keys = ['edited', 'succeed', 'none', 'loading', 'failed']
const types = ['error', 'warning', 'success', 'info', ''] // const types = ['error', 'warning', 'success', 'info', '']
const fn = (status) => { // const fn = (status) => {
if (!types.includes(status.type) && status.type) throw new Error(`type should be ${keys.join()}`) // if (!this.types.includes(status.type) && status.type) throw new Error(`type should be ${this.keys.join()}`)
if (status.key === undefined) throw new Error('status key should be defined') // if (status.key === undefined) throw new Error('status key should be defined')
if (typeof status.key === 'string' && (!keys.includes(status.key))) { // if (typeof status.key === 'string' && (!this.keys.includes(status.key))) {
throw new Error('key should contain either number or ' + keys.join()) // throw new Error('key should contain either number or ' + this.keys.join())
} // }
this.setIconStatus(profile.name, status) // this.setIconStatus(profile.name, status)
} // }
this.iconStatus[profile.name] = fn // this.iconStatus[profile.name] = fn
this.on(profile.name, 'statusChanged', this.iconStatus[profile.name]) // this.on(profile.name, 'statusChanged', this.iconStatus[profile.name])
} }
/** /**
@ -84,6 +86,7 @@ export class VerticalIcons extends Plugin {
*/ */
resolveClasses (key, type) { resolveClasses (key, type) {
let classes = 'remixui_status' let classes = 'remixui_status'
switch (key) { switch (key) {
case 'succeed': case 'succeed':
classes += ' fas fa-check-circle text-' + type + ' ' + 'remixui_statusCheck' classes += ' fas fa-check-circle text-' + type + ' ' + 'remixui_statusCheck'
@ -111,6 +114,8 @@ export class VerticalIcons extends Plugin {
*/ */
setIconStatus (name, status) { setIconStatus (name, status) {
const el = this.icons[name] const el = this.icons[name]
// eslint-disable-next-line no-debugger
debugger
if (!el) return if (!el) return
const statusEl = el.querySelector('i') const statusEl = el.querySelector('i')
if (statusEl) { if (statusEl) {

@ -22,19 +22,7 @@ function Debugger ({ verticalIconsPlugin, itemContextAction, addActive, removeAc
verticalIconsPlugin.targetProfileForChange[p].displayName verticalIconsPlugin.targetProfileForChange[p].displayName
}> }>
<Icon <Icon
kind={verticalIconsPlugin.targetProfileForChange[p].kind} profile={verticalIconsPlugin.targetProfileForChange[p]}
displayName={
verticalIconsPlugin.targetProfileForChange[p].displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={verticalIconsPlugin.targetProfileForChange[p].icon}
name={verticalIconsPlugin.targetProfileForChange[p].name}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -43,19 +43,7 @@ function FilePanel ({ verticalIconsPlugin, itemContextAction, addActive, removeA
ref={filePanelRef} ref={filePanelRef}
> >
<Icon <Icon
kind={verticalIconsPlugin.targetProfileForChange[p].kind} profile={verticalIconsPlugin.targetProfileForChange[p]}
displayName={
verticalIconsPlugin.targetProfileForChange[p].displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={verticalIconsPlugin.targetProfileForChange[p].icon}
name={verticalIconsPlugin.targetProfileForChange[p].name}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -3,36 +3,33 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import VerticalIconsContextMenu from '../vertical-icons-context-menu' import VerticalIconsContextMenu from '../vertical-icons-context-menu'
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import React, { Fragment, SyntheticEvent, useRef, useState } from 'react' import React, { Fragment, SyntheticEvent, useEffect, useRef, useState } from 'react'
import { VerticalIcons } from 'libs/remix-ui/vertical-icons-panel/types/vertical-icons-panel' import { VerticalIcons } from 'libs/remix-ui/vertical-icons-panel/types/vertical-icons-panel'
import * as helper from '../../../../../../apps/remix-ide/src/lib/helper'
interface IconProps { interface IconProps {
verticalIconPlugin: VerticalIcons verticalIconPlugin: VerticalIcons
kind: string // kind: string
name: string // name: string
icon: string // icon: string
displayName: string // displayName: string
tooltip: string // tooltip: string
documentation: string // documentation: string
profile: any
contextMenuAction: (evt: any, profileName: string, documentation: string) => void contextMenuAction: (evt: any, profileName: string, documentation: string) => void
addActive: (profileName: string) => void addActive: (profileName: string) => void
removeActive: () => void removeActive: () => void
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function Icon ({ function Icon ({
// eslint-disable-next-line @typescript-eslint/no-unused-vars profile,
kind,
name,
icon,
displayName,
tooltip,
documentation,
verticalIconPlugin, verticalIconPlugin,
contextMenuAction, contextMenuAction,
addActive, addActive,
removeActive removeActive
}: IconProps) { }: IconProps) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { tooltip, displayName, name, kind, icon, documentation } = profile
const [title] = useState(() => { const [title] = useState(() => {
const temp = tooltip || displayName || name const temp = tooltip || displayName || name
return temp.replace(/^\w/, word => word.toUpperCase()) return temp.replace(/^\w/, word => word.toUpperCase())
@ -47,6 +44,7 @@ function Icon ({
const [showContext, setShowContext] = useState(false) const [showContext, setShowContext] = useState(false)
const [canDeactivate] = useState(false) const [canDeactivate] = useState(false)
const iconRef = useRef<any>(null) const iconRef = useRef<any>(null)
const iconStatusValues = { title: '', key: '', type: '', text: '' }
const handleContextMenu = (e: SyntheticEvent & PointerEvent) => { const handleContextMenu = (e: SyntheticEvent & PointerEvent) => {
const deactivationState = verticalIconPlugin.appManager const deactivationState = verticalIconPlugin.appManager
@ -65,6 +63,94 @@ function Icon ({
setShowContext(false) setShowContext(false)
} }
/**
* resolve a classes list for @arg key
* @param {String} key
* @param {String} type
*/
function resolveClasses (key: string, type: string) {
let classes = 'remixui_status'
switch (key) {
case 'succeed':
classes += ' fas fa-check-circle text-' + type + ' ' + 'remixui_statusCheck'
break
case 'edited':
classes += ' fas fa-sync text-' + type + ' ' + 'remixui_statusCheck'
break
case 'loading':
classes += ' fas fa-spinner text-' + type + ' ' + 'remixui_statusCheck'
break
case 'failed':
classes += ' fas fa-exclamation-triangle text-' + type + ' ' + 'remixui_statusCheck'
break
default: {
classes += ' badge badge-pill badge-' + type
}
}
return classes
}
/**
* Set a new status for the @arg name
* @param {String} name
* @param {Object} status
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function setIconStatus (name: string, status: { key: string | number, title: string, type: string }) {
if (!iconRef.current) return
const statusEl = iconRef.current.querySelector('i')
if (statusEl) {
iconRef.current.removeChild(statusEl)
}
if (status.key === 'none') return // remove status
let text = ''
let key = ''
if (typeof status.key === 'number') {
key = status.key.toString()
text = key
} else key = helper.checkSpecialChars(status.key) ? '' : status.key
let type = ''
if (status.type === 'error') {
type = 'danger' // to use with bootstrap
} else type = helper.checkSpecialChars(status.type) ? '' : status.type
const title = helper.checkSpecialChars(status.title) ? '' : status.title
const icon = document.createElement('i')
icon.title = title
icon.className = resolveClasses(key, type)
icon.ariaHidden = 'true'
const innerText = document.createTextNode(text)
icon.appendChild(innerText)
iconRef.current!.appendChild(icon)
iconRef.current.classList.add('remixui_icon')
}
function listenOnStatus (profile: any) {
function setErrorStatus (status: any) {
if (!verticalIconPlugin.types.includes(status.type) && status.type) throw new Error(`type should be ${verticalIconPlugin.keys.join()}`)
if (status.key === undefined) throw new Error('status key should be defined')
if (typeof status.key === 'string' && (!verticalIconPlugin.keys.includes(status.key))) {
throw new Error('key should contain either number or ' + verticalIconPlugin.keys.join())
}
setIconStatus(profile.name, status)
}
verticalIconPlugin.iconStatus[profile.name] = setErrorStatus
verticalIconPlugin.on(profile.name, 'statusChanged', verticalIconPlugin.iconStatus[profile.name])
}
useEffect(() => {
listenOnStatus(profile)
return () => {
console.log('just listened for status change ', { profile })
addEventListener('statusChanged', (e) => {
console.log('statusChanged just happend for this icon and this is its payload ', e)
})
}
}, [])
return ( return (
<Fragment> <Fragment>
<div <div
@ -94,6 +180,15 @@ function Icon ({
> >
<img className="remixui_image" src={icon} alt={name} /> <img className="remixui_image" src={icon} alt={name} />
</div> </div>
{verticalIconPlugin.iconStatus && Object.keys(verticalIconPlugin.iconStatus).length !== null ? (
<i
title={iconStatusValues.title}
className={resolveClasses(iconStatusValues.key, iconStatusValues.type)}
aria-hidden="true"
>
{iconStatusValues.text}
</i>
) : null }
{showContext ? ( {showContext ? (
<VerticalIconsContextMenu <VerticalIconsContextMenu
pageX={pageX} pageX={pageX}

@ -26,18 +26,7 @@ function OtherIcons ({ verticalIconsPlugin, itemContextAction, addActive, remove
.filter(customFilter) .filter(customFilter)
.map(p => ( .map(p => (
<Icon <Icon
kind={verticalIconsPlugin.targetProfileForChange[p].kind} profile={verticalIconsPlugin.targetProfileForChange[p]}
displayName={
verticalIconsPlugin.targetProfileForChange[p].displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p].documentation
}
icon={verticalIconsPlugin.targetProfileForChange[p].icon}
name={verticalIconsPlugin.targetProfileForChange[p].name}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -18,26 +18,7 @@ function PluginManager ({ verticalIconsPlugin, itemContextAction, addActive, rem
.filter(p => p === 'pluginManager') .filter(p => p === 'pluginManager')
.map(p => ( .map(p => (
<Icon <Icon
kind={ profile={verticalIconsPlugin.targetProfileForChange[p]}
verticalIconsPlugin.targetProfileForChange[p].kind
}
displayName={
verticalIconsPlugin.targetProfileForChange[p]
.displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={
verticalIconsPlugin.targetProfileForChange[p].icon
}
name={
verticalIconsPlugin.targetProfileForChange[p].name
}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -42,26 +42,7 @@ function Settings ({ scrollableRef, verticalIconsPlugin, itemContextAction, addA
.filter(p => p === 'settings') .filter(p => p === 'settings')
.map(p => ( .map(p => (
<Icon <Icon
kind={ profile={verticalIconsPlugin.targetProfileForChange[p]}
verticalIconsPlugin.targetProfileForChange[p].kind
}
displayName={
verticalIconsPlugin.targetProfileForChange[p]
.displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={
verticalIconsPlugin.targetProfileForChange[p].icon
}
name={
verticalIconsPlugin.targetProfileForChange[p].name
}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -22,19 +22,7 @@ function Solidity ({ verticalIconsPlugin, itemContextAction, addActive, removeAc
verticalIconsPlugin.targetProfileForChange[p].displayName verticalIconsPlugin.targetProfileForChange[p].displayName
}> }>
<Icon <Icon
kind={verticalIconsPlugin.targetProfileForChange[p].kind} profile={verticalIconsPlugin.targetProfileForChange[p]}
displayName={
verticalIconsPlugin.targetProfileForChange[p].displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={verticalIconsPlugin.targetProfileForChange[p].icon}
name={verticalIconsPlugin.targetProfileForChange[p].name}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -22,19 +22,7 @@ function SolidityStaticAnalysis ({ verticalIconsPlugin, itemContextAction, addAc
verticalIconsPlugin.targetProfileForChange[p].displayName verticalIconsPlugin.targetProfileForChange[p].displayName
}> }>
<Icon <Icon
kind={verticalIconsPlugin.targetProfileForChange[p].kind} profile={verticalIconsPlugin.targetProfileForChange[p]}
displayName={
verticalIconsPlugin.targetProfileForChange[p].displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={verticalIconsPlugin.targetProfileForChange[p].icon}
name={verticalIconsPlugin.targetProfileForChange[p].name}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -23,19 +23,7 @@ function Udapp ({ verticalIconsPlugin, itemContextAction, addActive, removeActiv
} }
> >
<Icon <Icon
kind={verticalIconsPlugin.targetProfileForChange[p].kind} profile={verticalIconsPlugin.targetProfileForChange[p]}
displayName={
verticalIconsPlugin.targetProfileForChange[p].displayName
}
documentation={
verticalIconsPlugin.targetProfileForChange[p]
.documentation
}
icon={verticalIconsPlugin.targetProfileForChange[p].icon}
name={verticalIconsPlugin.targetProfileForChange[p].name}
tooltip={
verticalIconsPlugin.targetProfileForChange[p].tooltip
}
verticalIconPlugin={verticalIconsPlugin} verticalIconPlugin={verticalIconsPlugin}
contextMenuAction={itemContextAction} contextMenuAction={itemContextAction}
addActive={addActive} addActive={addActive}

@ -0,0 +1,10 @@
export const defaultState: {
key: string | number
title: string
type: string
text: string
} = { key: '', title: '', type: '', text: '' }
function iconStatusReducer (state, action: any) {
return defaultState
}

@ -53,6 +53,8 @@ export class VerticalIcons extends Plugin<any, any> {
targetProfileForChange: any targetProfileForChange: any
targetProfileForRemoval: any targetProfileForRemoval: any
registry: registry registry: registry
keys: string[]
types: string[]
renderComponent(): void renderComponent(): void
linkContent(profile: any): void linkContent(profile: any): void
unlinkContent(profile: any): void unlinkContent(profile: any): void

Loading…
Cancel
Save