add warning

pull/3097/head
filip mertens 2 years ago committed by Aniket
parent 7d11e11702
commit 96c36acc4b
  1. 2
      libs/remix-ui/settings/src/lib/constants.ts
  2. 2
      libs/remix-ui/settings/src/lib/github-settings.tsx
  3. 7
      libs/remix-ui/workspace/src/lib/actions/payload.ts
  4. 121
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  5. 15
      libs/remix-ui/workspace/src/lib/reducers/workspace.ts
  6. 7
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -5,7 +5,7 @@ export const warnText = 'Be sure the endpoint is opened before enabling it. \nTh
export const gitAccessTokenTitle = 'GitHub Access Token' export const gitAccessTokenTitle = 'GitHub Access Token'
export const gitAccessTokenText = 'Manage the access token used to publish to Gist and retrieve GitHub contents.' export const gitAccessTokenText = 'Manage the access token used to publish to Gist and retrieve GitHub contents.'
export const gitAccessTokenText2 = 'Go to github token page (link below) to create a new token and save it in Remix. Make sure this token has only \'create gist\' permission.' export const gitAccessTokenText2 = 'Go to github token page (link below) to create a new token and save it in Remix. To create gists set the scope to "gist". To retrieve GitHub contents set the scope to "repo".'
export const gitAccessTokenLink = 'https://github.com/settings/tokens/new?scopes=gist,repo&description=Remix%20IDE%20Token' export const gitAccessTokenLink = 'https://github.com/settings/tokens/new?scopes=gist,repo&description=Remix%20IDE%20Token'
export const etherscanTokenTitle = 'EtherScan Access Token' export const etherscanTokenTitle = 'EtherScan Access Token'
export const etherscanTokenLink = 'https://etherscan.io/myapikey' export const etherscanTokenLink = 'https://etherscan.io/myapikey'

