switch branches and checkout to new branch

pull/2879/head
David Disu 2 years ago
parent 018a324daf
commit 6a370e714a
  1. 8
      apps/remix-ide/src/app/files/dgitProvider.js
  2. 8
      libs/remix-ui/workspace/src/lib/actions/index.ts
  3. 31
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  4. 3
      libs/remix-ui/workspace/src/lib/contexts/index.ts
  5. 10
      libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
  6. 56
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx

@ -107,15 +107,17 @@ class DGitProvider extends Plugin {
}, 1000) }, 1000)
} }
async checkout (cmd) { async checkout (cmd, refresh = true) {
await git.checkout({ await git.checkout({
...await this.getGitConfig(), ...await this.getGitConfig(),
...cmd ...cmd
}) })
if (refresh) {
setTimeout(async () => { setTimeout(async () => {
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}, 1000) }, 1000)
} }
}
async log (cmd) { async log (cmd) {
const status = await git.log({ const status = await git.log({
@ -135,14 +137,16 @@ class DGitProvider extends Plugin {
return remotes return remotes
} }
async branch (cmd) { async branch (cmd, refresh = true) {
const status = await git.branch({ const status = await git.branch({
...await this.getGitConfig(), ...await this.getGitConfig(),
...cmd ...cmd
}) })
if (refresh) {
setTimeout(async () => { setTimeout(async () => {
await this.call('fileManager', 'refresh') await this.call('fileManager', 'refresh')
}, 1000) }, 1000)
}
return status return status
} }

@ -488,11 +488,3 @@ export const moveFolder = async (src: string, dest: string) => {
dispatch(displayPopUp('Oops! An error ocurred while performing moveDir operation.' + error)) dispatch(displayPopUp('Oops! An error ocurred while performing moveDir operation.' + error))
} }
} }
export const showAllBranches = async () => {
const isActive = await plugin.call('manager', 'isActive', 'dgit')
if (!isActive) await plugin.call('manager', 'activatePlugin', 'dgit')
plugin.call('menuicons', 'select', 'dgit')
}

@ -451,28 +451,29 @@ export const switchToBranch = async (branch: string) => {
const gitConfig = { const gitConfig = {
ref: branch ref: branch
} }
const promise = plugin.call('dGitProvider', 'checkout', gitConfig) const promise = plugin.call('dGitProvider', 'checkout', gitConfig, false)
dispatch(cloneRepositoryRequest()) dispatch(cloneRepositoryRequest())
promise.then(async () => { promise.then(async () => {
await fetchWorkspaceDirectory(ROOT_PATH) await fetchWorkspaceDirectory(ROOT_PATH)
dispatch(cloneRepositorySuccess()) dispatch(cloneRepositorySuccess())
}).catch((e) => { }).catch((e) => {
const checkoutModal = {
id: 'checkoutGitBranch',
title: 'Checkout Git Branch',
message: 'An error occurred: ' + e,
modalType: 'modal',
okLabel: 'OK',
okFn: async () => {
// await deleteWorkspace(repoName)
dispatch(cloneRepositoryFailed())
},
hideFn: async () => {
// await deleteWorkspace(repoName)
dispatch(cloneRepositoryFailed()) dispatch(cloneRepositoryFailed())
})
return promise
}
export const switchToNewBranch = async (branch: string) => {
const gitConfig = {
ref: branch
} }
} const promise = plugin.call('dGitProvider', 'branch', gitConfig, false)
plugin.call('notification', 'modal', checkoutModal)
dispatch(cloneRepositoryRequest())
promise.then(async () => {
dispatch(cloneRepositorySuccess())
}).catch((e) => {
dispatch(cloneRepositoryFailed())
}) })
return promise
} }

@ -34,6 +34,7 @@ export const FileSystemContext = createContext<{
dispatchMoveFile: (src: string, dest: string) => Promise<void>, dispatchMoveFile: (src: string, dest: string) => Promise<void>,
dispatchMoveFolder: (src: string, dest: string) => Promise<void>, dispatchMoveFolder: (src: string, dest: string) => Promise<void>,
dispatchShowAllBranches: () => Promise<void>, dispatchShowAllBranches: () => Promise<void>,
dispatchSwitchToBranch: (branch: string) => Promise<void> dispatchSwitchToBranch: (branch: string) => Promise<void>,
dispatchSwitchToNewBranch: (branch: string) => Promise<void>
}>(null) }>(null)

