import React, { PureComponent } from 'react'; import classnames from 'classnames'; import { autoBindMethodsForReact } from 'class-autobind-decorator'; import { AUTOBIND_CFG } from '../../../common/constants'; import Modal from '../base/modal'; import ModalBody from '../base/modal-body'; import ModalHeader from '../base/modal-header'; import type { Workspace } from '../../../models/workspace'; import { VCS } from '../../../sync/vcs/vcs'; import { database as db } from '../../../common/database'; import type { StatusCandidate } from '../../../sync/types'; import PromptButton from '../base/prompt-button'; import SyncPullButton from '../sync-pull-button'; interface Props { workspace: Workspace; syncItems: StatusCandidate[]; vcs: VCS; } interface State { error: string; newBranchName: string; currentBranch: string; branches: string[]; remoteBranches: string[]; } @autoBindMethodsForReact(AUTOBIND_CFG) class SyncBranchesModal extends PureComponent { modal: Modal | null = null; state: State = { error: '', newBranchName: '', branches: [], remoteBranches: [], currentBranch: '', } _setModalRef(m: Modal) { this.modal = m; } async _handleCheckout(branch: string) { const { vcs, syncItems } = this.props; try { const delta = await vcs.checkout(syncItems, branch); // @ts-expect-error -- TSCONVERSION await db.batchModifyDocs(delta); await this.refreshState(); } catch (err) { console.log('Failed to checkout', err.stack); this.setState({ error: err.message, }); } } async _handleMerge(branch: string) { const { vcs, syncItems } = this.props; const delta = await vcs.merge(syncItems, branch); try { // @ts-expect-error -- TSCONVERSION await db.batchModifyDocs(delta); await this.refreshState(); } catch (err) { console.log('Failed to merge', err.stack); this.setState({ error: err.message, }); } } async _handleRemoteDelete(branch: string) { const { vcs } = this.props; try { await vcs.removeRemoteBranch(branch); await this.refreshState(); } catch (err) { console.log('Failed to remote delete', err.stack); this.setState({ error: err.message, }); } } async _handleDelete(branch: string) { const { vcs } = this.props; try { await vcs.removeBranch(branch); await this.refreshState(); } catch (err) { console.log('Failed to delete', err.stack); this.setState({ error: err.message, }); } } async _handleCreate(e: React.SyntheticEvent) { e.preventDefault(); const { vcs, syncItems } = this.props; try { // Create new branch const { newBranchName } = this.state; await vcs.fork(newBranchName); // Checkout new branch const delta = await vcs.checkout(syncItems, newBranchName); // @ts-expect-error -- TSCONVERSION await db.batchModifyDocs(delta); // Clear branch name and refresh things await this.refreshState({ newBranchName: '', }); } catch (err) { console.log('Failed to create', err.stack); this.setState({ error: err.message, }); } } _updateNewBranchName(e: React.ChangeEvent) { this.setState({ newBranchName: e.currentTarget.value }); } _handleClearError() { this.setState({ error: '' }); } async refreshState(newState?: Record) { const { vcs } = this.props; try { const currentBranch = await vcs.getBranch(); const branches = (await vcs.getBranches()).sort(); this.setState({ branches, currentBranch, error: '', ...newState, }); const remoteBranches = (await vcs.getRemoteBranches()) .filter(b => !branches.includes(b)) .sort(); this.setState({ remoteBranches, }); } catch (err) { console.log('Failed to refresh', err.stack); this.setState({ error: err.message, }); } } hide() { this.modal && this.modal.hide(); } async show(options: { onHide: (...args: any[]) => any }) { this.modal && this.modal.show({ onHide: options.onHide, }); await this.refreshState(); } render() { const { vcs } = this.props; const { branches, remoteBranches, currentBranch, newBranchName, error } = this.state; return ( Branches {error && (

{error}

)}
{branches.map(name => ( ))}
Branches  
{name} {name === currentBranch ? ( (current) ) : null} {name === 'master' && } this._handleMerge(name)}> Merge this._handleDelete(name)}> Delete
{remoteBranches.length > 0 && (
{remoteBranches.map(name => ( ))}
Remote Branches  
{name} {name === 'master' && } {name !== 'master' && ( this._handleRemoteDelete(name)}> Delete )} Fetch
)}
); } } export default SyncBranchesModal;