diff --git a/editor/js/settings.js b/editor/js/settings.js index 8a27f7bc5..19a385166 100644 --- a/editor/js/settings.js +++ b/editor/js/settings.js @@ -202,6 +202,7 @@ RED.settings = (function () { return { init: init, load: load, + loadUserSettings: loadUserSettings, set: set, get: get, remove: remove, diff --git a/editor/js/ui/keyboard.js b/editor/js/ui/keyboard.js index cb2e46a32..ca294be78 100644 --- a/editor/js/ui/keyboard.js +++ b/editor/js/ui/keyboard.js @@ -57,8 +57,24 @@ RED.keyboard = (function() { 173:189 } + function migrateOldKeymap() { + if ('localStorage' in window && window['localStorage'] !== null) { + var oldKeyMap = localStorage.getItem("keymap"); + if (oldKeyMap !== null) { + localStorage.removeItem("keymap"); + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.keymap = JSON.parse(oldKeyMap); + RED.settings.set('editor',currentEditorSettings); + } + } + } function init() { - var userKeymap = RED.settings.get('keymap') || {}; + // Migrate from pre-0.18 + migrateOldKeymap(); + + var currentEditorSettings = RED.settings.get('editor') || {}; + var userKeymap = currentEditorSettings.keymap || {}; + $.getJSON("red/keymap.json",function(data) { for (var scope in data) { if (data.hasOwnProperty(scope)) { @@ -67,12 +83,12 @@ RED.keyboard = (function() { if (keys.hasOwnProperty(key)) { if (!userKeymap.hasOwnProperty(keys[key])) { addHandler(scope,key,keys[key],false); - defaultKeyMap[keys[key]] = { - scope:scope, - key:key, - user:false - }; } + defaultKeyMap[keys[key]] = { + scope:scope, + key:key, + user:false + }; } } } @@ -369,8 +385,11 @@ RED.keyboard = (function() { container.removeClass('keyboard-shortcut-entry-expanded'); var shortcut = RED.keyboard.getShortcut(object.id); var userKeymap = RED.settings.get('keymap') || {}; - delete userKeymap[object.id]; - RED.settings.set('keymap',userKeymap); + + var currentEditorSettings = RED.settings.get('editor') || {}; + var userKeymap = currentEditorSettings.keymap || {}; + userKeymap[object.id] = null; + RED.settings.set('editor',currentEditorSettings); var obj = { id:object.id, @@ -419,9 +438,11 @@ RED.keyboard = (function() { object.scope = scope; RED.keyboard.add(object.scope,object.key,object.id,true); } - var userKeymap = RED.settings.get('keymap') || {}; + + var currentEditorSettings = RED.settings.get('editor') || {}; + var userKeymap = currentEditorSettings.keymap || {}; userKeymap[object.id] = RED.keyboard.getShortcut(object.id); - RED.settings.set('keymap',userKeymap); + RED.settings.set('editor',currentEditorSettings); } } } diff --git a/editor/js/ui/projectUserSettings.js b/editor/js/ui/projectUserSettings.js index 9dd970684..2401e5985 100644 --- a/editor/js/ui/projectUserSettings.js +++ b/editor/js/ui/projectUserSettings.js @@ -15,249 +15,124 @@ **/ RED.projects.userSettings = (function() { - - var trayWidth = 700; - var settingsVisible = false; - - function createRemoteRepositorySection(pane) { - var title = $('

').text("Version Control").appendTo(pane); - var editGitUserButton = $('') - .appendTo(title) - .click(function(evt) { - editGitUserButton.hide(); - formButtons.show(); - - gitUsernameLabel.hide(); - gitUsernameInput.show(); - gitEmailLabel.hide(); - gitEmailInput.show(); - }); - - var gitconfigContainer = $('
').appendTo(pane); - var subtitle = $('

').text("Committer Details").appendTo(gitconfigContainer); - $('
').appendTo(subtitle).find('small').text("Leave blank to use system default"); - - var row = $('
').appendTo(gitconfigContainer); - $('').text('Username').appendTo(row); - var gitUsernameLabel = $('
').appendTo(row); - var gitUsernameInput = $('').hide().appendTo(row); - - row = $('
').appendTo(gitconfigContainer); - $('').text('Email').appendTo(row); - var gitEmailLabel = $('
').appendTo(row); - var gitEmailInput = $('').hide().appendTo(row); - - // var formButtons = $('') - var formButtonArea = $('
').appendTo(gitconfigContainer); - var formButtons = $('') - .hide().appendTo(formButtonArea); - - // var sshkeyTitle = $('

').text("SSH Keys").appendTo(gitconfigContainer); - // var generateSshKeyButton = $('') - // .appendTo(sshkeyTitle) - // .click(function(evt) { - // console.log('click generateSshKeyButton'); - // }); + var gitUsernameInput; + var gitEmailInput; - // row = $('').appendTo(gitconfigContainer); - // var sshkeysList = $('
    ').appendTo(row); - // sshkeysList.editableList({ - // addButton: false, - // height: 'auto', - // addItem: function(outer,index,entry) { - - // var header = $('
    ').appendTo(outer); - // entry.header = $('').text(entry.path||"Add new remote").appendTo(header); - // var body = $('
    ').appendTo(outer); - // entry.body = body; - // if (entry.path) { - // entry.removeButton = $('') - // // .hide() - // .appendTo(header) - // .click(function(e) { - // entry.removed = true; - // body.fadeOut(100); - // entry.header.css("text-decoration","line-through") - // entry.header.css("font-style","italic") - // if (entry.copyToClipboard) { - // entry.copyToClipboard.hide(); - // } - // $(this).hide(); - // }); - // if (entry.data) { - // entry.copyToClipboard = $('') - // // .hide() - // .appendTo(header) - // .click(function(e) { - // var textarea = document.createElement("textarea"); - // textarea.style.position = 'fixed'; - // textarea.style.top = 0; - // textarea.style.left = 0; - // textarea.style.width = '2em'; - // textarea.style.height = '2em'; - // textarea.style.padding = 0; - // textarea.style.border = 'none'; - // textarea.style.outline = 'none'; - // textarea.style.boxShadow = 'none'; - // textarea.style.background = 'transparent'; - // textarea.value = entry.data; - // document.body.appendChild(textarea); - // textarea.select(); - // try { - // var ret = document.execCommand('copy'); - // var msg = ret ? 'successful' : 'unsuccessful'; - // console.log('Copy text command was ' + msg); - // } catch (err) { - // console.log('Oops unable to copy'); - // } - // document.body.removeChild(textarea); - // }); - // } - // } - // } - // }); - - // var remoteListAddButton = row.find(".red-ui-editableList-addButton").hide(); - - var hideGitUserEditForm = function() { - editGitUserButton.show(); - formButtons.hide(); - // $('.projects-dialog-remote-list-entry-delete').hide(); - // remoteListAddButton.hide(); - - gitUsernameLabel.show(); - gitUsernameInput.hide(); - gitEmailLabel.show(); - gitEmailInput.hide(); - - } - - $('') - .appendTo(formButtons) - .click(function(evt) { - evt.preventDefault(); - hideGitUserEditForm(); - }); - - var saveButton = $('') - .appendTo(formButtons) - .click(function(evt) { - evt.preventDefault(); - var spinner = utils.addSpinnerOverlay(gitconfigContainer); - - var body = { - git: { - user: { - name: gitUsernameInput.val(), - email: gitEmailInput.val() - } - } - } - - var done = function(err) { - spinner.remove(); - if (err) { - console.log(err); - return; - } - hideGitUserEditForm(); - } - - utils.sendRequest({ - url: "settings/user", - type: "POST", - responses: { - 0: function(error) { - done(error); - }, - 200: function(data) { - gitUsernameLabel.text(body.git.user.name); - gitEmailLabel.text(body.git.user.email); - done(); - }, - 400: { - 'unexpected_error': function(error) { - console.log(error); - done(error); - } - }, - } - },body); - }); - var updateForm = function() { - // sshkeysList.editableList('empty'); - // if (activeProject.git.hasOwnProperty('remotes')) { - // for (var name in activeProject.git.remotes) { - // if (activeProject.git.remotes.hasOwnProperty(name)) { - // remotesList.editableList('addItem',{name:name,urls:activeProject.git.remotes[name]}); - // } - // } - // } - // var sshkeyFiles = ["/User/hideki/.node-red/sshkeys/node-red-ssh-test01", "/User/hideki/.node-red/sshkeys/node-red-ssh-test02"]; - // if ( sshkeyFiles ) { - // sshkeyFiles.map(function(sshkeyFilePath) { - // sshkeysList.editableList('addItem', {path: sshkeyFilePath, data: 'XXXXXXX'}); - // }); - // } + function createRemoteRepositorySection(pane) { + + var currentGitSettings = RED.settings.get('git') || {}; + currentGitSettings.user = currentGitSettings.user || {}; + + + + var title = $('

    ').text("Committer Details").appendTo(pane); + + var gitconfigContainer = $('').appendTo(pane); + $('
    ').appendTo(gitconfigContainer).text("Leave blank to use system default"); + + var row = $('').appendTo(gitconfigContainer); + $('').text('Username').appendTo(row); + gitUsernameInput = $('').appendTo(row); + gitUsernameInput.val(currentGitSettings.user.name||""); + + row = $('').appendTo(gitconfigContainer); + $('').text('Email').appendTo(row); + gitEmailInput = $('').appendTo(row); + gitEmailInput.val(currentGitSettings.user.email||""); + // var sshkeyTitle = $('

    ').text("SSH Keys").appendTo(gitconfigContainer); + // var generateSshKeyButton = $('') + // .appendTo(sshkeyTitle) + // .click(function(evt) { + // console.log('click generateSshKeyButton'); + // }); + + // row = $('').appendTo(gitconfigContainer); + // var sshkeysList = $('
      ').appendTo(row); + // sshkeysList.editableList({ + // addButton: false, + // height: 'auto', + // addItem: function(outer,index,entry) { + + // var header = $('
      ').appendTo(outer); + // entry.header = $('').text(entry.path||"Add new remote").appendTo(header); + // var body = $('
      ').appendTo(outer); + // entry.body = body; + // if (entry.path) { + // entry.removeButton = $('') + // // .hide() + // .appendTo(header) + // .click(function(e) { + // entry.removed = true; + // body.fadeOut(100); + // entry.header.css("text-decoration","line-through") + // entry.header.css("font-style","italic") + // if (entry.copyToClipboard) { + // entry.copyToClipboard.hide(); + // } + // $(this).hide(); + // }); + // if (entry.data) { + // entry.copyToClipboard = $('') + // // .hide() + // .appendTo(header) + // .click(function(e) { + // var textarea = document.createElement("textarea"); + // textarea.style.position = 'fixed'; + // textarea.style.top = 0; + // textarea.style.left = 0; + // textarea.style.width = '2em'; + // textarea.style.height = '2em'; + // textarea.style.padding = 0; + // textarea.style.border = 'none'; + // textarea.style.outline = 'none'; + // textarea.style.boxShadow = 'none'; + // textarea.style.background = 'transparent'; + // textarea.value = entry.data; + // document.body.appendChild(textarea); + // textarea.select(); + // try { + // var ret = document.execCommand('copy'); + // var msg = ret ? 'successful' : 'unsuccessful'; + // console.log('Copy text command was ' + msg); + // } catch (err) { + // console.log('Oops unable to copy'); + // } + // document.body.removeChild(textarea); + // }); + // } + // } + // } + // }); + + // var remoteListAddButton = row.find(".red-ui-editableList-addButton").hide(); + } + + function createSettingsPane(activeProject) { + var pane = $('
      '); + createRemoteRepositorySection(pane); + return pane; + } + + var utils; + function init(_utils) { + utils = _utils; + RED.userSettings.add({ + id:'gitconfig', + title: "Git config", // TODO: nls + get: createSettingsPane, + close: function() { + var currentGitSettings = RED.settings.get('git') || {}; + currentGitSettings.user = currentGitSettings.user || {}; + currentGitSettings.user.name = gitUsernameInput.val(); + currentGitSettings.user.email = gitEmailInput.val(); + RED.settings.set('git', currentGitSettings); } + }); - utils.sendRequest({ - url: "settings/user", - type: "GET", - responses: { - 0: function(error) { - console.log(error); - }, - 200: function(result) { - console.log(result); - if ( result && result.git && result.git.user ) { - var username = result.git.user.name || ""; - var email = result.git.user.email || ""; - gitUsernameLabel.text(username); - gitUsernameInput.val(username); - gitEmailLabel.text(email); - gitEmailInput.val(email); - } - }, - 400: { - 'unexpected_error': function(error) { - console.log(error); - } - } - } - }) + } - updateForm(); - } - - function createSettingsPane(activeProject) { - var pane = $('
      '); - createRemoteRepositorySection(pane); - return pane; - } - - var popover; - - var utils; - function init(_utils) { - utils = _utils; - RED.userSettings.add({ - id:'gitconfig', - title: "Git config", // TODO: nls - get: createSettingsPane, - close: function() { - if (popover) { - popover.close(); - popover = null; - } - } - }); - - } - - return { - init: init, - }; - })(); - \ No newline at end of file + return { + init: init, + }; +})(); diff --git a/editor/js/ui/userSettings.js b/editor/js/ui/userSettings.js index e7c5cb395..594129f87 100644 --- a/editor/js/ui/userSettings.js +++ b/editor/js/ui/userSettings.js @@ -127,10 +127,13 @@ RED.userSettings = (function() { var pane = $('
      '); + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + viewSettings.forEach(function(section) { $('

      ').text(RED._(section.title)).appendTo(pane); section.options.forEach(function(opt) { - var initialState = RED.settings.get(opt.setting); + var initialState = currentEditorSettings.view[opt.setting]; var row = $('').appendTo(pane); var input; if (opt.toggle) { @@ -147,7 +150,10 @@ RED.userSettings = (function() { function setSelected(id, value) { var opt = allSettings[id]; - RED.settings.set(opt.setting,value); + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + currentEditorSettings.view[opt.setting] = value; + RED.settings.set('editor', currentEditorSettings); var callback = opt.onchange; if (typeof callback === 'string') { callback = RED.actions.get(callback); @@ -158,8 +164,9 @@ RED.userSettings = (function() { } function toggle(id) { var opt = allSettings[id]; - var state = RED.settings.get(opt.setting); - setSelected(id,!state); + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + setSelected(id,!currentEditorSettings.view[opt.setting]); } @@ -185,21 +192,26 @@ RED.userSettings = (function() { } }) + var currentEditorSettings = RED.settings.get('editor') || {}; + currentEditorSettings.view = currentEditorSettings.view || {}; + var editorSettingsChanged = false; viewSettings.forEach(function(section) { section.options.forEach(function(opt) { if (opt.oldSetting) { var oldValue = RED.settings.get(opt.oldSetting); if (oldValue !== undefined && oldValue !== null) { - RED.settings.set(opt.setting,oldValue); + currentEditorSettings.view[opt.setting] = oldValue; + editorSettingsChanged = true; RED.settings.remove(opt.oldSetting); } } allSettings[opt.setting] = opt; if (opt.onchange) { - var value = RED.settings.get(opt.setting); + var value = currentEditorSettings.view[opt.setting]; if ((value === null || value === undefined) && opt.hasOwnProperty('default')) { value = opt.default; - RED.settings.set(opt.setting,value); + currentEditorSettings.view[opt.setting] = value; + editorSettingsChanged = true; } var callback = opt.onchange; @@ -212,6 +224,9 @@ RED.userSettings = (function() { } }); }); + if (editorSettingsChanged) { + RED.settings.set('editor',currentEditorSettings); + } } return { diff --git a/red/api/editor/settings.js b/red/api/editor/settings.js index d4675902c..1408ec401 100644 --- a/red/api/editor/settings.js +++ b/red/api/editor/settings.js @@ -68,7 +68,9 @@ module.exports = { } else { username = req.user.username; } - settings.setUserSettings(username, req.body).then(function() { + var currentSettings = settings.getUserSettings(username)||{}; + currentSettings = extend(currentSettings, req.body); + settings.setUserSettings(username, currentSettings).then(function() { log.audit({event: "settings.update",username:username},req); res.status(204).end(); }).otherwise(function(err) { @@ -77,3 +79,27 @@ module.exports = { }); } } + +function extend(target, source) { + var keys = Object.keys(source); + var i = keys.length; + while(i--) { + var value = source[keys[i]] + var type = typeof value; + if (type === 'string' || type === 'number' || type === 'boolean' || Array.isArray(value)) { + target[keys[i]] = value; + } else if (value === null) { + if (target.hasOwnProperty(keys[i])) { + delete target[keys[i]]; + } + } else { + // Object + if (target.hasOwnProperty(keys[i])) { + target[keys[i]] = extend(target[keys[i]],value); + } else { + target[keys[i]] = value; + } + } + } + return target; +} diff --git a/red/runtime/settings.js b/red/runtime/settings.js index 93fe86cdd..ba913ea31 100644 --- a/red/runtime/settings.js +++ b/red/runtime/settings.js @@ -165,17 +165,18 @@ var persistentSettings = { }); }, getUserSettings: function(username) { - console.log(username); - return userSettings[username]; + return clone(userSettings[username]); }, setUserSettings: function(username,settings) { var current = userSettings[username]; userSettings[username] = settings; try { assert.deepEqual(current,settings); + console.log("skip the save"); return when.resolve(); } catch(err) { globalSettings.users = userSettings; + console.log("saving"); return storage.saveSettings(globalSettings); } } diff --git a/red/runtime/storage/localfilesystem/projects/Project.js b/red/runtime/storage/localfilesystem/projects/Project.js index 863d27ad2..4143ed0cb 100644 --- a/red/runtime/storage/localfilesystem/projects/Project.js +++ b/red/runtime/storage/localfilesystem/projects/Project.js @@ -53,7 +53,6 @@ Project.prototype.load = function () { this.credentialSecret = projectSettings.credentialSecret; this.git = projectSettings.git || { user:{} }; -console.log("LOADED",this.git); // this.paths.flowFile = fspath.join(this.path,"flow.json"); // this.paths.credentialsFile = fspath.join(this.path,"flow_cred.json");