alm
Version:
The best IDE for TypeScript
245 lines (244 loc) • 17.8 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
var utils = require("../common/utils");
var styles = require("./styles/styles");
var React = require("react");
var ReactDOMServer = require("react-dom/server");
var csx = require("./base/csx");
var ui_1 = require("./ui");
var ui = require("./ui");
var commands = require("./commands/commands");
var types = require("../common/types");
var pendingRequestsIndicator_1 = require("./pendingRequestsIndicator");
var icon_1 = require("./components/icon");
var appTabsContainer_1 = require("./tabs/v2/appTabsContainer");
var progress_1 = require("./components/progress");
var react_redux_1 = require("react-redux");
var state_1 = require("./state/state");
var state = require("./state/state");
var globalErrorCacheClient_1 = require("./globalErrorCacheClient");
var clientTestResultsCache_1 = require("./clientTestResultsCache");
var notificationKeyboardStyle = {
border: '2px solid',
borderRadius: '6px',
display: 'inline-block',
padding: '5px',
background: 'grey',
};
var ouputStatusStyle = csx.extend(styles.noSelect, { fontSize: '.6rem' });
var activeProjectContainerStyle = csx.extend(styles.statusBarSection, styles.hand, styles.noSelect, {
border: '1px solid grey',
paddingTop: '2px',
paddingBottom: '2px',
paddingLeft: '4px',
paddingRight: '4px',
fontSize: '.7rem',
marginTop: '1px',
});
var projectTipKeboard = ReactDOMServer.renderToString(React.createElement("div", { style: notificationKeyboardStyle }, "Alt+Shift+P"));
var StatusBar = /** @class */ (function (_super) {
__extends(StatusBar, _super);
function StatusBar(props) {
var _this = _super.call(this, props) || this;
_this.toggleErrors = function () {
if (_this.props.errorsExpanded) {
state_1.collapseErrors({});
}
else {
state_1.expandErrors({});
}
};
_this.toggleFileTree = function () {
if (_this.props.fileTreeShown) {
state.collapseFileTree({});
}
else {
state.expandFileTree({});
}
};
_this.openErrorLocation = function (error) {
commands.doOpenOrFocusFile.emit({ filePath: error.filePath, position: error.from });
};
_this.openFile = function (filePath) {
commands.doOpenOrFocusFile.emit({ filePath: filePath });
};
_this.giveStar = function () {
window.open('https://github.com/alm-tools/alm');
};
_this.giveRose = function () {
window.open('https://twitter.com/basarat');
};
_this.whatsNew = function () {
/** We currently show the diff. Once we have semantic releases we will show release notes */
var update = serverState.update;
window.open("https://github.com/alm-tools/alm/compare/v" + update.current + "...v" + update.latest);
};
_this.state = {};
return _this;
}
StatusBar.prototype.componentDidMount = function () {
var _this = this;
exports.statusBar = this;
appTabsContainer_1.tabStateChanged.on(function () { return _this.forceUpdate(); });
globalErrorCacheClient_1.errorsCache.errorsDelta.on(function () { return _this.forceUpdate(); });
clientTestResultsCache_1.testResultsCache.testResultsDelta.on(function () { return _this.forceUpdate(); });
};
StatusBar.prototype.render = function () {
var _this = this;
var tab = appTabsContainer_1.tabState.getSelectedTab();
var filePath = tab && utils.getFilePathFromUrl(tab.url);
var protocol = tab && utils.getFilePathAndProtocolFromUrl(tab.url).protocol;
var activeProjectDetails = this.props.activeProject
? React.createElement("span", { className: "hint--top-right", "data-hint": "Active Project path. Click to open project file", style: activeProjectContainerStyle, onClick: function () {
_this.openFile(_this.props.activeProject.tsconfigFilePath);
ui.notifyInfoNormalDisappear("TIP : You can change the active project using project search <br/> <br/> " + projectTipKeboard, { onClick: function () { return commands.omniSelectProject.emit({}); } });
} },
React.createElement("span", { style: csx.extend(styles.noSelect, styles.statusBarSuccess, styles.hand, { marginRight: '5px' }) },
React.createElement(icon_1.Icon, { name: "heartbeat" })),
this.props.activeProject.isVirtual && React.createElement("span", { style: csx.extend(styles.noSelect, styles.statusBarSuccess, styles.hand, { marginRight: '5px' }) },
React.createElement(icon_1.Icon, { name: "blind" })),
this.props.activeProject.name)
: React.createElement("span", { className: "hint--top-right", style: csx.extend(styles.statusBarSection, styles.noSelect, styles.statusBarError, styles.hand), onClick: function () { return ui.notifyWarningNormalDisappear("There is no active project. Please select from the available ones <br/> <br/> " + projectTipKeboard, { onClick: function () { return commands.omniSelectProject.emit({}); } }); }, "data-hint": "There is no active TypeScript project. Robots deactivated." },
React.createElement(icon_1.Icon, { name: "heartbeat" }));
var inActiveProjectSection = !tab
? ''
: React.createElement("span", { style: styles.statusBarSection }, state.inActiveProjectUrl(tab.url)
? React.createElement("span", { className: "hint--top-right hint--success", style: csx.extend(styles.noSelect, styles.statusBarSuccess, styles.hand), onClick: function () { return ui.notifySuccessNormalDisappear("The file is a part of the currently active TypeScript project and we are actively providing code intelligence"); }, "data-hint": "File is part of the currently active project. \uD83D\uDCBB providing code intelligence." },
React.createElement(icon_1.Icon, { name: "eye" }))
: React.createElement("span", { className: "hint--top-right", style: csx.extend(styles.noSelect, styles.statusBarError, styles.hand), onClick: function () { return ui.notifyWarningNormalDisappear("The file is not a part of the currently active TypeScript project <br/> <br/> " + projectTipKeboard, { onClick: function () { return commands.omniSelectProject.emit({}); } }); }, "data-hint": "File is not a part of the currently active project. Robots deactivated." },
React.createElement(icon_1.Icon, { name: "eye-slash" })));
var fileOutput = protocol !== 'file' ? null
: !this.props.outputStatusCache[filePath] ? null
: this.props.outputStatusCache[filePath];
var fileOutputState = fileOutput && fileOutput.state;
var openOutputJSFile = function () {
commands.doToggleFileTab.emit({ filePath: fileOutput.outputFilePath });
};
var fileOutputStateRendered = !!fileOutputState
&& React.createElement("span", { style: styles.statusBarSection },
React.createElement("span", { style: csx.extend(ouputStatusStyle) }, fileOutputState === types.JSOutputState.NoJSFile ? null
: fileOutputState === types.JSOutputState.JSOutOfDate ? React.createElement("span", { style: csx.extend(styles.statusBarError, { transition: 'color .5s', cursor: 'pointer' }), onClick: openOutputJSFile }, "\u274C JS Outdated")
: React.createElement("span", { style: csx.extend(styles.statusBarSuccess, { transition: 'color .5s', cursor: 'pointer' }), onClick: openOutputJSFile }, "\u2713 JS Current")));
var fileTreeToggleRendered = React.createElement("span", { style: csx.extend(styles.statusBarSection, styles.noSelect, styles.hand), onClick: this.toggleFileTree, className: "hint--top-right", "data-hint": "Click to toggle the file tree \uD83C\uDF32" },
React.createElement("span", { style: csx.extend(this.props.fileTreeShown ? { color: 'white' } : { color: 'grey' }, { transition: 'color .4s' }) },
React.createElement(icon_1.Icon, { name: "tree" })));
var updateRendered = serverState.update
&& React.createElement("span", { style: csx.extend(styles.statusBarSection) },
React.createElement("span", { className: "hint--left hint--error", "data-hint": "Update " + serverState.update.latest + " available (current: " + serverState.update.current + ")" + ". Please run `npm i -g alm`" },
React.createElement(icon_1.Icon, { style: { color: styles.errorColor, cursor: 'pointer' }, name: "wrench", onClick: this.whatsNew })));
var errorsUpdate = globalErrorCacheClient_1.errorsCache.getErrorsLimited();
var errorFilteringActive = this.props.errorsDisplayMode !== types.ErrorsDisplayMode.all || this.props.errorsFilter.trim();
var errorsFilteredCount = appTabsContainer_1.tabState.errorsByFilePathFiltered().errorsFlattened.length;
/** Tested */
var testResultsStats = clientTestResultsCache_1.testResultsCache.getStats();
var failing = !!testResultsStats.failCount;
var totalThatRan = testResultsStats.passCount + testResultsStats.failCount;
var testStatsRendered = !!testResultsStats.testCount && React.createElement("span", { className: "hint--top-right", "data-hint": "Test Total: " + testResultsStats.testCount + ", Pass: " + testResultsStats.passCount + ", Fail: " + testResultsStats.failCount + ", Skip: " + testResultsStats.skipCount + ", Duration: " + utils.formatMilliseconds(testResultsStats.durationMs), style: csx.extend(activeProjectContainerStyle), onClick: function () {
commands.doOpenTestResultsView.emit({});
} },
React.createElement("span", { style: csx.extend(styles.noSelect, failing ? styles.statusBarError : styles.statusBarSuccess, styles.hand, {
marginRight: '5px',
transition: '.4s color, .4s opacity',
opacity: this.props.testedWorking.working ? 1 : 0.5,
}) },
React.createElement(icon_1.Icon, { name: styles.icons.tested, spin: this.props.testedWorking.working })),
failing
? React.createElement("span", { style: { color: styles.errorColor, fontWeight: 'bold' } },
testResultsStats.failCount,
"/",
totalThatRan,
" fail")
: React.createElement("span", { style: { color: styles.successColor, fontWeight: 'bold' } },
testResultsStats.passCount,
"/",
totalThatRan,
" pass"));
return (React.createElement("div", null,
React.createElement("div", { style: csx.extend(styles.statusBar, csx.horizontal, csx.center, styles.noWrap) },
React.createElement("span", { style: csx.extend(styles.statusBarSection, styles.noSelect, styles.hand), onClick: this.toggleErrors, className: "hint--top-right", "data-hint": errorsUpdate.totalCount + " errors. Click to toggle message panel." },
React.createElement("span", { style: csx.extend(errorsUpdate.totalCount ? styles.statusBarError : styles.statusBarSuccess, { transition: 'color .4s' }) },
errorsUpdate.totalCount,
" ",
React.createElement(icon_1.Icon, { name: "times-circle" }),
errorFilteringActive && ' ',
errorFilteringActive && React.createElement("span", null,
"( ",
errorsFilteredCount,
" ",
React.createElement(icon_1.Icon, { name: "filter" }),
")"))),
React.createElement("span", { style: csx.extend(styles.statusBarSection, styles.noSelect, styles.hand) },
React.createElement("span", { className: this.props.tsWorking.working ? "hint--right hint--success" : "hint--right", "data-hint": this.props.tsWorking.working ? "TS Worker Busy" : "TS Worker Idle", style: {
color: this.props.tsWorking.working ? 'white' : 'grey',
transition: 'color .4s'
} },
React.createElement(icon_1.Icon, { name: "rocket" }))),
testStatsRendered,
fileTreeToggleRendered,
activeProjectDetails,
inActiveProjectSection,
filePath
? React.createElement("span", { className: "hint--top-right", "data-hint": "Click to copy the file path to clipboard", "data-clipboard-text": filePath.replace(/\//g, commands.windows ? '\\' : '/'), onClick: function () { return ui.notifyInfoQuickDisappear("File path copied to clipboard"); }, style: csx.extend(styles.statusBarSection, styles.noSelect, styles.hand) }, filePath)
: '',
fileOutputStateRendered,
React.createElement("span", { style: csx.flex }),
React.createElement("span", { style: csx.extend(styles.statusBarSection) },
React.createElement(pendingRequestsIndicator_1.PendingRequestsIndicator, null)),
this.props.liveBuildResults.builtCount !== this.props.liveBuildResults.totalCount &&
React.createElement("span", { style: csx.extend(styles.statusBarSection) },
React.createElement(progress_1.Progress, { current: this.props.liveBuildResults.builtCount, total: this.props.liveBuildResults.totalCount },
this.props.liveBuildResults.builtCount,
" / ",
this.props.liveBuildResults.totalCount)),
React.createElement("span", { style: csx.extend(styles.statusBarSection) }, this.props.socketConnected ?
React.createElement("span", { className: "hint--left hint--success", "data-hint": "Connected to server" },
" ",
React.createElement(icon_1.Icon, { style: { color: styles.successColor, cursor: 'pointer' }, name: "flash", onClick: function () { return ui.notifySuccessNormalDisappear("Connected to alm server"); } }))
: React.createElement("span", { className: "hint--left hint--error", "data-hint": "Disconnected from server" },
" ",
React.createElement(icon_1.Icon, { style: { color: styles.errorColor, cursor: 'pointer' }, name: "spinner", spin: true, onClick: function () { return ui.notifyWarningNormalDisappear("Disconneted from alm server"); } }))),
React.createElement("span", { style: csx.extend(styles.statusBarSection, styles.noSelect, styles.hand) },
React.createElement("span", { style: { paddingRight: '2px' }, onClick: this.giveStar, className: "hint--left", "data-hint": "If you like it then you should have put a star on it \uD83C\uDF1F. Also, go here for support. Version: " + serverState.version + ", TypeScript version: " + serverState.typescriptVersion }, "\uD83C\uDF1F"),
React.createElement("span", { onClick: this.giveRose, className: "hint--left", "data-hint": "Your love keep this rose alive \uD83C\uDF39" }, "\uD83C\uDF39")),
updateRendered)));
};
StatusBar = __decorate([
react_redux_1.connect(function (state) {
return {
errorsExpanded: state.errorsExpanded,
activeProject: state.activeProject,
activeProjectFiles: state.activeProjectFilePathTruthTable,
socketConnected: state.socketConnected,
outputStatusCache: state.outputStatusCache,
liveBuildResults: state.liveBuildResults,
fileTreeShown: state.fileTreeShown,
errorsDisplayMode: state.errorsDisplayMode,
errorsFilter: state.errorsFilter,
tsWorking: state.tsWorking,
testedWorking: state.testedWorking,
};
}),
__metadata("design:paramtypes", [Object])
], StatusBar);
return StatusBar;
}(ui_1.BaseComponent));
exports.StatusBar = StatusBar;