@ -8,8 +8,7 @@ import { browserReducer, browserInitialState } from '../reducers/workspace'
import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder,
deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, deletePath, renamePath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace,
fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder,
showAllBranches, showAllBranches, switchToBranch, switchToNewBranch
switchToBranch
} from '../actions' } from '../actions'
import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -148,6 +147,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await switchToBranch(branch) await switchToBranch(branch)
} }
const dispatchSwitchToNewBranch = async (branch: string) => {
await switchToNewBranch(branch)
}
useEffect(() => { useEffect(() => {
dispatchInitWorkspace() dispatchInitWorkspace()
}, []) }, [])
@ -254,7 +257,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchMoveFile, dispatchMoveFile,
dispatchMoveFolder, dispatchMoveFolder,
dispatchShowAllBranches, dispatchShowAllBranches,
dispatchSwitchToBranch dispatchSwitchToBranch,
dispatchSwitchToNewBranch
} }
return ( return (
<FileSystemContext.Provider value={value}> <FileSystemContext.Provider value={value}>

@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef, useContext, SyntheticEvent } from 'react' // eslint-disable-line import React, { useState, useEffect, useRef, useContext, SyntheticEvent, ChangeEvent, KeyboardEvent } from 'react' // eslint-disable-line
import { Dropdown, OverlayTrigger, Tooltip } from 'react-bootstrap' import { Dropdown, OverlayTrigger, Tooltip } from 'react-bootstrap'
import { CustomIconsToggle, CustomMenu, CustomToggle } from '@remix-ui/helper' import { CustomIconsToggle, CustomMenu, CustomToggle } from '@remix-ui/helper'
import { FileExplorer } from './components/file-explorer' // eslint-disable-line import { FileExplorer } from './components/file-explorer' // eslint-disable-line
@ -18,6 +18,7 @@ export function Workspace () {
const [showIconsMenu, hideIconsMenu] = useState<boolean>(false) const [showIconsMenu, hideIconsMenu] = useState<boolean>(false)
const [showBranches, setShowBranches] = useState<boolean>(false) const [showBranches, setShowBranches] = useState<boolean>(false)
const [branchFilter, setBranchFilter] = useState<string>('') const [branchFilter, setBranchFilter] = useState<string>('')
const [selectedBranch, setSelectedBranch] = useState<string>('')
const displayOzCustomRef = useRef<HTMLDivElement>() const displayOzCustomRef = useRef<HTMLDivElement>()
const mintableCheckboxRef = useRef() const mintableCheckboxRef = useRef()
const burnableCheckboxRef = useRef() const burnableCheckboxRef = useRef()
@ -30,6 +31,7 @@ export function Workspace () {
const workspaceCreateTemplateInput = useRef() const workspaceCreateTemplateInput = useRef()
const cloneUrlRef = useRef<HTMLInputElement>() const cloneUrlRef = useRef<HTMLInputElement>()
const initGitRepoRef = useRef<HTMLInputElement>() const initGitRepoRef = useRef<HTMLInputElement>()
const filteredBranches = selectedWorkspace ? (selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 20) : []
useEffect(() => { useEffect(() => {
let workspaceName = localStorage.getItem('currentWorkspace') let workspaceName = localStorage.getItem('currentWorkspace')
@ -65,6 +67,7 @@ export function Workspace () {
const workspace = global.fs.browser.workspaces.find(workspace => workspace.name === currentWorkspace) const workspace = global.fs.browser.workspaces.find(workspace => workspace.name === currentWorkspace)
setSelectedWorkspace(workspace) setSelectedWorkspace(workspace)
workspace && setSelectedBranch(workspace.currentBranch)
}, [currentWorkspace]) }, [currentWorkspace])
const renameCurrentWorkspace = () => { const renameCurrentWorkspace = () => {
@ -205,7 +208,9 @@ export function Workspace () {
setShowBranches(isOpen) setShowBranches(isOpen)
} }
const handleBranchFilerChange = (branchFilter: string) => { const handleBranchFilterChange = (e: ChangeEvent<HTMLInputElement>) => {
const branchFilter = e.target.value
setBranchFilter(branchFilter) setBranchFilter(branchFilter)
} }
@ -213,8 +218,22 @@ export function Workspace () {
global.dispatchShowAllBranches() global.dispatchShowAllBranches()
} }
const switchToBranch = (branch: string) => { const switchToBranch = async (branch: string) => {
global.dispatchSwitchToBranch(branch) try {
await global.dispatchSwitchToBranch(branch)
setSelectedBranch(branch)
} catch (e) {
global.modal('Checkout Git Branch', e.message, 'OK', () => {})
}
}
const switchToNewBranch = async () => {
try {
await global.dispatchSwitchToNewBranch(branchFilter)
setSelectedBranch(branchFilter)
} catch (e) {
global.modal('Checkout Git Branch', e.message, 'OK', () => {})
}
} }
const createModalMessage = () => { const createModalMessage = () => {
@ -606,6 +625,7 @@ export function Workspace () {
</Dropdown.Item> </Dropdown.Item>
)) ))
} }
<Dropdown.Item onClick={() => { switchWorkspace(LOCALHOST) }}>{currentWorkspace === LOCALHOST ? <span>&#10003; localhost </span> : <span className="pl-3"> { LOCALHOST } </span>}</Dropdown.Item>
{ ((global.fs.browser.workspaces.length <= 0) || currentWorkspace === NO_WORKSPACE) && <Dropdown.Item onClick={() => { switchWorkspace(NO_WORKSPACE) }}>{ <span className="pl-3">NO_WORKSPACE</span> }</Dropdown.Item> } { ((global.fs.browser.workspaces.length <= 0) || currentWorkspace === NO_WORKSPACE) && <Dropdown.Item onClick={() => { switchWorkspace(NO_WORKSPACE) }}>{ <span className="pl-3">NO_WORKSPACE</span> }</Dropdown.Item> }
</Dropdown.Menu> </Dropdown.Menu>
</Dropdown> </Dropdown>
@ -705,7 +725,7 @@ export function Workspace () {
<div className="pt-1 mr-1"> <div className="pt-1 mr-1">
<Dropdown style={{ height: 30, minWidth: 80 }} onToggle={toggleBranches} show={showBranches} drop={'up'}> <Dropdown style={{ height: 30, minWidth: 80 }} onToggle={toggleBranches} show={showBranches} drop={'up'}>
<Dropdown.Toggle as={CustomToggle} id="dropdown-custom-components" className="btn btn-light btn-block w-100 d-inline-block border border-dark form-control h-100 p-0 pl-2 pr-2 text-dark" icon={null}> <Dropdown.Toggle as={CustomToggle} id="dropdown-custom-components" className="btn btn-light btn-block w-100 d-inline-block border border-dark form-control h-100 p-0 pl-2 pr-2 text-dark" icon={null}>
{ selectedWorkspace.currentBranch || '-none-' } { global.fs.browser.isRequestingCloning ? <i className="fad fa-spinner fa-spin"></i> : selectedBranch || '-none-' }
</Dropdown.Toggle> </Dropdown.Toggle>
<Dropdown.Menu as={CustomMenu} className='custom-dropdown-items branches-dropdown' data-id="custom-dropdown-items"> <Dropdown.Menu as={CustomMenu} className='custom-dropdown-items branches-dropdown' data-id="custom-dropdown-items">
@ -715,21 +735,31 @@ export function Workspace () {
</div> </div>
</div> </div>
<div className='border-top py-2'> <div className='border-top py-2'>
<input className='form-control border checkout-input bg-light' placeholder='Find or create a branch.' style={{ minWidth: 225 }} onChange={(e) => { handleBranchFilerChange(e.target.value) }} /> <input
className='form-control border checkout-input bg-light'
placeholder='Find or create a branch.'
style={{ minWidth: 225 }}
onChange={handleBranchFilterChange}
/>
</div> </div>
<div className='border-top'> <div className='border-top' style={{ maxHeight: 120, overflowY: 'scroll' }}>
{ {
(selectedWorkspace.branches || []).filter(branch => branch.name.includes(branchFilter) && branch.remote).slice(0, 4).map((branch, index) => { filteredBranches.length > 0 ? filteredBranches.map((branch, index) => {
return ( return (
<Dropdown.Item key={index}> <Dropdown.Item key={index} onClick={() => { switchToBranch(branch.name) }}>
{ {
selectedWorkspace.currentBranch === branch.name ? selectedBranch === branch.name ?
<span onClick={() => { switchToBranch(branch.name) }}>&#10003; { branch.name } </span> : <span>&#10003; { branch.name } </span> :
<span className="pl-3" onClick={() => { switchToBranch(branch.name) }}>{ branch.name }</span> <span className="pl-3">{ branch.name }</span>
} }
</Dropdown.Item> </Dropdown.Item>
) )
}) }) :
<Dropdown.Item onClick={switchToNewBranch}>
<div className="pl-1 pr-1">
<i className="fas fa-code-branch pr-2"></i><span>Create branch: { branchFilter } from '{selectedBranch}'</span>
</div>
</Dropdown.Item>
} }
</div> </div>
{ {

Loading…
Cancel
Save