From a85e268f0928d83fc571996547a727ed31142ab1 Mon Sep 17 00:00:00 2001 From: filip mertens Date: Tue, 17 Dec 2024 10:23:41 +0100 Subject: [PATCH 1/6] refactor environment explorer --- .../app/providers/environment-explorer.tsx | 278 +++--------------- apps/remix-ide/src/blockchain/blockchain.tsx | 4 + .../environment-explorer/src/index.ts | 2 + .../components/environment-explorer-ui.tsx | 111 +++++++ .../src/lib/types/index.ts | 45 +++ .../grid-view/src/lib/remix-ui-grid-cell.tsx | 8 +- tsconfig.paths.json | 5 +- 7 files changed, 213 insertions(+), 240 deletions(-) create mode 100644 libs/remix-ui/environment-explorer/src/index.ts create mode 100644 libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx create mode 100644 libs/remix-ui/environment-explorer/src/lib/types/index.ts diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index facc93e4d8..cbf57ec29c 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -1,11 +1,8 @@ import React from 'react' // eslint-disable-line import { ViewPlugin } from '@remixproject/engine-web' -import { CustomTooltip, PluginViewWrapper } from '@remix-ui/helper' -import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view' -import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section' -import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell' +import { PluginViewWrapper } from '@remix-ui/helper' import './style/environment-explorer.css' -import type { Provider } from '../../blockchain/blockchain' +import { EnvironmentExplorerUI, Provider } from '@remix-ui/environment-explorer' import * as packageJson from '../../../../../package.json' @@ -25,44 +22,31 @@ const profile = { methods: [] } -type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked VMs' | 'Saved VM States' +type EnvironmentExplorerState = { + providersFlat: { [key: string]: Provider }, + pinnedProviders: string[], +} export class EnvironmentExplorer extends ViewPlugin { - providers: { [key in ProvidersSection]: Provider[] } - providersFlat: { [key: string]: Provider } - pinnedProviders: string[] - dispatch: React.Dispatch = () => {} - + dispatch: React.Dispatch = () => { } + state: EnvironmentExplorerState constructor() { super(profile) - this.providersFlat = {} - this.providers = { - 'Injected': [], - 'Remix VMs': [], - 'Saved VM States': [], - 'Remix forked VMs': [], - 'Externals': [] + this.state = { + providersFlat: {}, + pinnedProviders: [], } } async onActivation(): Promise { - this.providersFlat = await this.call('blockchain', 'getAllProviders') - this.pinnedProviders = await this.call('blockchain', 'getPinnedProviders') - this.renderComponent() + this.on('blockchain', 'providersChanged', this.updateProviders.bind(this)) + await this.updateProviders() } - addProvider (provider: Provider) { - if (provider.isInjected) { - this.providers['Injected'].push(provider) - } else if (provider.isForkedVM) { - this.providers['Remix forked VMs'].push(provider) - } else if (provider.isVM) { - this.providers['Remix VMs'].push(provider) - } else if (provider.isSavedState) { - this.providers['Saved VM States'].push(provider) - } else { - this.providers['Externals'].push(provider) - } + async updateProviders() { + this.state.providersFlat = await this.call('blockchain', 'getAllProviders') + this.state.pinnedProviders = await this.call('blockchain', 'getPinnedProviders') + this.renderComponent() } setDispatch(dispatch: React.Dispatch): void { @@ -77,215 +61,33 @@ export class EnvironmentExplorer extends ViewPlugin { ) } + + async pinStateCallback(provider: Provider, pinned: boolean) { + if (pinned) { + this.emit('providerPinned', provider.name, provider) + this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) + } else { + const providerName = await this.call('blockchain', 'getProvider') + if (providerName !== provider.name) { + this.emit('providerUnpinned', provider.name, provider) + this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) + return true + } else { + this.call('notification', 'toast', 'Cannot unpin the current selected provider') + return false + } + } + } + renderComponent() { this.dispatch({ - ...this + ...this.state }) } - updateComponent(state: any) { - this.providers = { - 'Injected': [], - 'Remix VMs': [], - 'Saved VM States': [], - 'Externals': [], - 'Remix forked VMs': [] - } - for (const [key, provider] of Object.entries(this.providersFlat)) { - this.addProvider(provider) - } - return ( - - - {this.providers['Injected'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })} -
- {this.providers['Remix VMs'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })}
- {this.providers['Saved VM States'].map(provider => { - const { latestBlock, timestamp } = JSON.parse(provider.description) - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
Latest Block: {parseInt(latestBlock)}
- -
Saved at: {(new Date(timestamp)).toDateString()}
-
-
- })}
- {this.providers['Remix forked VMs'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })}
- {this.providers['Externals'].map(provider => { - return { - if (pinned) { - this.emit('providerPinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been added to the Environment list of the Deploy & Run Transactions plugin.`) - return true - } - const providerName = await this.call('blockchain', 'getProvider') - if (providerName !== provider.name) { - this.emit('providerUnpinned', provider.name, provider) - this.call('notification', 'toast', `"${provider.displayName}" has been removed from the Environment list of the Deploy & Run Transactions plugin.`) - return true - } else { - this.call('notification', 'toast', 'Cannot unpin the current selected provider') - return false - } - }} - > -
{provider.description}
-
- })}
-
- ) + updateComponent(state: EnvironmentExplorerState) { + return (<> + + ) } } diff --git a/apps/remix-ide/src/blockchain/blockchain.tsx b/apps/remix-ide/src/blockchain/blockchain.tsx index d5832e9ff4..6d3958a064 100644 --- a/apps/remix-ide/src/blockchain/blockchain.tsx +++ b/apps/remix-ide/src/blockchain/blockchain.tsx @@ -146,6 +146,7 @@ export class Blockchain extends Plugin { this.pinnedProviders.push(name) this.call('config', 'setAppParameter', 'settings/pinned-providers', JSON.stringify(this.pinnedProviders)) _paq.push(['trackEvent', 'blockchain', 'providerPinned', name]) + this.emit('providersChanged') }) this.on('environmentExplorer', 'providerUnpinned', (name, provider) => { @@ -154,6 +155,7 @@ export class Blockchain extends Plugin { this.pinnedProviders.splice(index, 1) this.call('config', 'setAppParameter', 'settings/pinned-providers', JSON.stringify(this.pinnedProviders)) _paq.push(['trackEvent', 'blockchain', 'providerUnpinned', name]) + this.emit('providersChanged') }) this.call('config', 'getAppParameter', 'settings/pinned-providers').then((providers) => { @@ -665,10 +667,12 @@ export class Blockchain extends Plugin { addProvider(provider: Provider) { if (this.pinnedProviders.includes(provider.name)) this.emit('shouldAddProvidertoUdapp', provider.name, provider) this.executionContext.addProvider(provider) + this.emit('providersChanged') } removeProvider(name) { this.executionContext.removeProvider(name) + this.emit('providersChanged') } getAllProviders() { diff --git a/libs/remix-ui/environment-explorer/src/index.ts b/libs/remix-ui/environment-explorer/src/index.ts new file mode 100644 index 0000000000..6b3a3132fa --- /dev/null +++ b/libs/remix-ui/environment-explorer/src/index.ts @@ -0,0 +1,2 @@ +export * from './lib/types' +export { EnvironmentExplorerUI } from './lib/components/environment-explorer-ui' \ No newline at end of file diff --git a/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx new file mode 100644 index 0000000000..be13e52982 --- /dev/null +++ b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx @@ -0,0 +1,111 @@ +// eslint-disable-next-line no-use-before-define +import React, { useEffect, useState } from 'react' +import { environmentExplorerUIGridSections, environmentExplorerUIProps } from '../types' +import { RemixUIGridCell, RemixUIGridSection, RemixUIGridView } from '@remix-ui/remix-ui-grid-view' +import { CustomTooltip } from '@remix-ui/helper' + +const defaultSections: environmentExplorerUIGridSections = { + Injected: { + title: 'Deploy using a Browser Extension.', + keywords: ['Injected'], + providers: [], + filterFn: (provider) => provider.isInjected + }, + 'Remix VMs': { + title: 'Deploy to an In-browser Virtual Machine.', + keywords: ['Remix VMs'], + providers: [], + filterFn: (provider) => provider.isVM + }, + 'Saved VM States': { + title: 'Deploy to an In-browser Saved VM State.', + keywords: ['Saved VM States'], + providers: [], + filterFn: (provider) => provider.isSavedState, + descriptionFn: (provider) => { + const { latestBlock, timestamp } = JSON.parse(provider.description) + return ( + <> +
Latest Block: {parseInt(latestBlock)}
+ +
Saved at: {(new Date(timestamp)).toDateString()}
+
+ ) + } + }, + 'Remix forked VMs': { + title: 'Deploy to a Remix forked Virtual Machine.', + keywords: ['Remix forked VMs'], + providers: [], + filterFn: (provider) => provider.isForkedVM + }, + 'Externals': { + title: 'Deploy to an external Provider.', + keywords: ['Externals'], + providers: [], + filterFn: (provider) => (!provider.isInjected && !provider.isVM && !provider.isSavedState && !provider.isForkedVM) + }, +} +export const EnvironmentExplorerUI = (props: environmentExplorerUIProps) => { + + const [sections, setSections] = useState(defaultSections) + const { state, pinStateCallback, profile } = props + + useEffect(() => { + + setSections((prevSections) => { + const newSections = { ...prevSections } + Object.keys(newSections).forEach((section) => { + newSections[section].providers = Object.values(state.providersFlat).filter(newSections[section].filterFn) + }) + return newSections + }) + }, [state]) + + return ( + <> + { + Object.values(sections).length && Object.values(sections).map((section) => ( + + {section.providers.map(provider => { + return { + await pinStateCallback(provider, pinned) + }} + > +
{(section.descriptionFn && section.descriptionFn(provider)) || provider.description}
+
+ })} +
+ )) + } +
+ + ) +} \ No newline at end of file diff --git a/libs/remix-ui/environment-explorer/src/lib/types/index.ts b/libs/remix-ui/environment-explorer/src/lib/types/index.ts new file mode 100644 index 0000000000..61685a5f36 --- /dev/null +++ b/libs/remix-ui/environment-explorer/src/lib/types/index.ts @@ -0,0 +1,45 @@ +import { Plugin } from '@remixproject/engine' +import { Profile } from '@remixproject/plugin-utils' + +export type ProvidersSection = `Injected` | 'Remix VMs' | 'Externals' | 'Remix forked VMs' | 'Saved VM States' + +export type environmentExplorerUIProps = { + state: { + providersFlat: { [key: string]: Provider } + pinnedProviders: string[] + } + pinStateCallback (provider: Provider, pinned: boolean): Promise + profile: Profile +} + +export type environmentExplorerUIGridSection = { + title: string + keywords: string[], + providers: Provider[] + filterFn: (provider: Provider) => boolean + descriptionFn?: (provider: Provider) => string | JSX.Element | null +} + +export type environmentExplorerUIGridSections = { + [key in ProvidersSection]: environmentExplorerUIGridSection +} + +export type Provider = { + options: { [key: string]: string } + dataId: string + name: string + displayName: string + logo?: string, + logos?: string[], + fork: string + description?: string + isInjected: boolean + isVM: boolean + isSavedState: boolean + isForkedVM: boolean + title: string + init: () => Promise + provider: { + sendAsync: (payload: any) => Promise + } +} \ No newline at end of file diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx index f215b9ab53..3c66f9703d 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx @@ -54,6 +54,12 @@ export const RemixUIGridCell = (props: RemixUIGridCellProps) => { setAnyEnabled(enabled) }, [filterCon, props.tagList]) + useEffect(() => { + if(props.pinned!== pinned) { + setPinned(props.pinned) + } + },[props.pinned]) + /*const listenOnExpand = (key) => { if (key === props.key) setExpand(props.toggleExpandView) console.log('expand ----> ', key) @@ -86,7 +92,7 @@ export const RemixUIGridCell = (props: RemixUIGridCellProps) => { : <> } - { props.logos && props.logos.map((logo) => )} + { props.logos && props.logos.map((logo, index) => )} { props.title && Date: Tue, 17 Dec 2024 15:39:26 +0100 Subject: [PATCH 2/6] lint --- apps/remix-ide/src/app/providers/environment-explorer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/remix-ide/src/app/providers/environment-explorer.tsx b/apps/remix-ide/src/app/providers/environment-explorer.tsx index cbf57ec29c..a38c0d74d3 100644 --- a/apps/remix-ide/src/app/providers/environment-explorer.tsx +++ b/apps/remix-ide/src/app/providers/environment-explorer.tsx @@ -61,7 +61,6 @@ export class EnvironmentExplorer extends ViewPlugin { ) } - async pinStateCallback(provider: Provider, pinned: boolean) { if (pinned) { this.emit('providerPinned', provider.name, provider) From f72477cfd64022cdc32d56fc764200143f8c2807 Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 18 Dec 2024 08:10:54 +0100 Subject: [PATCH 3/6] linting --- .../src/lib/components/environment-explorer-ui.tsx | 2 +- libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx index be13e52982..42c2835a41 100644 --- a/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx +++ b/libs/remix-ui/environment-explorer/src/lib/components/environment-explorer-ui.tsx @@ -78,7 +78,7 @@ export const EnvironmentExplorerUI = (props: environmentExplorerUIProps) => { title={profile.description} description="Select the providers and chains to include them in the ENVIRONMENT select box of the Deploy & Run Transactions plugin." >{ - Object.values(sections).length && Object.values(sections).map((section) => ( + Object.values(sections).length && Object.values(sections).map((section) => ( { }, [filterCon, props.tagList]) useEffect(() => { - if(props.pinned!== pinned) { + if (props.pinned!== pinned) { setPinned(props.pinned) } },[props.pinned]) From b48d376865facd115572a344dcb9d36d75d403bd Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Wed, 18 Dec 2024 08:26:06 +0100 Subject: [PATCH 4/6] z index --- libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css index 760a85e1d6..3226d3c53f 100644 --- a/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css +++ b/libs/remix-ui/grid-view/src/lib/remix-ui-grid-cell.css @@ -31,6 +31,7 @@ right: 0.9rem; top: -0.7rem; background: transparent; + z-index: 1000; } .remixui_grid_cell_tags { From 5f202f32c423da2f0fd53f6ff6c5be5fe267e20c Mon Sep 17 00:00:00 2001 From: FT <140458077+zeevick10@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:05:34 +0100 Subject: [PATCH 5/6] Update release-process.md --- release-process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-process.md b/release-process.md index d66786d602..3443b2a083 100644 --- a/release-process.md +++ b/release-process.md @@ -49,7 +49,7 @@ This command will ask for a new version. This command uses `lerna` and is solely responsible for publishing all the remix libraries. It will ask for a new version of each library. Make sure you are logged in to NPM. -Once these commands run successfully, the version for each remix library will be updated to latest in the libs' package.json file. +Once these commands run successfully, the version for each remix library will be updated to the latest in the libs' package.json file. - Create and merge bump PR to master From 144f424329c53fd17a5d9030c235894033063363 Mon Sep 17 00:00:00 2001 From: witty <131909329+0xwitty@users.noreply.github.com> Date: Wed, 18 Dec 2024 14:54:44 +0300 Subject: [PATCH 6/6] docs: Fix Typos and Grammar in Documentation Update team-best-practices.md --- apps/remix-ide/team-best-practices.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/remix-ide/team-best-practices.md b/apps/remix-ide/team-best-practices.md index 7517e3483c..2088cd5bf9 100644 --- a/apps/remix-ide/team-best-practices.md +++ b/apps/remix-ide/team-best-practices.md @@ -5,7 +5,7 @@ This document aims to address contributors best practices of the following repos - remix-ide https://github.com/ethereum/remix-project - remix-plugin https://github.com/ethereum/remix-plugin -This document is not in its final version, **a team meeting which aims to address new/old best practices, feedback, workflows, all kind of issues related to how the team work together occurs every 2 weeks.** +This document is not in its final version, **a team meeting which aims to address new/old best practices, feedback, workflows, all kind of issues related to how the team works together occurs every 2 weeks.** This document link to other specialised best practices (like coding best practices). Related links: @@ -122,9 +122,9 @@ Before starting to coding, we should ensure all devs / contributors are aware of - A milestone should **only** contain items we are sure to finish. - The end of a milestone trigger a new release. - - Milestone items and duration should take in account time spent in bugs fixing and support. + - Milestone items and duration should take into account time spent in bugs fixing and support. - The team should commit to the milestone duration. - - If a dev finish early he/she can help other to push remaining tasks. + - If a dev finish early he/she can help others to push remaining tasks. - If a dev finish early he/she can work on specifying / integrating the next milestone. - A milestone duration is fixed at the start of the milestone (but should better not exceed 1 month). - Progress and issues regarding a milestone are discussed on regular standups. @@ -146,7 +146,7 @@ Before starting to coding, we should ensure all devs / contributors are aware of - After a new release we should stay in alert for possible regression and better not release on Friday at 5pm :) ### 2) Community: - - Before the official release, we should select a group of power users and invite them to test and give feedbacks. + - Before the official release, we should select a group of power users and invite them to test and give feedback. - Users need to know upfront a new release is coming and we should prepare them for it by showcasing some new features they can expect and when it will happen (fixed date, published at least 1 week in advance). - Whenever we have a new release we have to communicate this efficiently (twitter, reddit, ...).