Better handling of empty projects and lifecycle

This commit is contained in:
Nick O'Leary 2018-01-09 15:06:05 +00:00
parent 8a6488b067
commit 13356047dc
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
9 changed files with 96 additions and 40 deletions

View File

@ -118,6 +118,7 @@
text: "Setup project files",
click: function() {
persistentNotifications[notificationId].close();
delete persistentNotifications[notificationId];
RED.projects.showFilesPrompt();
}
}
@ -128,11 +129,13 @@
text: "No thanks",
click: function() {
persistentNotifications[notificationId].close();
delete persistentNotifications[notificationId];
}
}, {
text: "Create default project files",
click: function() {
persistentNotifications[notificationId].close();
delete persistentNotifications[notificationId];
RED.projects.createDefaultFileSet();
}
}
@ -142,7 +145,7 @@
if (!persistentNotifications.hasOwnProperty(notificationId)) {
persistentNotifications[notificationId] = RED.notify(text,options);
} else {
persistentNotifications[notificationId].update(text,msg.timeout);
persistentNotifications[notificationId].update(text,options);
}
} else if (persistentNotifications.hasOwnProperty(notificationId)) {
persistentNotifications[notificationId].close();

View File

@ -85,18 +85,34 @@ RED.notify = (function() {
n.update = (function() {
var nn = n;
return function(msg,timeout) {
return function(msg,options) {
if (typeof msg === "string") {
nn.innerHTML = msg;
} else {
$(nn).empty().append(msg);
}
var timeout;
if (typeof options === 'number') {
timeout = options;
} else if (options !== undefined) {
timeout = options.timeout;
if (options.buttons) {
var buttonSet = $('<div style="margin-top: 20px;" class="ui-dialog-buttonset"></div>').appendTo(nn)
options.buttons.forEach(function(buttonDef) {
var b = $('<button>').html(buttonDef.text).click(buttonDef.click).appendTo(buttonSet);
if (buttonDef.class) {
b.addClass(buttonDef.class);
}
})
}
}
if (timeout !== undefined && timeout > 0) {
window.clearTimeout(nn.timeoutid);
nn.timeoutid = window.setTimeout(nn.close,timeout);
} else {
window.clearTimeout(nn.timeoutid);
}
}
})();

View File

@ -1067,7 +1067,7 @@ RED.projects = (function() {
'open': (function() {
var selectedProject;
return {
title: "Open a project", // TODO: NLS
title: "Select a project to open", // TODO: NLS
content: function() {
return createProjectList({
canSelectActive: false,
@ -1111,6 +1111,7 @@ RED.projects = (function() {
'delete': (function() {
var selectedProject;
return {
title: "Select a project to delete", // TODO: NLS
content: function() {
return createProjectList({
canSelectActive: false,

View File

@ -55,7 +55,7 @@ RED.sidebar.info = (function() {
});
nodeSection.expand();
infoSection = sections.add({
title: RED._("sidebar.info.help"),
title: RED._("sidebar.info.nodeHelp"),
collapsible: true
});
infoSection.expand();

View File

@ -34,6 +34,10 @@
border-left-width: 16px;
overflow: hidden;
}
.notification p:first-child {
font-size: 1.1em;
font-weight: 500;
}
.notification a {
text-decoration: none;
&:hover {

View File

@ -214,8 +214,8 @@
cursor: pointer;
&:hover {
background: #f3f3f3;
border-left-color: #aaa;
border-right-color: #aaa;
// border-left-color: #aaa;
// border-right-color: #aaa;
}
}
i {

View File

@ -85,9 +85,9 @@
"nodeActionDisabled": "node actions disabled within subflow",
"missing-types": "Flows stopped due to missing node types. Check logs for details.",
"restartRequired": "Node-RED must be restarted to enable upgraded modules",
"credentials_load_failed": "Flows stopped due to missing or invalid credentialSecret",
"missing_flow_file": "Could not find the project flow file",
"project_empty": "<p>The project repository is empty.</p><p>Do you want to create a default set of project files?<br/>Otherwise, you will have to manually add files to the project outside of the editor.</p>"
"credentials_load_failed": "<p>Flows stopped due to missing or invalid credentialSecret.</p>",
"missing_flow_file": "<p>Project flow file not found.</p><p>The project is not configured with a flow file.</p>",
"project_empty": "<p>The project is empty.</p><p>Do you want to create a default set of project files?<br/>Otherwise, you will have to manually add files to the project outside of the editor.</p>"
},
"error": "<strong>Error</strong>: __message__",

View File

@ -155,7 +155,8 @@ Project.prototype.loadRemotes = function() {
return gitTools.getRemotes(project.path).then(function(remotes) {
project.remotes = remotes;
}).then(function() {
return project.loadBranches();
project.branches = {};
return project.status();
}).then(function() {
var allRemotes = Object.keys(project.remotes);
var match = "";
@ -189,15 +190,6 @@ Project.prototype.parseRemoteBranch = function (remoteBranch) {
};
Project.prototype.loadBranches = function() {
var project = this;
return gitTools.getBranchInfo(project.path).then(function(branches) {
project.branches = branches;
project.empty = project.branches.empty;
delete project.branches.empty;
});
}
Project.prototype.isEmpty = function () {
return this.empty;
};
@ -439,6 +431,37 @@ Project.prototype.status = function(user) {
code: fetchError.code
}
}
if (result.commits.total === 0 && Object.keys(result.files).length === 0) {
if (!self.empty) {
runtime.events.emit("runtime-event",{
id:"runtime-state",
payload:{
type:"warning",
error:"project_empty",
text:"notification.warnings.project_empty"},
retain:true
}
);
}
self.empty = true;
} else {
if (self.empty) {
if (self.paths.flowFile) {
runtime.events.emit("runtime-event",{id:"runtime-state",retain:true});
} else {
runtime.events.emit("runtime-event",{
id:"runtime-state",
payload:{
type:"warning",
error:"missing_flow_file",
text:"notification.warnings.missing_flow_file"},
retain:true
}
);
}
}
delete self.empty;
}
return result;
}).catch(function(err) {
if (/ambiguous argument/.test(err.message)) {

View File

@ -117,25 +117,28 @@ function parseFilenames(name) {
}
return result;
}
function getBranchInfo(localRepo) {
return runGitCommand(["status","--porcelain","-b"],localRepo).then(function(output) {
var lines = output.split("\n");
var unknownDirs = [];
var branchLineRE = /^## (No commits yet on )?(.+?)($|\.\.\.(.+?)($| \[(ahead (\d+))?.*?(behind (\d+))?\]))/m;
var m = branchLineRE.exec(output);
var result = {}; //commits:{}};
if (m) {
if (m[1]) {
result.empty = true;
}
result.local = m[2];
if (m[4]) {
result.remote = m[4];
}
}
return result;
});
}
// function getBranchInfo(localRepo) {
// return runGitCommand(["status","--porcelain","-b"],localRepo).then(function(output) {
// var lines = output.split("\n");
// var unknownDirs = [];
// var branchLineRE = /^## (No commits yet on )?(.+?)($|\.\.\.(.+?)($| \[(ahead (\d+))?.*?(behind (\d+))?\]))/m;
// console.log(output);
// console.log(lines);
// var m = branchLineRE.exec(output);
// console.log(m);
// var result = {}; //commits:{}};
// if (m) {
// if (m[1]) {
// result.empty = true;
// }
// result.local = m[2];
// if (m[4]) {
// result.remote = m[4];
// }
// }
// return result;
// });
// }
function getStatus(localRepo) {
// parseFilename('"test with space"');
// parseFilename('"test with space" -> knownFile.txt');
@ -147,6 +150,12 @@ function getStatus(localRepo) {
}
return runGitCommand(['rev-list', 'HEAD', '--count'],localRepo).then(function(count) {
result.commits.total = parseInt(count);
}).catch(function(err) {
if (/ambiguous argument/.test(err.message)) {
result.commits.total = 0;
} else {
throw err;
}
}).then(function() {
return runGitCommand(["ls-files","--cached","--others","--exclude-standard"],localRepo).then(function(output) {
var lines = output.split("\n");
@ -174,7 +183,7 @@ function getStatus(localRepo) {
return runGitCommand(["status","--porcelain","-b"],localRepo).then(function(output) {
var lines = output.split("\n");
var unknownDirs = [];
var branchLineRE = /^## (.+?)(?:$|\.\.\.(.+?)(?:$| \[(?:(?:ahead (\d+)(?:,\s*)?)?(?:behind (\d+))?|(gone))\]))/;
var branchLineRE = /^## (?:No commits yet on )?(.+?)(?:$|\.\.\.(.+?)(?:$| \[(?:(?:ahead (\d+)(?:,\s*)?)?(?:behind (\d+))?|(gone))\]))/;
lines.forEach(function(line) {
if (line==="") {
return;
@ -566,7 +575,7 @@ module.exports = {
})
},
getBranches: getBranches,
getBranchInfo: getBranchInfo,
// getBranchInfo: getBranchInfo,
checkoutBranch: function(cwd, branchName, isCreate) {
var args = ['checkout'];
if (isCreate) {