Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delete forked state environment from env explorer #5600

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
13 changes: 8 additions & 5 deletions apps/remix-dapp/src/locales/en/udapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@
"udapp.hash": "hash",
"udapp.signature": "signature",
"udapp.forkStateTitle": "Fork VM state",
"udapp.forkStateLabel": "State Name",
"udapp.forkStateLabel": "New environment name",
"udapp.forkVmStateDesc1":"Forking state will create a new environment with same state as selected environment",
"udapp.forkVmStateDesc2":"New environment will be pinned, which can be unpinned or deleted using Envionment Explorer",
"udapp.fork": "Fork",
"udapp.deleteVmStateTitle": "Delete VM state",
"udapp.deleteVmStateDesc1": "Deleting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.deleteVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.deleteVmStateDesc3": "Do you want to continue?",
"udapp.resetVmStateTitle": "Reset VM state",
"udapp.resetVmStateDesc1": "Resetting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.resetVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.resetVmStateDesc3": "Do you want to continue?",
"udapp.reset": "Reset",
"udapp.delete": "Delete",
"udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).",
"udapp.createNewAccount": "Create a new account",
Expand Down
4 changes: 2 additions & 2 deletions apps/remix-ide-e2e/src/tests/vm_state.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const tests = {
.click('*[data-id="delete-state-icon"]')
.waitForElementVisible(
{
selector: "//*[@data-shared='tooltipPopup' and contains(.,'State not available to delete')]",
selector: "//*[@data-shared='tooltipPopup' and contains(.,'State not available to reset')]",
locateStrategy: 'xpath'
}
)
Expand Down Expand Up @@ -140,7 +140,7 @@ const tests = {
.modalFooterOKClick('udappNotify')
.waitForElementVisible('*[data-shared="tooltipPopup"]', 10000)
// check if toaster is shown
.assert.textContains('*[data-shared="tooltipPopup"]', `VM state deleted successfully.`)
.assert.textContains('*[data-shared="tooltipPopup"]', `VM state reset successfully.`)
// check that there are no instances
.assert.textContains('*[data-id="deployedContractsBadge"]', '0')
// check if state file is deleted
Expand Down
16 changes: 15 additions & 1 deletion apps/remix-ide/src/app/providers/environment-explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ export class EnvironmentExplorer extends ViewPlugin {
}
}

async deleteForkedState (provider) {
const providerName = await this.call('blockchain', 'getProvider')
if (providerName !== provider.name) {
await this.call('fileManager', 'remove', `.states/forked_states/${provider.displayName}.json`)
await this.call('blockchain', 'removeProvider', provider.name)
this.call('notification', 'toast', `Environment "${provider.displayName}" deleted successfully.`)
} else this.call('notification', 'toast', 'Cannot delete the current selected environment')
}

renderComponent() {
this.dispatch({
...this.state
Expand All @@ -86,7 +95,12 @@ export class EnvironmentExplorer extends ViewPlugin {

updateComponent(state: EnvironmentExplorerState) {
return (<>
<EnvironmentExplorerUI pinStateCallback={this.pinStateCallback.bind(this)} profile={profile} state={state} />
<EnvironmentExplorerUI
pinStateCallback={this.pinStateCallback.bind(this)}
deleteForkedState={this.deleteForkedState.bind(this)}
profile={profile}
state={state}
/>
</>)
}
}
13 changes: 8 additions & 5 deletions apps/remix-ide/src/app/tabs/locales/en/udapp.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@
"udapp.hash": "hash",
"udapp.signature": "signature",
"udapp.forkStateTitle": "Fork VM state",
"udapp.forkStateLabel": "State Name",
"udapp.forkStateLabel": "New environment name",
"udapp.forkVmStateDesc1":"Forking state will create a new environment with same state as selected environment",
"udapp.forkVmStateDesc2":"After forking, new environment will be pinned and selected automatically. It can be unpinned or deleted using Envionment Explorer",
"udapp.fork": "Fork",
"udapp.deleteVmStateTitle": "Delete VM state",
"udapp.deleteVmStateDesc1": "Deleting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.deleteVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.deleteVmStateDesc3": "Do you want to continue?",
"udapp.resetVmStateTitle": "Reset VM state",
"udapp.resetVmStateDesc1": "Resetting the state of this VM will delete the associated transaction details in this Workspace.",
"udapp.resetVmStateDesc2": "It will also delete the data of contracts deployed and pinned in this Workspace.",
"udapp.resetVmStateDesc3": "Do you want to continue?",
"udapp.reset": "Reset",
"udapp.delete": "Delete",
"udapp.injectedTitle": "Unfortunately it's not possible to create an account using injected provider. Please create the account directly from your provider (i.e metamask or other of the same type).",
"udapp.createNewAccount": "Create new account",
Expand Down
3 changes: 2 additions & 1 deletion apps/remix-ide/src/blockchain/blockchain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class Blockchain extends Plugin {
_paq.push(['trackEvent', 'blockchain', 'providerPinned', name])
this.emit('providersChanged')
this.changeExecutionContext({ context: name }, null, null, null)
this.call('notification', 'toast', `VM state '${providerName}' forked and selected as current environment.`)
this.call('notification', 'toast', `New environment '${providerName}' created with forked state.`)
})

this.on('environmentExplorer', 'providerUnpinned', (name, provider) => {
Expand Down Expand Up @@ -687,6 +687,7 @@ export class Blockchain extends Plugin {
}

removeProvider(name) {
if (this.pinnedProviders.includes(name)) this.emit('shouldRemoveProviderFromUdapp', name, this.getProviderObjByName(name))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is already emitted by on('environmentExplorer', 'providerUnpinned'. Could you explain why you need this here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, it doesn't remove provider from dropdown even after deletion. A similar check is there in addProvider too

this.executionContext.removeProvider(name)
this.emit('providersChanged')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ export const EnvironmentExplorerUI = (props: environmentExplorerUIProps) => {
}}
>
<div data-id={`${provider.name}desc`}>{(section.descriptionFn && section.descriptionFn(provider)) || provider.description}</div>
{ provider.isForkedState && <CustomTooltip
placement="auto"
tooltipId={`overlay-tooltip-${provider.name}`}
tooltipText="Delete Environment Immediately"
>
<span
onClick={async () => props.deleteForkedState(provider)}
className="btn btn-sm mt-1 border border-danger"
>
Delete Environment
</span>
</CustomTooltip>
}
</RemixUIGridCell>
))}
</RemixUIGridSection>
Expand Down
1 change: 1 addition & 0 deletions libs/remix-ui/environment-explorer/src/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export type environmentExplorerUIProps = {
providersFlat: { [key: string]: Provider }
pinnedProviders: string[]
}
deleteForkedState (provider: Provider): Promise<void>
pinStateCallback (provider: Provider, pinned: boolean): Promise<void>
profile: Profile
}
Expand Down
41 changes: 19 additions & 22 deletions libs/remix-ui/run-tab/src/lib/components/environment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export function EnvironmentUI(props: EnvironmentProps) {
const forkStatePrompt = (defaultName: string) => {
return (
<div data-id="forkVmStateModal">
<ul className='ml-3'>
<li><FormattedMessage id="udapp.forkVmStateDesc1"/></li>
<li><FormattedMessage id="udapp.forkVmStateDesc2"/></li>
</ul>
<label id="stateName" className="form-check-label" style={{ fontWeight: 'bolder' }}>
<FormattedMessage id="udapp.forkStateLabel" />
</label>
Expand All @@ -49,10 +53,10 @@ export function EnvironmentUI(props: EnvironmentProps) {
return (
<div data-id="deleteVmStateModal">
<ul className='ml-3'>
<li><FormattedMessage id="udapp.deleteVmStateDesc1"/></li>
<li><FormattedMessage id="udapp.deleteVmStateDesc2"/></li>
<li><FormattedMessage id="udapp.resetVmStateDesc1"/></li>
<li><FormattedMessage id="udapp.resetVmStateDesc2"/></li>
</ul>
<FormattedMessage id="udapp.deleteVmStateDesc3"/>
<FormattedMessage id="udapp.resetVmStateDesc3"/>
</div>
)
}
Expand Down Expand Up @@ -83,15 +87,15 @@ export function EnvironmentUI(props: EnvironmentProps) {
} else props.runTabPlugin.call('notification', 'toast', `State not available to fork, as no transactions have been made for selected environment & selected workspace.`)
}

const deleteVmState = async() => {
const resetVmState = async() => {
_paq.push(['trackEvent', 'udapp', 'deleteState', `deleteState clicked`])
const context = currentProvider.name
const contextExists = await props.runTabPlugin.call('fileManager', 'exists', `.states/${context}/state.json`)
if (contextExists) {
props.modal(
intl.formatMessage({ id: 'udapp.deleteVmStateTitle' }),
intl.formatMessage({ id: 'udapp.resetVmStateTitle' }),
deleteVmStatePrompt(),
intl.formatMessage({ id: 'udapp.delete' }),
intl.formatMessage({ id: 'udapp.reset' }),
async () => {
const currentProvider = await props.runTabPlugin.call('blockchain', 'getCurrentProvider')
// Reset environment blocks and account data
Expand All @@ -103,35 +107,28 @@ export function EnvironmentUI(props: EnvironmentProps) {
// If there are pinned contracts, delete pinned contracts folder
const isPinnedContracts = await props.runTabPlugin.call('fileManager', 'exists', `.deploys/pinned-contracts/${context}`)
if (isPinnedContracts) await props.runTabPlugin.call('fileManager', 'remove', `.deploys/pinned-contracts/${context}`)
props.runTabPlugin.call('notification', 'toast', `VM state deleted successfully.`)
_paq.push(['trackEvent', 'udapp', 'deleteState', `VM state deleted`])
props.runTabPlugin.call('notification', 'toast', `VM state reset successfully.`)
_paq.push(['trackEvent', 'udapp', 'deleteState', `VM state reset`])
},
intl.formatMessage({ id: 'udapp.cancel' }),
null
)
} else props.runTabPlugin.call('notification', 'toast', `State not available to delete, as no transactions have been made for selected environment & selected workspace.`)
} else props.runTabPlugin.call('notification', 'toast', `State not available to reset, as no transactions have been made for selected environment & selected workspace.`)
}

const isL2 = (providerDisplayName: string) => providerDisplayName && (providerDisplayName.startsWith('L2 - Optimism') || providerDisplayName.startsWith('L2 - Arbitrum'))
return (
<div className="udapp_crow">
<label id="selectExEnv" className="udapp_settingsLabel">
<label id="selectExEnv" className="udapp_settingsLabel w-100">
<FormattedMessage id="udapp.environment" />
<CustomTooltip placement={'auto-end'} tooltipClasses="text-nowrap" tooltipId="info-recorder" tooltipText={<FormattedMessage id="udapp.tooltipText2" />}>
<a href="https://chainlist.org/" target="_blank">
<i className={'ml-2 fas fa-plug'} aria-hidden="true"></i>
</a>
</CustomTooltip>
<CustomTooltip placement={'auto-end'} tooltipClasses="text-wrap" tooltipId="runAndDeployAddresstooltip" tooltipText={<FormattedMessage id="udapp.environmentDocs" />}>
<a href="https://remix-ide.readthedocs.io/en/latest/run.html#environment" target="_blank" rel="noreferrer">
<i className="udapp_infoDeployAction ml-2 fas fa-info"></i>
</a>
</CustomTooltip>
{ currentProvider && currentProvider.isVM && isSaveEvmStateChecked && <CustomTooltip placement={'auto-end'} tooltipClasses="text-wrap" tooltipId="forkStatetooltip" tooltipText={<FormattedMessage id="udapp.forkStateTitle" />}>
<i className="udapp_infoDeployAction ml-2 fas fa-code-branch" style={{ cursor: 'pointer' }} onClick={forkState} data-id="fork-state-icon"></i>
</CustomTooltip> }
{ currentProvider && currentProvider.isVM && isSaveEvmStateChecked && <CustomTooltip placement={'auto-end'} tooltipClasses="text-wrap" tooltipId="deleteVMStatetooltip" tooltipText={<FormattedMessage id="udapp.deleteVmStateTitle" />}>
<i className="udapp_infoDeployAction ml-2 fas fa-trash" style={{ cursor: 'pointer' }} onClick={deleteVmState} data-id="delete-state-icon"></i>
{ currentProvider && currentProvider.isVM && isSaveEvmStateChecked && <CustomTooltip placement={'auto-end'} tooltipClasses="text-wrap" tooltipId="deleteVMStatetooltip" tooltipText={<FormattedMessage id="udapp.resetVmStateTitle" />}>
<span onClick={resetVmState} style={{ cursor: 'pointer', float: 'right', textTransform: 'none' }}>
<i className="udapp_infoDeployAction ml-2 fas fa-refresh" data-id="delete-state-icon"></i>
<span className="ml-1" style = {{textTransform: 'none', fontSize: '13px' }}>Reset State</span>
</span>
</CustomTooltip> }
</label>
<div className="udapp_environment" data-id={`selected-provider-${currentProvider && currentProvider.name}`}>
Expand Down
Loading