@jupyterlab/git
Version:
A JupyterLab extension for version control using git
133 lines (132 loc) • 6.25 kB
JavaScript
import * as React from 'react';
import { classes } from 'typestyle';
import { checkboxLabelContainerStyle, checkboxLabelLastContainerStyle, checkboxLabelStyle, fileChangedLabelAddedStyle, fileChangedLabelDeletedStyle, fileChangedLabelInfoStyle, fileChangedLabelModifiedStyle, fileChangedLabelStyle, fileClickableStyle, fileStyle, gitMarkBoxStyle, selectedFileChangedLabelStyle, selectedFileStyle } from '../style/FileItemStyle';
import { fileLabelStyle } from '../style/FilePathStyle';
import { FilePath } from './FilePath';
/**
* Render the selection box in simple mode
*/
class GitMarkBox extends React.PureComponent {
constructor() {
super(...arguments);
this._onDoubleClick = (event) => {
event.stopPropagation();
};
}
render() {
// idempotent, will only run once per file
this.props.model.addMark(this.props.fname, this.props.stage !== 'untracked');
return (React.createElement("input", { name: "gitMark", className: gitMarkBoxStyle, type: "checkbox", checked: this.props.checked, onDoubleClick: this._onDoubleClick }));
}
}
export class FileItem extends React.PureComponent {
constructor(props) {
super(props);
this._onClick = (event) => {
var _a, _b;
if (this.props.markBox) {
if (event.shiftKey) {
this.props.markUntilFile(this.props.file);
}
else {
this.props.model.toggleMark(this.props.file.to);
this.props.setSelection(this.props.file, { singleton: true });
}
}
else {
if (event.ctrlKey || event.metaKey) {
this.props.setSelection(this.props.file);
}
else if (event.shiftKey) {
this.props.setSelection(this.props.file, { group: true });
}
else {
this.props.setSelection(this.props.file, { singleton: true });
// Skip on the second click of a double-click so a `diff-on-single`
// navigation isn't triggered twice on the way to `onDoubleClick`.
if (event.detail <= 1) {
(_b = (_a = this.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, this.props.file);
}
}
}
};
}
_getFileChangedLabel(change, trans) {
return Private.get_status(change, trans) || trans.__('Unmodified');
}
_getFileChangedLabelClass(change) {
let colorStyle;
switch (change) {
case 'A':
case 'U':
colorStyle = fileChangedLabelAddedStyle;
break;
case 'D':
case '!':
colorStyle = fileChangedLabelDeletedStyle;
break;
case 'M':
case 'R':
colorStyle = fileChangedLabelModifiedStyle;
break;
default:
colorStyle = fileChangedLabelInfoStyle;
}
return this.props.selected
? classes(fileChangedLabelStyle, colorStyle, selectedFileChangedLabelStyle)
: classes(fileChangedLabelStyle, colorStyle);
}
_getFileClass() {
// Show the pointer cursor only when a single click triggers an action
// beyond selection (i.e. when `onClick` is provided by the parent).
const clickableClass = this.props.onClick ? fileClickableStyle : '';
const baseClass = this.props.selected
? classes(fileStyle, selectedFileStyle, clickableClass)
: classes(fileStyle, clickableClass);
return this.props.className
? `${baseClass} ${this.props.className}`
: baseClass;
}
render() {
var _a;
const { file } = this.props;
const status_code = file.status === 'staged' ? file.x : file.y;
const badge_code = file.status === 'unmerged' ? '!' : file.y === '?' ? 'U' : status_code;
const status = file.status === 'unmerged'
? this.props.trans.__('Conflicted')
: this._getFileChangedLabel(status_code, this.props.trans);
return (React.createElement("div", { "data-test-selected": this.props.selected, "data-test-checked": this.props.checked, className: this._getFileClass(), onClick: this._onClick, onContextMenu: this.props.contextMenu &&
(event => {
this.props.contextMenu(this.props.file, event);
}), onDoubleClick: this.props.onDoubleClick, style: this.props.style, title: this.props.trans.__(`%1 • ${status}`, this.props.file.to) },
React.createElement("div", { className: checkboxLabelContainerStyle },
React.createElement("div", { className: checkboxLabelStyle + ' ' + fileLabelStyle },
this.props.markBox && (React.createElement(GitMarkBox, { fname: this.props.file.to, stage: this.props.file.status, model: this.props.model, checked: (_a = this.props.checked) !== null && _a !== void 0 ? _a : false })),
React.createElement(FilePath, { filepath: this.props.file.to, filetype: this.props.file.type })),
React.createElement("div", { className: checkboxLabelLastContainerStyle },
this.props.actions,
React.createElement("span", { className: this._getFileChangedLabelClass(badge_code) }, badge_code)))));
}
}
var Private;
(function (Private) {
let i18nCodes = null;
function get_status(code, trans) {
if (!i18nCodes) {
// Git status codes https://git-scm.com/docs/git-status
i18nCodes = {
M: trans.__('Modified'),
A: trans.__('Added'),
D: trans.__('Deleted'),
R: trans.__('Renamed'),
C: trans.__('Copied'),
U: trans.__('Updated'),
B: trans.__('Behind'),
'?': trans.__('Untracked'),
'!': trans.__('Ignored')
};
}
return i18nCodes[code];
}
Private.get_status = get_status;
})(Private || (Private = {}));