UNPKG

@jupyterlab/git

Version:

A JupyterLab extension for version control using git

195 lines (194 loc) 7.74 kB
import { Notification } from '@jupyterlab/apputils'; import ClearIcon from '@mui/icons-material/Clear'; import Dialog from '@mui/material/Dialog'; import DialogActions from '@mui/material/DialogActions'; import * as React from 'react'; import { classes } from 'typestyle'; import { showError } from '../notifications'; import { actionsWrapperClass, buttonClass, cancelButtonClass, closeButtonClass, commitFormClass, contentWrapperClass, resetRevertDialogClass, submitButtonClass, titleClass, titleWrapperClass } from '../style/ResetRevertDialog'; import { CommitMessage } from './CommitMessage'; /** * React component for rendering a dialog for resetting or reverting a single commit. */ export class ResetRevertDialog extends React.Component { /** * Returns a React component for resetting or reverting a single commit. * * @param props - component properties * @returns React component */ constructor(props) { super(props); /** * Callback invoked upon updating a commit message summary. */ this._onSummaryChange = (summary) => { this.setState({ summary }); }; /** * Callback invoked upon updating a commit message description. */ this._onDescriptionChange = (description) => { this.setState({ description }); }; /** * Callback invoked upon clicking on a dialog. * * @param event - event object */ this._onClick = (event) => { event.stopPropagation(); }; /** * Callback invoked upon closing the dialog. * * @param event - event object */ this._onClose = (event) => { event.stopPropagation(); this.props.onClose(); this._reset(); }; /** * Callback invoked upon clicking a button to reset or revert a commit. * * @param event - event object */ this._onSubmit = async () => { this.setState({ disabled: true }); if (this.props.action === 'reset') { this._resetCommit(this.props.commit.commit); } else { this._revertCommit(this.props.commit.commit); } this._reset(); this.props.onClose(); }; this.state = { summary: '', description: '', disabled: false }; } /** * Renders a dialog. * * @returns React element */ render() { const shortCommit = this.props.commit.commit.slice(0, 7); const isRevert = this.props.action === 'revert'; return (React.createElement(Dialog, { classes: { paper: resetRevertDialogClass }, open: this.props.open, onClick: this._onClick, onClose: this._onClose }, React.createElement("div", { className: titleWrapperClass }, React.createElement("p", { className: titleClass }, isRevert ? this.props.trans.__('Revert Changes') : this.props.trans.__('Reset Changes')), React.createElement("button", { className: closeButtonClass }, React.createElement(ClearIcon, { titleAccess: this.props.trans.__('Close this dialog'), fontSize: "small", onClick: this._onClose }))), React.createElement("div", { className: contentWrapperClass }, React.createElement("p", null, isRevert ? this.props.trans.__("These changes will be reverted. Only commit if you're sure you're okay losing these changes.") : this.props.trans.__('All changes after commit %1 will be gone forever (hard reset). Are you sure?', shortCommit)), isRevert && (React.createElement("div", { className: commitFormClass }, React.createElement(CommitMessage, { trans: this.props.trans, summary: this.state.summary, summaryPlaceholder: this._defaultSummary(), description: this.state.description, descriptionPlaceholder: this._defaultDescription(), setSummary: this._onSummaryChange, setDescription: this._onDescriptionChange })))), React.createElement(DialogActions, { className: actionsWrapperClass }, React.createElement("input", { disabled: this.state.disabled, className: classes(buttonClass, cancelButtonClass), type: "button", title: this.props.trans.__('Cancel changes'), value: "Cancel", onClick: this._onClose }), React.createElement("input", { disabled: this.state.disabled, className: classes(buttonClass, submitButtonClass), type: "button", title: this.props.trans.__('Submit changes'), value: "Submit", onClick: this._onSubmit })))); } /** * Reset the current branch on the provided commit * * @param hash Git commit hash */ async _resetCommit(hash) { const id = Notification.emit(this.props.trans.__('Discarding changes…'), 'in-progress', { autoClose: false }); try { await this.props.model.resetToCommit(hash); Notification.update({ id, message: this.props.trans.__('Successfully discarded changes.'), type: 'success', autoClose: 5000 }); } catch (error) { Notification.update({ id, message: this.props.trans.__('Failed to discard changes.'), type: 'error', ...showError(new Error(`Failed to discard changes after ${hash.slice(0, 7)}: ${error}`), this.props.trans) }); } } /** * Revert the provided commit. * * @param hash Git commit hash */ async _revertCommit(hash) { const id = Notification.emit(this.props.trans.__('Reverting changes…'), 'in-progress', { autoClose: false }); try { await this.props.model.revertCommit(this._commitMessage(), hash); Notification.update({ id, message: this.props.trans.__('Successfully reverted changes.'), type: 'success', autoClose: 5000 }); } catch (error) { Notification.update({ id, message: this.props.trans.__('Failed to revert changes.'), type: 'error', ...showError(new Error(`Failed to revert ${hash.slice(0, 7)}: ${error}`), this.props.trans) }); } } /** * Returns a default commit summary for reverting a commit. * * @returns default commit summary */ _defaultSummary() { const summary = this.props.commit.commit_msg.split('\n')[0]; return this.props.trans.__("Revert '%1'", summary); } /** * Returns a default commit description for reverting a commit. * * @returns default commit description */ _defaultDescription() { return this.props.trans.__('This reverts commit %1', this.props.commit.commit); } /** * Returns a commit message for reverting a commit. * * @returns commit message */ _commitMessage() { const summary = this.state.summary || this._defaultSummary(); const desc = this.state.description || this._defaultDescription(); return summary + '\n\n' + desc + '\n'; } /** * Resets component state. */ _reset() { this.setState({ summary: '', description: '', disabled: false }); } }