').appendTo(credentialsBox);
var credentialsLeftBox = $('
').appendTo(credentialsBox);
var credentialsEnabledBox = $('
').appendTo(credentialsLeftBox);
$('
'+RED._("projects.encryption-config.enable")+' ').appendTo(credentialsEnabledBox);
var credentialsDisabledBox = $('
').appendTo(credentialsLeftBox);
$('
'+RED._("projects.encryption-config.disable")+' ').appendTo(credentialsDisabledBox);
credentialsLeftBox.find("input[name=projects-encryption-type]").click(function(e) {
var val = $(this).val();
var toEnable;
var toDisable;
if (val === 'enabled') {
toEnable = credentialsEnabledBox;
toDisable = credentialsDisabledBox;
$(".projects-encryption-enabled-row").show();
$(".projects-encryption-disabled-row").hide();
if ($("input[name=projects-encryption-key]:checked").val() === 'custom') {
emptyProjectCredentialInput.focus();
}
} else {
toDisable = credentialsEnabledBox;
toEnable = credentialsDisabledBox;
$(".projects-encryption-enabled-row").hide();
$(".projects-encryption-disabled-row").show();
}
toEnable.css({
borderColor: "#ccc",
borderRightColor: "white"
});
toDisable.css({
borderColor: "white",
borderRightColor: "#ccc"
});
validateForm();
})
row = $('
').appendTo(credentialsRightBox);
$('
'+RED._("projects.encryption-config.copy")+' ').appendTo(row);
row = $('
').appendTo(credentialsRightBox);
$('
'+RED._("projects.encryption-config.use-custom")+' ').appendTo(row);
row = $('
').appendTo(credentialsRightBox);
emptyProjectCredentialInput = $('
').appendTo(row);
emptyProjectCredentialInput.on("change keyup paste", validateForm);
row = $('
').hide().appendTo(credentialsRightBox);
$('
'+RED._("projects.encryption-config.desc8")+'
').appendTo(row);
credentialsRightBox.find("input[name=projects-encryption-key]").click(function() {
var val = $(this).val();
emptyProjectCredentialInput.attr("disabled",val === 'default');
if (val === "custom") {
emptyProjectCredentialInput.focus();
}
validateForm();
});
setTimeout(function() {
credentialsLeftBox.find("input[name=projects-encryption-type][value=enabled]").click();
if (RED.settings.flowEncryptionType !== 'user') {
credentialsRightBox.find("input[name=projects-encryption-key][value=custom]").click();
} else {
credentialsRightBox.find("input[name=projects-encryption-key][value=default]").click();
}
validateForm();
},100);
return container;
},
buttons: function(options) {
return [
{
// id: "clipboard-dialog-cancel",
text: RED._("common.label.back"),
click: function() {
show('default-files',options);
}
},
{
id: "projects-dialog-create-encryption",
text: RED._(options.existingProject?"projects.encryption-config.create-project-files":"projects.encryption-config.create-project"),
class: "primary disabled",
disabled: true,
click: function() {
var encryptionState = $("input[name=projects-encryption-type]:checked").val();
if (encryptionState === 'enabled') {
var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val();
if (encryptionKeyType === 'custom') {
createProjectOptions.credentialSecret = emptyProjectCredentialInput.val();
} else {
// If 'use existing', leave createProjectOptions.credentialSecret blank
// - that will trigger it to use the existing key
// TODO: this option should be disabled if encryption is disabled
}
} else {
// Disabled encryption by explicitly setting credSec to false
createProjectOptions.credentialSecret = false;
}
RED.deploy.setDeployInflight(true);
RED.projects.settings.switchProject(createProjectOptions.name);
var method = "POST";
var url = "projects";
if (options.existingProject) {
createProjectOptions.initialise = true;
method = "PUT";
url = "projects/"+activeProject.name;
}
var self = this;
sendRequest({
url: url,
type: method,
requireCleanWorkspace: true,
handleAuthFail: false,
responses: {
200: function(data) {
createProjectOptions = {};
if (options.existingProject) {
$( self ).dialog( "close" );
} else {
show('create-success');
RED.menu.setDisabled('menu-item-projects-open',false);
RED.menu.setDisabled('menu-item-projects-settings',false);
}
},
400: {
'project_exists': function(error) {
console.log(RED._("projects.encryption-config.already-exists"));
},
'git_error': function(error) {
console.log(RED._("projects.encryption-config.git-error"),error);
},
'git_connection_failed': function(error) {
projectRepoInput.addClass("input-error");
},
'git_auth_failed': function(error) {
projectRepoUserInput.addClass("input-error");
projectRepoPasswordInput.addClass("input-error");
// getRepoAuthDetails(req);
console.log(RED._("projects.encryption-config.git-auth-error"),error);
},
'*': function(error) {
reportUnexpectedError(error);
$( dialog ).dialog( "close" );
}
}
}
},createProjectOptions).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
})
}
}
];
}
}
})(),
'create-success': {
content: function(options) {
var container = $('
');
migrateProjectHeader.appendTo(container);
var body = $('
').appendTo(container);
$('
').text(RED._("projects.create-success.success")).appendTo(body);
$('
').text(RED._("projects.create-success.desc0")).appendTo(body);
$('
').text(RED._("projects.create-success.desc1")).appendTo(body);
$('
').text(RED._("projects.create-success.desc2")).appendTo(body);
return container;
},
buttons: [
{
text: RED._("common.label.done"),
click: function() {
$( this ).dialog( "close" );
}
}
]
},
'create': (function() {
var projectNameInput;
var projectSummaryInput;
var projectFlowFileInput;
var projectSecretInput;
var projectSecretSelect;
var copyProject;
var projectRepoInput;
var projectCloneSecret;
var emptyProjectCredentialInput;
var projectRepoUserInput;
var projectRepoPasswordInput;
var projectNameSublabel;
var projectRepoSSHKeySelect;
var projectRepoPassphrase;
var projectRepoRemoteName
var projectRepoBranch;
var selectedProject;
return {
title: RED._("projects.create.projects"),
content: function(options) {
var projectList = null;
selectedProject = null;
var pendingFormValidation = false;
$.getJSON("projects", function(data) {
projectList = {};
data.projects.forEach(function(p) {
projectList[p] = true;
if (pendingFormValidation) {
pendingFormValidation = false;
validateForm();
}
})
});
var container = $('
');
var row;
var validateForm = function() {
var projectName = projectNameInput.val();
var valid = true;
if (projectNameInputChanged) {
if (projectList === null) {
pendingFormValidation = true;
return;
}
projectNameStatus.empty();
if (!/^[a-zA-Z0-9\-_]+$/.test(projectName) || projectList[projectName]) {
projectNameInput.addClass("input-error");
$('
').appendTo(projectNameStatus);
projectNameValid = false;
valid = false;
if (projectList[projectName]) {
projectNameSublabel.text(RED._("projects.create.already-exists"));
} else {
projectNameSublabel.text(RED._("projects.create.must-contain"));
}
} else {
projectNameInput.removeClass("input-error");
$('
').appendTo(projectNameStatus);
projectNameSublabel.text(RED._("projects.create.must-contain"));
projectNameValid = true;
}
projectNameLastChecked = projectName;
}
valid = projectNameValid;
var projectType = $(".projects-dialog-screen-create-type.selected").data('type');
if (projectType === 'copy') {
if (!copyProject) {
valid = false;
}
} else if (projectType === 'clone') {
var repo = projectRepoInput.val();
// var validRepo = /^(?:file|git|ssh|https?|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?[\w\.@:\/~_-]+(?:\/?|\#[\d\w\.\-_]+?)$/.test(repo);
var validRepo = repo.length > 0 && !/\s/.test(repo);
if (/^https?:\/\/[^/]+@/i.test(repo)) {
$("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.no-info-in-url"));
validRepo = false;
}
if (!validRepo) {
if (projectRepoChanged) {
projectRepoInput.addClass("input-error");
}
valid = false;
} else {
projectRepoInput.removeClass("input-error");
}
if (/^https?:\/\//.test(repo)) {
$(".projects-dialog-screen-create-row-creds").show();
$(".projects-dialog-screen-create-row-sshkey").hide();
} else if (/^(?:ssh|[\S]+?@[\S]+?):(?:\/\/)?/.test(repo)) {
$(".projects-dialog-screen-create-row-creds").hide();
$(".projects-dialog-screen-create-row-sshkey").show();
// if ( !getSelectedSSHKey(projectRepoSSHKeySelect) ) {
// valid = false;
// }
} else {
$(".projects-dialog-screen-create-row-creds").hide();
$(".projects-dialog-screen-create-row-sshkey").hide();
}
} else if (projectType === 'empty') {
var flowFile = projectFlowFileInput.val();
if (flowFile === "" || !/\.json$/.test(flowFile)) {
valid = false;
if (!projectFlowFileInput.hasClass("input-error")) {
projectFlowFileInput.addClass("input-error");
projectFlowFileInput.next().empty().append('
');
}
} else {
if (projectFlowFileInput.hasClass("input-error")) {
projectFlowFileInput.removeClass("input-error");
projectFlowFileInput.next().empty();
}
}
var encryptionState = $("input[name=projects-encryption-type]:checked").val();
if (encryptionState === 'enabled') {
var encryptionKeyType = $("input[name=projects-encryption-key]:checked").val();
if (encryptionKeyType === 'custom') {
valid = valid && emptyProjectCredentialInput.val()!==''
}
}
} else if (projectType === 'open') {
valid = !!selectedProject;
}
$("#projects-dialog-create").prop('disabled',!valid).toggleClass('disabled ui-button-disabled ui-state-disabled',!valid);
}
row = $('
').appendTo(container);
var openProject = $('
'+RED._("projects.create.open")+'').appendTo(row);
var createAsEmpty = $('
'+RED._("projects.create.create")+'').appendTo(row);
// var createAsCopy = $('
Copy existing').appendTo(row);
var createAsClone = $('
'+RED._("projects.create.clone")+'').appendTo(row);
// var createAsClone = $('
Clone Repository').appendTo(row);
row.find(".projects-dialog-screen-create-type").click(function(evt) {
evt.preventDefault();
container.find(".projects-dialog-screen-create-type").removeClass('selected');
$(this).addClass('selected');
container.find(".projects-dialog-screen-create-row").hide();
container.find(".projects-dialog-screen-create-row-"+$(this).data('type')).show();
validateForm();
projectNameInput.focus();
switch ($(this).data('type')) {
case "open": $("#projects-dialog-create").text(RED._("projects.create.open")); break;
case "empty": $("#projects-dialog-create").text(RED._("projects.create.create")); break;
case "clone": $("#projects-dialog-create").text(RED._("projects.create.clone")); break;
}
})
row = $('
').hide().appendTo(container);
createProjectList({
canSelectActive: false,
dblclick: function(project) {
selectedProject = project;
$("#projects-dialog-create").click();
},
select: function(project) {
selectedProject = project;
validateForm();
},
delete: function(project) {
if (projectList) {
delete projectList[project.name];
}
selectedProject = null;
validateForm();
}
}).appendTo(row);
row = $('
').appendTo(container);
$('
'+RED._("projects.create.project-name")+' ').appendTo(row);
var subrow = $('
').appendTo(row);
projectNameInput = $('
').appendTo(subrow);
var projectNameStatus = $('
').appendTo(subrow);
var projectNameInputChanged = false;
var projectNameLastChecked = "";
var projectNameValid;
var checkProjectName;
var autoInsertedName = "";
projectNameInput.on("change keyup paste",function() {
projectNameInputChanged = (projectNameInput.val() !== projectNameLastChecked);
if (checkProjectName) {
clearTimeout(checkProjectName);
} else if (projectNameInputChanged) {
projectNameStatus.empty();
$('
').appendTo(projectNameStatus);
if (projectNameInput.val() === '') {
validateForm();
return;
}
}
checkProjectName = setTimeout(function() {
validateForm();
checkProjectName = null;
},300)
});
projectNameSublabel = $('
'+RED._("projects.create.must-contain")+' ').appendTo(row).find("small");
// Empty Project
row = $('
').appendTo(container);
$('
'+RED._("projects.create.desc")+' ').appendTo(row);
projectSummaryInput = $('
').appendTo(row);
$('
'+RED._("projects.create.opt")+' ').appendTo(row);
row = $('
').appendTo(container);
$('
'+RED._("projects.create.flow-file")+' ').appendTo(row);
subrow = $('
').appendTo(row);
projectFlowFileInput = $('
').val("flow.json")
.on("change keyup paste",validateForm)
.appendTo(subrow);
$('
').appendTo(subrow);
$('
*.json ').appendTo(row);
row = $('
').appendTo(container);
$('
'+RED._("projects.create.credentials")+' ').appendTo(row);
var credentialsBox = $('
').appendTo(row);
var credentialsRightBox = $('
').appendTo(credentialsBox);
var credentialsLeftBox = $('
').appendTo(credentialsBox);
var credentialsEnabledBox = $('
').appendTo(credentialsLeftBox);
$('
'+RED._("projects.create.enable-encryption")+' ').appendTo(credentialsEnabledBox);
var credentialsDisabledBox = $('
').appendTo(credentialsLeftBox);
$('
'+RED._("projects.create.disable-encryption")+' ').appendTo(credentialsDisabledBox);
credentialsLeftBox.find("input[name=projects-encryption-type]").click(function(e) {
var val = $(this).val();
var toEnable;
var toDisable;
if (val === 'enabled') {
toEnable = credentialsEnabledBox;
toDisable = credentialsDisabledBox;
$(".projects-encryption-enabled-row").show();
$(".projects-encryption-disabled-row").hide();
if ($("input[name=projects-encryption-key]:checked").val() === 'custom') {
emptyProjectCredentialInput.focus();
}
} else {
toDisable = credentialsEnabledBox;
toEnable = credentialsDisabledBox;
$(".projects-encryption-enabled-row").hide();
$(".projects-encryption-disabled-row").show();
}
toEnable.css({
borderColor: "#ccc",
borderRightColor: "white"
});
toDisable.css({
borderColor: "white",
borderRightColor: "#ccc"
})
validateForm();
})
row = $('
').appendTo(credentialsRightBox);
$('
'+RED._("projects.create.encryption-key")+' ').appendTo(row);
// row = $('
').appendTo(credentialsRightBox);
emptyProjectCredentialInput = $('
').appendTo(row);
emptyProjectCredentialInput.on("change keyup paste", validateForm);
$('
'+RED._("projects.create.desc0")+' ').appendTo(row);
row = $('
').hide().appendTo(credentialsRightBox);
$('
'+RED._("projects.create.desc1")+'
').appendTo(row);
credentialsRightBox.find("input[name=projects-encryption-key]").click(function() {
var val = $(this).val();
emptyProjectCredentialInput.attr("disabled",val === 'default');
if (val === "custom") {
emptyProjectCredentialInput.focus();
}
validateForm();
})
// Clone Project
row = $('
').appendTo(container);
$('
'+RED._("projects.create.git-url")+' ').appendTo(row);
projectRepoInput = $('
').appendTo(row);
$('
'+RED._("projects.create.protocols")+' ').appendTo(row);
var projectRepoChanged = false;
var lastProjectRepo = "";
projectRepoInput.on("change keyup paste",function() {
projectRepoChanged = true;
var repo = $(this).val();
if (lastProjectRepo !== repo) {
$("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.protocols"));
}
lastProjectRepo = repo;
var m = /\/([^/]+?)(?:\.git)?$/.exec(repo);
if (m) {
var projectName = projectNameInput.val();
if (projectName === "" || projectName === autoInsertedName) {
autoInsertedName = m[1];
projectNameInput.val(autoInsertedName);
projectNameInput.change();
}
}
validateForm();
});
var cloneAuthRows = $('
').hide().appendTo(container);
row = $('
').hide().appendTo(cloneAuthRows);
$('
'+RED._("projects.create.auth-failed")+'
').appendTo(row);
// Repo credentials - username/password ----------------
row = $('
').hide().appendTo(cloneAuthRows);
var subrow = $('
').appendTo(row);
$('
'+RED._("projects.create.username")+' ').appendTo(subrow);
projectRepoUserInput = $('
').appendTo(subrow);
subrow = $('
').appendTo(row);
$('
'+RED._("projects.create.password")+' ').appendTo(subrow);
projectRepoPasswordInput = $('
').appendTo(subrow);
// -----------------------------------------------------
// Repo credentials - key/passphrase -------------------
row = $('
').hide().appendTo(cloneAuthRows);
subrow = $('
').appendTo(row);
$('
'+RED._("projects.create.ssh-key")+' ').appendTo(subrow);
projectRepoSSHKeySelect = $("
",{style:"width: 100%"}).appendTo(subrow);
$.getJSON("settings/user/keys", function(data) {
var count = 0;
data.keys.forEach(function(key) {
projectRepoSSHKeySelect.append($(" ").val(key.name).text(key.name));
count++;
});
if (count === 0) {
projectRepoSSHKeySelect.addClass("input-error");
projectRepoSSHKeySelect.attr("disabled",true);
sshwarningRow.show();
} else {
projectRepoSSHKeySelect.removeClass("input-error");
projectRepoSSHKeySelect.attr("disabled",false);
sshwarningRow.hide();
}
});
subrow = $('
').appendTo(row);
$(''+RED._("projects.create.passphrase")+' ').appendTo(subrow);
projectRepoPassphrase = $(' ').appendTo(subrow);
subrow = $('
').appendTo(cloneAuthRows);
var sshwarningRow = $('
').hide().appendTo(subrow);
$(' '+RED._("projects.create.desc2")+'
').appendTo(sshwarningRow);
subrow = $('').appendTo(sshwarningRow);
$('
'+RED._("projects.create.add-ssh-key")+' ').appendTo(subrow).click(function(e) {
e.preventDefault();
$('#projects-dialog-cancel').click();
RED.userSettings.show('gitconfig');
setTimeout(function() {
$("#user-settings-gitconfig-add-key").click();
},500);
});
// -----------------------------------------------------
// Secret - clone
row = $('
').appendTo(container);
$('
'+RED._("projects.create.credentials-encryption-key")+' ').appendTo(row);
projectSecretInput = $('
').appendTo(row);
switch(options.screen||"empty") {
case "empty": createAsEmpty.click(); break;
case "open": openProject.click(); break;
case "clone": createAsClone.click(); break;
}
setTimeout(function() {
if ((options.screen||"empty") !== "open") {
projectNameInput.focus();
} else {
$("#projects-dialog-project-list-search").focus();
}
},50);
return container;
},
buttons: function(options) {
var initialLabel;
switch (options.screen||"empty") {
case "open": initialLabel = RED._("projects.create.open"); break;
case "empty": initialLabel = RED._("projects.create.create"); break;
case "clone": initialLabel = RED._("projects.create.clone"); break;
}
return [
{
id: "projects-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
$( this ).dialog( "close" );
}
},
{
id: "projects-dialog-create",
text: initialLabel,
class: "primary disabled",
disabled: true,
click: function() {
var projectType = $(".projects-dialog-screen-create-type.selected").data('type');
var projectData = {
name: projectNameInput.val(),
}
if (projectType === 'empty') {
projectData.summary = projectSummaryInput.val();
projectData.files = {
flow: projectFlowFileInput.val()
};
var encryptionState = $("input[name=projects-encryption-type]:checked").val();
if (encryptionState === 'enabled') {
projectData.credentialSecret = emptyProjectCredentialInput.val();
} else {
// Disabled encryption by explicitly setting credSec to false
projectData.credentialSecret = false;
}
} else if (projectType === 'copy') {
projectData.copy = copyProject.name;
} else if (projectType === 'clone') {
projectData.credentialSecret = projectSecretInput.val();
var repoUrl = projectRepoInput.val();
var metaData = {};
if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(repoUrl)) {
var selected = projectRepoSSHKeySelect.val();//false;//getSelectedSSHKey(projectRepoSSHKeySelect);
if ( selected ) {
projectData.git = {
remotes: {
'origin': {
url: repoUrl,
keyFile: selected,
passphrase: projectRepoPassphrase.val()
}
}
};
}
else {
console.log(RED._("projects.create.cant-get-ssh-key-path"));
return;
}
}
else {
projectData.git = {
remotes: {
'origin': {
url: repoUrl,
username: projectRepoUserInput.val(),
password: projectRepoPasswordInput.val()
}
}
};
}
} else if (projectType === 'open') {
return switchProject(selectedProject.name,function(err,data) {
dialog.dialog( "close" );
if (err) {
if (err.error !== 'credentials_load_failed') {
console.log(RED._("projects.create.unexpected_error"),err)
}
}
})
}
$(".projects-dialog-screen-create-row-auth-error").hide();
$("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.protocols"));
projectRepoUserInput.removeClass("input-error");
projectRepoPasswordInput.removeClass("input-error");
projectRepoSSHKeySelect.removeClass("input-error");
projectRepoPassphrase.removeClass("input-error");
RED.deploy.setDeployInflight(true);
RED.projects.settings.switchProject(projectData.name);
sendRequest({
url: "projects",
type: "POST",
handleAuthFail: false,
responses: {
200: function(data) {
dialog.dialog( "close" );
},
400: {
'project_exists': function(error) {
console.log(RED._("projects.create.already-exists-2"));
},
'git_error': function(error) {
console.log(RED._("projects.create.git-error"),error);
},
'git_connection_failed': function(error) {
projectRepoInput.addClass("input-error");
$("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.con-failed"));
},
'git_not_a_repository': function(error) {
projectRepoInput.addClass("input-error");
$("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.not-git"));
},
'git_repository_not_found': function(error) {
projectRepoInput.addClass("input-error");
$("#projects-dialog-screen-create-project-repo-label small").text(RED._("projects.create.no-resource"));
},
'git_auth_failed': function(error) {
$(".projects-dialog-screen-create-row-auth-error").show();
projectRepoUserInput.addClass("input-error");
projectRepoPasswordInput.addClass("input-error");
// getRepoAuthDetails(req);
projectRepoSSHKeySelect.addClass("input-error");
projectRepoPassphrase.addClass("input-error");
},
'missing_flow_file': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'project_empty': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'credentials_load_failed': function(error) {
// This is handled via a runtime notification.
dialog.dialog("close");
},
'*': function(error) {
reportUnexpectedError(error);
$( dialog ).dialog( "close" );
}
}
}
},projectData).then(function() {
RED.events.emit("project:change", {name:name});
}).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
})
}
}
]
}
}
})()
}
}
function switchProject(name,done) {
RED.deploy.setDeployInflight(true);
RED.projects.settings.switchProject(name);
sendRequest({
url: "projects/"+name,
type: "PUT",
requireCleanWorkspace: true,
responses: {
200: function(data) {
done(null,data);
},
400: {
'*': done
},
}
},{active:true}).then(function() {
RED.events.emit("project:change", {name:name});
}).always(function() {
setTimeout(function() {
RED.deploy.setDeployInflight(false);
},500);
})
}
function deleteProject(row,name,done) {
var cover = $('
').css({
background:"white",
position:"absolute",
top:0,right:0,bottom:0,left:"100%",
overflow:"hidden",
padding: "5px 20px",
transition: "left 0.4s",
whitespace: "nowrap",
width:"1000px"
}).click(function(evt) { evt.stopPropagation(); }).appendTo(row);
$('
').css({"lineHeight":"40px"}).text(RED._("projects.delete.confirm")).appendTo(cover);
$(''+RED._("common.label.cancel")+' ')
.appendTo(cover)
.click(function(e) {
e.stopPropagation();
cover.remove();
done(true);
});
$(''+RED._("common.label.delete")+' ')
.appendTo(cover)
.click(function(e) {
e.stopPropagation();
cover.remove();
sendRequest({
url: "projects/"+name,
type: "DELETE",
responses: {
200: function(data) {
done(false);
},
400: {
'unexpected_error': function(error) {
cover.remove();
done(true);
}
}
}
});
});
setTimeout(function() {
cover.css("left",0);
},50);
//
}
function show(s,options) {
if (!dialog) {
RED.projects.init();
}
var screen = screens[s];
var container = screen.content(options||{});
dialogBody.empty();
var buttons = screen.buttons;
if (typeof buttons === 'function') {
buttons = buttons(options||{});
}
dialog.dialog('option','buttons',buttons);
dialogBody.append(container);
dialog.dialog('option','title',screen.title||"");
dialog.dialog("open");
dialog.dialog({position: { 'my': 'center top', 'at': 'center top+10%', 'of': window }});
}
function createProjectList(options) {
options = options||{};
var height = options.height || "300px";
var container = $('
',{class:"projects-dialog-project-list-container" });
var filterTerm = "";
var searchDiv = $("",{class:"red-ui-search-container"}).appendTo(container);
var searchInput = $('
').appendTo(searchDiv).searchBox({
//data-i18n="[placeholder]menu.label.searchInput"
delay: 200,
change: function() {
filterTerm = $(this).val().toLowerCase();
list.editableList('filter');
if (selectedListItem && !selectedListItem.is(":visible")) {
selectedListItem.children().children().removeClass('selected');
selectedListItem = list.children(":visible").first();
selectedListItem.children().children().addClass('selected');
if (options.select) {
options.select(selectedListItem.children().data('data'));
}
} else {
selectedListItem = list.children(":visible").first();
selectedListItem.children().children().addClass('selected');
if (options.select) {
options.select(selectedListItem.children().data('data'));
}
}
ensureSelectedIsVisible();
}
});
var selectedListItem;
searchInput.on('keydown',function(evt) {
if (evt.keyCode === 40) {
evt.preventDefault();
// Down
var next = selectedListItem;
if (selectedListItem) {
do {
next = next.next();
} while(next.length !== 0 && !next.is(":visible"));
if (next.length === 0) {
return;
}
selectedListItem.children().children().removeClass('selected');
} else {
next = list.children(":visible").first();
}
selectedListItem = next;
selectedListItem.children().children().addClass('selected');
if (options.select) {
options.select(selectedListItem.children().data('data'));
}
ensureSelectedIsVisible();
} else if (evt.keyCode === 38) {
evt.preventDefault();
// Up
var prev = selectedListItem;
if (selectedListItem) {
do {
prev = prev.prev();
} while(prev.length !== 0 && !prev.is(":visible"));
if (prev.length === 0) {
return;
}
selectedListItem.children().children().removeClass('selected');
} else {
prev = list.children(":visible").first();
}
selectedListItem = prev;
selectedListItem.children().children().addClass('selected');
if (options.select) {
options.select(selectedListItem.children().data('data'));
}
ensureSelectedIsVisible();
} else if (evt.keyCode === 13) {
evt.preventDefault();
// Enter
if (selectedListItem) {
if (options.dblclick) {
options.dblclick(selectedListItem.children().data('data'));
}
}
}
});
searchInput.i18n();
var ensureSelectedIsVisible = function() {
var selectedEntry = list.find(".projects-dialog-project-list-entry.selected").parent().parent();
if (selectedEntry.length === 1) {
var scrollWindow = listContainer;
var scrollHeight = scrollWindow.height();
var scrollOffset = scrollWindow.scrollTop();
var y = selectedEntry.position().top;
var h = selectedEntry.height();
if (y+h > scrollHeight) {
scrollWindow.animate({scrollTop: '-='+(scrollHeight-y-h)},50);
} else if (y<0) {
scrollWindow.animate({scrollTop: '+='+y},50);
}
}
}
var listContainer = $('
',{class:"projects-dialog-project-list-inner-container" }).appendTo(container);
var list = $('
',{class:"projects-dialog-project-list"}).appendTo(listContainer).editableList({
addButton: false,
height:"auto",
scrollOnAdd: false,
addItem: function(row,index,entry) {
var header = $('
',{class:"projects-dialog-project-list-entry"}).appendTo(row);
$(' ').appendTo(header);
$(' ').text(entry.name).appendTo(header);
if (activeProject && activeProject.name === entry.name) {
header.addClass("projects-list-entry-current");
$(''+RED._("projects.create-project-list.current")+' ').appendTo(header);
if (options.canSelectActive === false) {
// active project cannot be selected; so skip the rest
return
}
}
header.addClass("selectable");
var tools = $('
').appendTo(header);
$(' ')
.appendTo(tools)
.click(function(e) {
e.stopPropagation();
e.preventDefault();
deleteProject(row,entry.name, function(cancelled) {
if (!cancelled) {
row.fadeOut(300,function() {
list.editableList('removeItem',entry);
if (options.delete) {
options.delete(entry);
}
});
}
})
});
row.click(function(evt) {
$('.projects-dialog-project-list-entry').removeClass('selected');
header.addClass('selected');
selectedListItem = row.parent();
if (options.select) {
options.select(entry);
}
ensureSelectedIsVisible();
searchInput.focus();
})
if (options.dblclick) {
row.dblclick(function(evt) {
evt.preventDefault();
options.dblclick(entry);
})
}
},
filter: function(data) {
if (filterTerm === "") { return true; }
return data.name.toLowerCase().indexOf(filterTerm) !== -1;
}
});
$.getJSON("projects", function(data) {
data.projects.forEach(function(project) {
list.editableList('addItem',{name:project});
});
})
return container;
}
function requireCleanWorkspace(done) {
if (RED.nodes.dirty()) {
var message = RED._("projects.require-clean.confirm");
var cleanNotification = RED.notify(message,{
type:"info",
fixed: true,
modal: true,
buttons: [
{
//id: "node-dialog-delete",
//class: 'leftButton',
text: RED._("common.label.cancel"),
click: function() {
cleanNotification.close();
done(true);
}
},{
text: RED._("common.label.cont"),
click: function() {
cleanNotification.close();
done(false);
}
}
]
});
}
}
function sendRequest(options,body) {
// dialogBody.hide();
// console.log(options.url,body);
if (options.requireCleanWorkspace && RED.nodes.dirty()) {
var thenCallback;
var alwaysCallback;
requireCleanWorkspace(function(cancelled) {
if (cancelled) {
if (options.cancel) {
options.cancel();
if (alwaysCallback) {
alwaysCallback();
}
}
} else {
delete options.requireCleanWorkspace;
sendRequest(options,body).then(function() {
if (thenCallback) {
thenCallback();
}
}).always(function() {
if (alwaysCallback) {
alwaysCallback();
}
})
}
})
// What follows is a very hacky Promise-like api thats good enough
// for our needs.
return {
then: function(done) {
thenCallback = done;
return { always: function(done) { alwaysCallback = done; }}
},
always: function(done) { alwaysCallback = done; }
}
}
var start = Date.now();
// TODO: this is specific to the dialog-based requests
$(".projects-dialog-spinner").show();
$("#projects-dialog").parent().find(".ui-dialog-buttonset").children().css("visibility","hidden")
if (body) {
options.data = JSON.stringify(body);
options.contentType = "application/json; charset=utf-8";
}
var resultCallback;
var resultCallbackArgs;
return $.ajax(options).done(function(data,textStatus,xhr) {
if (options.responses && options.responses[200]) {
resultCallback = options.responses[200];
resultCallbackArgs = data;
}
}).fail(function(xhr,textStatus,err) {
if (options.responses && options.responses[xhr.status]) {
var responses = options.responses[xhr.status];
if (typeof responses === 'function') {
resultCallback = responses;
resultCallbackArgs = {error:responses.statusText};
return;
} else if (options.handleAuthFail !== false && xhr.responseJSON.error === 'git_auth_failed') {
var url = activeProject.git.remotes[xhr.responseJSON.remote||options.remote||'origin'].fetch;
var message = $(''+
'
'+RED._("projects.send-req.auth-req")+':
'+
'
'+
'
');
var isSSH = false;
if (/^https?:\/\//.test(url)) {
$(''+RED._("projects.send-req.username")+'
'+
''+RED._("projects.send-req.password")+'
').appendTo(message);
} else if (/^(?:ssh|[\d\w\.\-_]+@[\w\.]+):(?:\/\/)?/.test(url)) {
isSSH = true;
var row = $('
').appendTo(message);
$('SSH Key ').appendTo(row);
var projectRepoSSHKeySelect = $('').width('70%').appendTo(row);
$.getJSON("settings/user/keys", function(data) {
var count = 0;
data.keys.forEach(function(key) {
projectRepoSSHKeySelect.append($(" ").val(key.name).text(key.name));
count++;
});
if (count === 0) {
//TODO: handle no keys yet setup
}
});
row = $('
').appendTo(message);
$(''+RED._("projects.send-req.passphrase")+' ').appendTo(row);
$(' ').appendTo(row);
}
var notification = RED.notify(message,{
type:"error",
fixed: true,
modal: true,
buttons: [
{
//id: "node-dialog-delete",
//class: 'leftButton',
text: RED._("common.label.cancel"),
click: function() {
notification.close();
}
},{
text: $(' Retry '),
click: function() {
body = body || {};
var authBody = {};
if (isSSH) {
authBody.keyFile = $('#projects-user-auth-key').val();
authBody.passphrase = $('#projects-user-auth-passphrase').val();
} else {
authBody.username = $('#projects-user-auth-username').val();
authBody.password = $('#projects-user-auth-password').val();
}
var done = function(err) {
if (err) {
console.log(RED._("projects.send-req.update-failed"));
console.log(err);
} else {
sendRequest(options,body);
notification.close();
}
}
sendRequest({
url: "projects/"+activeProject.name+"/remotes/"+(xhr.responseJSON.remote||options.remote||'origin'),
type: "PUT",
responses: {
0: function(error) {
done(error,null);
},
200: function(data) {
done(null,data);
},
400: {
'unexpected_error': function(error) {
done(error,null);
}
},
}
},{auth:authBody});
}
}
]
});
return;
} else if (responses[xhr.responseJSON.error]) {
resultCallback = responses[xhr.responseJSON.error];
resultCallbackArgs = xhr.responseJSON;
return;
} else if (responses['*']) {
resultCallback = responses['*'];
resultCallbackArgs = xhr.responseJSON;
return;
}
}
console.log(RED._("projects.send-req.unhandled")+":");
console.log(xhr);
console.log(textStatus);
console.log(err);
}).always(function() {
var delta = Date.now() - start;
delta = Math.max(0,500-delta);
setTimeout(function() {
// dialogBody.show();
$(".projects-dialog-spinner").hide();
$("#projects-dialog").parent().find(".ui-dialog-buttonset").children().css("visibility","")
if (resultCallback) {
resultCallback(resultCallbackArgs)
}
},delta);
});
}
function createBranchList(options) {
var branchFilterTerm = "";
var branchFilterCreateItem;
var branches = [];
var branchPrefix = "";
var container = $('