@ -73,7 +73,7 @@ export function GithubSettings (props: GithubSettingsProps) {
<div className="text-secondary mb-0 h6"> <div className="text-secondary mb-0 h6">
<input id="githubemail" data-id="settingsTabGithubEmail" type="text" className="form-control" onChange={(e) => handleChangeEmailState(e)} value={ githubEmail } /> <input id="githubemail" data-id="settingsTabGithubEmail" type="text" className="form-control" onChange={(e) => handleChangeEmailState(e)} value={ githubEmail } />
<div className="d-flex justify-content-end pt-2"> <div className="d-flex justify-content-end pt-2">
<input className="btn btn-sm btn-primary ml-2" id="savegisttoken" data-id="settingsTabSaveGistToken" onClick={saveGithubToken} value="Save" type="button" disabled={githubToken === ''}></input> <input className="btn btn-sm btn-primary ml-2" id="savegisttoken" data-id="settingsTabSaveGistToken" onClick={saveGithubToken} value="Save" type="button"></input>
<CustomTooltip <CustomTooltip
tooltipText="Delete Github Credentials" tooltipText="Delete Github Credentials"
tooltipClasses="text-nowrap" tooltipClasses="text-nowrap"

@ -285,3 +285,10 @@ export const setCurrentWorkspaceIsGitRepo = (isRepo: boolean) => {
payload: isRepo payload: isRepo
} }
} }
export const setGitConfig = (config: {username: string, token: string, email: string}) => {
return {
type: 'SET_GIT_CONFIG',
payload: config
}
}

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import { bufferToHex, keccakFromString } from 'ethereumjs-util' import { bufferToHex, keccakFromString } from 'ethereumjs-util'
import axios, { AxiosResponse } from 'axios' import axios, { AxiosResponse } from 'axios'
import { addInputFieldSuccess, cloneRepositoryFailed, cloneRepositoryRequest, cloneRepositorySuccess, createWorkspaceError, createWorkspaceRequest, createWorkspaceSuccess, displayNotification, displayPopUp, fetchWorkspaceDirectoryError, fetchWorkspaceDirectoryRequest, fetchWorkspaceDirectorySuccess, hideNotification, setCurrentWorkspace, setCurrentWorkspaceBranches, setCurrentWorkspaceCurrentBranch, setDeleteWorkspace, setMode, setReadOnlyMode, setRenameWorkspace, setCurrentWorkspaceIsGitRepo } from './payload' import { addInputFieldSuccess, cloneRepositoryFailed, cloneRepositoryRequest, cloneRepositorySuccess, createWorkspaceError, createWorkspaceRequest, createWorkspaceSuccess, displayNotification, displayPopUp, fetchWorkspaceDirectoryError, fetchWorkspaceDirectoryRequest, fetchWorkspaceDirectorySuccess, hideNotification, setCurrentWorkspace, setCurrentWorkspaceBranches, setCurrentWorkspaceCurrentBranch, setDeleteWorkspace, setMode, setReadOnlyMode, setRenameWorkspace, setCurrentWorkspaceIsGitRepo, setGitConfig } from './payload'
import { addSlash, checkSlash, checkSpecialChars } from '@remix-ui/helper' import { addSlash, checkSlash, checkSpecialChars } from '@remix-ui/helper'
import { JSONStandardInput, WorkspaceTemplate } from '../types' import { JSONStandardInput, WorkspaceTemplate } from '../types'
@ -41,6 +41,13 @@ export const setPlugin = (filePanelPlugin, reducerDispatch) => {
plugin.on('dGitProvider', 'branch', async () => { plugin.on('dGitProvider', 'branch', async () => {
await checkGit() await checkGit()
}) })
plugin.on('config', 'configChanged', async () => {
await getGitConfig()
})
plugin.on('settings', 'configChanged', async () => {
await getGitConfig()
})
getGitConfig()
} }
export const addInputField = async (type: 'file' | 'folder', path: string, cb?: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => { export const addInputField = async (type: 'file' | 'folder', path: string, cb?: (err: Error, result?: string | number | boolean | Record<string, any>) => void) => {
@ -80,12 +87,7 @@ export const createWorkspace = async (workspaceName: string, workspaceTemplateNa
await plugin.workspaceCreated(workspaceName) await plugin.workspaceCreated(workspaceName)
if (isGitRepo) { if (isGitRepo) {
const workspacesPath = plugin.fileProviders.workspace.workspacesPath await checkGit()
const allBranches = await getGitRepoBranches(workspacesPath + '/' + workspaceName)
// selected branch will be 'master' or 'main'
const selectedBranch = allBranches?.length ? allBranches[0].name : 'main'
await plugin.call('dGitProvider', 'init', { branch: selectedBranch })
dispatch(setCurrentWorkspaceCurrentBranch(selectedBranch))
const isActive = await plugin.call('manager', 'isActive', 'dgit') const isActive = await plugin.call('manager', 'isActive', 'dgit')
if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit')
@ -95,9 +97,8 @@ export const createWorkspace = async (workspaceName: string, workspaceTemplateNa
if (isGitRepo) { if (isGitRepo) {
const name = await plugin.call('settings', 'get', 'settings/github-user-name') const name = await plugin.call('settings', 'get', 'settings/github-user-name')
const email = await plugin.call('settings', 'get', 'settings/github-email') const email = await plugin.call('settings', 'get', 'settings/github-email')
const token = await plugin.call('settings', 'get', 'settings/gist-access-token')
if (!name || !email ) {
if (!name || !email || !token) {
await plugin.call('notification', 'toast', 'Please provide GitHub details in the settings section to start committing and branching.') await plugin.call('notification', 'toast', 'Please provide GitHub details in the settings section to start committing and branching.')
} else { } else {
// commit the template as first commit // commit the template as first commit
@ -156,44 +157,44 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
switch (template) { switch (template) {
case 'code-template': case 'code-template':
// creates a new workspace code-sample and loads code from url params. // creates a new workspace code-sample and loads code from url params.
try { try {
let path = ''; let content let path = ''; let content
if (params.code) {
const hash = bufferToHex(keccakFromString(params.code))
path = 'contract-' + hash.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul': '.sol')
content = atob(params.code)
await workspaceProvider.set(path, content)
}
if (params.url) {
const data = await plugin.call('contentImport', 'resolve', params.url)
path = data.cleanUrl if (params.code) {
content = data.content const hash = bufferToHex(keccakFromString(params.code))
try { path = 'contract-' + hash.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul' : '.sol')
content = JSON.parse(content) as any content = atob(params.code)
if (content.language && content.language === "Solidity" && content.sources) { await workspaceProvider.set(path, content)
const standardInput: JSONStandardInput = content as JSONStandardInput }
for (const [fname, source] of Object.entries(standardInput.sources)) { if (params.url) {
await workspaceProvider.set(fname, source.content) const data = await plugin.call('contentImport', 'resolve', params.url)
path = data.cleanUrl
content = data.content
try {
content = JSON.parse(content) as any
if (content.language && content.language === "Solidity" && content.sources) {
const standardInput: JSONStandardInput = content as JSONStandardInput
for (const [fname, source] of Object.entries(standardInput.sources)) {
await workspaceProvider.set(fname, source.content)
}
return Object.keys(standardInput.sources)[0]
} else {
await workspaceProvider.set(path, JSON.stringify(content))
} }
return Object.keys(standardInput.sources)[0] } catch (e) {
} else { console.log(e)
await workspaceProvider.set(path, JSON.stringify(content)) await workspaceProvider.set(path, content)
} }
} catch (e) {
console.log(e)
await workspaceProvider.set(path, content)
} }
return path
} catch (e) {
console.error(e)
} }
return path break
} catch (e) {
console.error(e)
}
break
case 'gist-template': case 'gist-template':
// creates a new workspace gist-sample and get the file from gist // creates a new workspace gist-sample and get the file from gist
@ -214,7 +215,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
}) })
plugin.fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => { plugin.fileManager.setBatchFiles(obj, 'workspace', true, (errorLoadingFile) => {
if (errorLoadingFile) { if (errorLoadingFile) {
dispatch(displayNotification('', errorLoadingFile.message || errorLoadingFile, 'OK', null, () => {}, null)) dispatch(displayNotification('', errorLoadingFile.message || errorLoadingFile, 'OK', null, () => { }, null))
} }
}) })
} catch (e) { } catch (e) {
@ -351,12 +352,12 @@ export const uploadFile = async (target, targetFolder: string, cb?: (err: Error,
fileReader.onload = async function (event) { fileReader.onload = async function (event) {
if (checkSpecialChars(file.name)) { if (checkSpecialChars(file.name)) {
return dispatch(displayNotification('File Upload Failed', 'Special characters are not allowed', 'Close', null, async () => {})) return dispatch(displayNotification('File Upload Failed', 'Special characters are not allowed', 'Close', null, async () => { }))
} }
try { try {
await workspaceProvider.set(name, event.target.result) await workspaceProvider.set(name, event.target.result)
} catch (error) { } catch (error) {
return dispatch(displayNotification('File Upload Failed', 'Failed to create file ' + name, 'Close', null, async () => {})) return dispatch(displayNotification('File Upload Failed', 'Failed to create file ' + name, 'Close', null, async () => { }))
} }
const config = plugin.registry.get('config').api const config = plugin.registry.get('config').api
@ -376,14 +377,14 @@ export const uploadFile = async (target, targetFolder: string, cb?: (err: Error,
} else { } else {
dispatch(displayNotification('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, 'OK', null, () => { dispatch(displayNotification('Confirm overwrite', `The file ${name} already exists! Would you like to overwrite it?`, 'OK', null, () => {
loadFile(name) loadFile(name)
}, () => {})) }, () => { }))
} }
}) })
} }
export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }[]> | undefined => { export const getWorkspaces = async (): Promise<{ name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }[]> | undefined => {
try { try {
const workspaces: {name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string}[] = await new Promise((resolve, reject) => { const workspaces: { name: string, isGitRepo: boolean, branches?: { remote: any; name: string; }[], currentBranch?: string }[] = await new Promise((resolve, reject) => {
const workspacesPath = plugin.fileProviders.workspace.workspacesPath const workspacesPath = plugin.fileProviders.workspace.workspacesPath
plugin.fileProviders.browser.resolveDirectory('/' + workspacesPath, (error, items) => { plugin.fileProviders.browser.resolveDirectory('/' + workspacesPath, (error, items) => {
@ -418,7 +419,7 @@ export const getWorkspaces = async (): Promise<{name: string, isGitRepo: boolean
}) })
await plugin.setWorkspaces(workspaces) await plugin.setWorkspaces(workspaces)
return workspaces return workspaces
} catch (e) {} } catch (e) { }
} }
export const cloneRepository = async (url: string) => { export const cloneRepository = async (url: string) => {
@ -518,12 +519,20 @@ export const getGitRepoCurrentBranch = async (workspaceName: string) => {
export const showAllBranches = async () => { export const showAllBranches = async () => {
const isActive = await plugin.call('manager', 'isActive', 'dgit') const isActive = await plugin.call('manager', 'isActive', 'dgit')
if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit') if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit')
plugin.call('menuicons', 'select', 'dgit') plugin.call('menuicons', 'select', 'dgit')
plugin.call('dgit', 'open', 'branches') plugin.call('dgit', 'open', 'branches')
} }
export const getGitConfig = async () => {
const username = await plugin.call('settings', 'get', 'settings/github-user-name')
const email = await plugin.call('settings', 'get', 'settings/github-email')
const token = await plugin.call('settings', 'get', 'settings/gist-access-token')
const config = { username, email, token }
dispatch(setGitConfig(config))
return config
}
const refreshBranches = async () => { const refreshBranches = async () => {
const workspacesPath = plugin.fileProviders.workspace.workspacesPath const workspacesPath = plugin.fileProviders.workspace.workspacesPath
const workspaceName = plugin.fileProviders.workspace.workspace const workspaceName = plugin.fileProviders.workspace.workspace
@ -556,8 +565,8 @@ export const switchBranch = async (branch: string) => {
}) })
}, },
cancelLabel: 'Cancel', cancelLabel: 'Cancel',
cancelFn: () => {}, cancelFn: () => { },
hideFn: () => {} hideFn: () => { }
} }
plugin.call('notification', 'modal', cloneModal) plugin.call('notification', 'modal', cloneModal)
} else { } else {
@ -611,7 +620,7 @@ export const checkoutRemoteBranch = async (branch: string, remote: string) => {
const workspacesPath = plugin.fileProviders.workspace.workspacesPath const workspacesPath = plugin.fileProviders.workspace.workspacesPath
const workspaceName = plugin.fileProviders.workspace.workspace const workspaceName = plugin.fileProviders.workspace.workspace
const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName)
dispatch(setCurrentWorkspaceBranches(branches)) dispatch(setCurrentWorkspaceBranches(branches))
dispatch(cloneRepositorySuccess()) dispatch(cloneRepositorySuccess())
}).catch(() => { }).catch(() => {
@ -619,8 +628,8 @@ export const checkoutRemoteBranch = async (branch: string, remote: string) => {
}) })
}, },
cancelLabel: 'Cancel', cancelLabel: 'Cancel',
cancelFn: () => {}, cancelFn: () => { },
hideFn: () => {} hideFn: () => { }
} }
plugin.call('notification', 'modal', cloneModal) plugin.call('notification', 'modal', cloneModal)
} else { } else {
@ -631,7 +640,7 @@ export const checkoutRemoteBranch = async (branch: string, remote: string) => {
const workspacesPath = plugin.fileProviders.workspace.workspacesPath const workspacesPath = plugin.fileProviders.workspace.workspacesPath
const workspaceName = plugin.fileProviders.workspace.workspace const workspaceName = plugin.fileProviders.workspace.workspace
const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName) const branches = await getGitRepoBranches(workspacesPath + '/' + workspaceName)
dispatch(setCurrentWorkspaceBranches(branches)) dispatch(setCurrentWorkspaceBranches(branches))
dispatch(cloneRepositorySuccess()) dispatch(cloneRepositorySuccess())
}).catch(() => { }).catch(() => {

@ -64,7 +64,8 @@ export interface BrowserState {
popup: string, popup: string,
focusEdit: string, focusEdit: string,
focusElement: { key: string, type: 'file' | 'folder' | 'gist' }[], focusElement: { key: string, type: 'file' | 'folder' | 'gist' }[],
initializingFS: boolean initializingFS: boolean,
gitConfig: { username: string, email: string, token: string },
} }
export const browserInitialState: BrowserState = { export const browserInitialState: BrowserState = {
@ -116,7 +117,8 @@ export const browserInitialState: BrowserState = {
popup: '', popup: '',
focusEdit: '', focusEdit: '',
focusElement: [], focusElement: [],
initializingFS: true initializingFS: true,
gitConfig: { username: '', email: '', token: '' }
} }
export const browserReducer = (state = browserInitialState, action: Action) => { export const browserReducer = (state = browserInitialState, action: Action) => {
@ -718,6 +720,15 @@ export const browserReducer = (state = browserInitialState, action: Action) => {
} }
} }
case 'SET_GIT_CONFIG' : {
const payload: { username: string, token: string, email: string } = action.payload
return {
...state,
gitConfig: payload
}
}
default: default:
throw new Error() throw new Error()
} }

@ -303,6 +303,7 @@ export function Workspace () {
data-id="initGitRepository" data-id="initGitRepository"
className="form-check-input custom-control-input" className="form-check-input custom-control-input"
type="checkbox" type="checkbox"
disabled={!global.fs.gitConfig.username || !global.fs.gitConfig.email}
onChange={() => {}} onChange={() => {}}
/> />
<label <label
@ -314,6 +315,12 @@ export function Workspace () {
Initialize workspace as a new git repository Initialize workspace as a new git repository
</label> </label>
</div> </div>
{!global.fs.gitConfig.username || !global.fs.gitConfig.email ?
(
<div className='text-warning'>You need to set a username and email to be able to use git features.<br>
</br>Please update these fields in the settings of Remix</div>)
:<></>
}
</> </>
) )

Loading…
Cancel
Save