diff --git a/editor/js/main.js b/editor/js/main.js index affa6315f..4573d57aa 100644 --- a/editor/js/main.js +++ b/editor/js/main.js @@ -43,9 +43,13 @@ $(".palette-scroll").removeClass("hide"); $("#palette-search").removeClass("hide"); loadFlows(function() { - RED.projects.refresh(function() { + if (RED.settings.theme("projects.enabled",true)) { + RED.projects.refresh(function() { + RED.sidebar.info.refresh() + }); + } else { RED.sidebar.info.refresh() - }); + } var persistentNotifications = {}; RED.comms.subscribe("notification/#",function(topic,msg) { @@ -65,7 +69,6 @@ RED.view.redraw(true); RED.projects.refresh(function() { loadFlows(function() { - console.log(msg); var project = RED.projects.getActiveProject(); var message = { "change-branch":"Change to local branch '"+project.git.branches.local+"'", @@ -214,12 +217,13 @@ function loadEditor() { var menuOptions = []; - - menuOptions.push({id:"menu-item-projects-menu",label:"NLS: Projects",options:[ - {id:"menu-item-projects-new",label:"New...",disabled:false,onselect:"core:new-project"}, - {id:"menu-item-projects-open",label:"Open...",disabled:false,onselect:"core:open-project"}, - {id:"menu-item-projects-delete",label:"Delete...",disabled:false,onselect:"core:delete-project"}, - ]}); + if (RED.settings.theme("projects.enabled",true)) { + menuOptions.push({id:"menu-item-projects-menu",label:"NLS: Projects",options:[ + {id:"menu-item-projects-new",label:"New...",disabled:false,onselect:"core:new-project"}, + {id:"menu-item-projects-open",label:"Open...",disabled:false,onselect:"core:open-project"}, + {id:"menu-item-projects-delete",label:"Delete...",disabled:false,onselect:"core:delete-project"}, + ]}); + } menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ @@ -284,10 +288,18 @@ RED.palette.init(); if (RED.settings.theme('palette.editable') !== false) { RED.palette.editor.init(); + } else { + console.log("Palette editor disabled"); } RED.sidebar.init(); - RED.projects.init(); + + if (RED.settings.theme("projects.enabled",true)) { + RED.projects.init(); + } else { + console.log("Palette editor disabled"); + } + RED.subflow.init(); RED.workspaces.init(); RED.clipboard.init(); diff --git a/red/api/editor/index.js b/red/api/editor/index.js index b9f4d539a..4e26ef82f 100644 --- a/red/api/editor/index.js +++ b/red/api/editor/index.js @@ -68,9 +68,11 @@ module.exports = { editorApp.use("/",ui.editorResources); //Projects - var projects = require("./projects"); - projects.init(runtime); - editorApp.use("/projects",projects.app()); + if (runtime.storage.projects) { + var projects = require("./projects"); + projects.init(runtime); + editorApp.use("/projects",projects.app()); + } // Locales var locales = require("./locales"); diff --git a/red/api/editor/projects/index.js b/red/api/editor/projects/index.js index 65fae6de2..cd9d1b935 100644 --- a/red/api/editor/projects/index.js +++ b/red/api/editor/projects/index.js @@ -31,7 +31,6 @@ module.exports = { // List all projects app.get("/", needsPermission("projects.read"), function(req,res) { - console.log(req.user); runtime.storage.projects.listProjects(req.user, req.user).then(function(list) { var active = runtime.storage.projects.getActiveProject(req.user); var response = { diff --git a/red/api/editor/theme.js b/red/api/editor/theme.js index b34266646..6699e7cd7 100644 --- a/red/api/editor/theme.js +++ b/red/api/editor/theme.js @@ -182,6 +182,12 @@ module.exports = { if (theme.hasOwnProperty("palette")) { themeSettings.palette = theme.palette; } + + if (theme.hasOwnProperty("projects")) { + themeSettings.projects = theme.projects; + } + + return themeApp; }, context: function() { diff --git a/red/runtime/locales/en-US/runtime.json b/red/runtime/locales/en-US/runtime.json index 9853a2b3f..597ad6bbe 100644 --- a/red/runtime/locales/en-US/runtime.json +++ b/red/runtime/locales/en-US/runtime.json @@ -133,13 +133,19 @@ "localfilesystem": { "user-dir": "User directory : __path__", "flows-file": "Flows file : __path__", - "changing-project": "Setting active project : __project__", - "active-project": "Active project : __project__", "create": "Creating new __type__ file", "empty": "Existing __type__ file is empty", "invalid": "Existing __type__ file is not valid json", "restore": "Restoring __type__ file backup : __path__", - "restore-fail": "Restoring __type__ file backup failed : __message__" + "restore-fail": "Restoring __type__ file backup failed : __message__", + "projects": { + "changing-project": "Setting active project : __project__", + "active-project": "Active project : __project__", + "no-active-project": "No active project : using default flows file", + "disabled": "Projects disabled : editorTheme.projects.enabled=false", + "git-not-found": "Projects disabled : git command not found", + "git-version-old": "Projects disabled : git __version__ too old" + } } } } diff --git a/red/runtime/settings.js b/red/runtime/settings.js index dd27dd3a5..bc51f98b8 100644 --- a/red/runtime/settings.js +++ b/red/runtime/settings.js @@ -56,7 +56,7 @@ var persistentSettings = { return storage.getSettings().then(function(_settings) { globalSettings = _settings; if (globalSettings) { - userSettings = globalSettings.users || {}; + userSettings = globalSettings.users || {}; } else { userSettings = {}; @@ -177,11 +177,9 @@ var persistentSettings = { 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/index.js b/red/runtime/storage/index.js index f60862fe7..65b2f8bbf 100644 --- a/red/runtime/storage/index.js +++ b/red/runtime/storage/index.js @@ -54,8 +54,10 @@ var storageModuleInterface = { } catch (e) { return when.reject(e); } - if (storageModule.projects) { - storageModuleInterface.projects = storageModule.projects; + if (runtime.settings.hasOwnProperty("editorTheme") && runtime.settings.editorTheme.hasOwnProperty("projects")) { + if (storageModule.projects) { + storageModuleInterface.projects = storageModule.projects; + } } return storageModule.init(runtime.settings,runtime); }, diff --git a/red/runtime/storage/localfilesystem/projects/git/index.js b/red/runtime/storage/localfilesystem/projects/git/index.js index 320f508c6..a706b410e 100644 --- a/red/runtime/storage/localfilesystem/projects/git/index.js +++ b/red/runtime/storage/localfilesystem/projects/git/index.js @@ -22,6 +22,7 @@ var clone = require('clone'); var path = require("path"); var gitCommand = "git"; +var gitVersion; var log; function runGitCommand(args,cwd,env) { @@ -334,6 +335,15 @@ function removeRemote(cwd,name) { module.exports = { init: function(_settings,_runtime) { log = _runtime.log + return new Promise(function(resolve,reject) { + runGitCommand(["--version"]).then(function(output) { + var m = / (\d\S+)/.exec(output); + gitVersion = m[1]; + resolve(gitVersion); + }).catch(function(err) { + resolve(null); + }); + }); }, initRepo: function(cwd) { return runGitCommand(["init"],cwd); diff --git a/red/runtime/storage/localfilesystem/projects/index.js b/red/runtime/storage/localfilesystem/projects/index.js index 3de6bd36e..2c24a48af 100644 --- a/red/runtime/storage/localfilesystem/projects/index.js +++ b/red/runtime/storage/localfilesystem/projects/index.js @@ -29,6 +29,9 @@ var Projects = require("./Project"); var settings; var runtime; +var projectsEnabled; +var projectLogMessages = []; + var projectsDir; var activeProject @@ -36,11 +39,15 @@ function init(_settings, _runtime) { settings = _settings; runtime = _runtime; log = runtime.log; - gitTools.init(_settings, _runtime); - Projects.init(settings,runtime); - - projectsDir = fspath.join(settings.userDir,"projects"); + try { + if (settings.editorTheme.projects.enabled === false) { + projectLogMessages.push(log._("storage.localfilesystem.projects.disabled")) + projectsEnabled = false; + } + } catch(err) { + projectsEnabled = true; + } if (settings.flowFile) { flowsFile = settings.flowFile; @@ -73,27 +80,39 @@ function init(_settings, _runtime) { credentialsFile = fspath.join(settings.userDir,ffBase+"_cred"+ffExt); credentialsFileBackup = getBackupFilename(credentialsFile) - if (!settings.readOnly) { - return fs.ensureDir(projectsDir) - //TODO: this is accessing settings from storage directly as settings - // has not yet been initialised. That isn't ideal - can this be deferred? - .then(storageSettings.getSettings) - .then(function(globalSettings) { - if (!globalSettings.projects) { - // TODO: Migration Case - console.log("TODO: Migration from single file to project"); - globalSettings.projects = { - activeProject: "", - projects: {} - } - return storageSettings.saveSettings(globalSettings); - } else { - activeProject = globalSettings.projects.activeProject; + var setupProjectsPromise; + + if (projectsEnabled) { + return gitTools.init(_settings, _runtime).then(function(gitVersion) { + if (!gitVersion) { + projectLogMessages.push(log._("storage.localfilesystem.projects.git-not-found")) + projectsEnabled = false; + } else { + Projects.init(settings,runtime); + projectsDir = fspath.join(settings.userDir,"projects"); + if (!settings.readOnly) { + return fs.ensureDir(projectsDir) + //TODO: this is accessing settings from storage directly as settings + // has not yet been initialised. That isn't ideal - can this be deferred? + .then(storageSettings.getSettings) + .then(function(globalSettings) { + if (!globalSettings.projects) { + // TODO: Migration Case + console.log("TODO: Migration from single file to project"); + globalSettings.projects = { + activeProject: "", + projects: {} + } + return storageSettings.saveSettings(globalSettings); + } else { + activeProject = globalSettings.projects.activeProject; + } + }); } - }); - } else { - return when.resolve(); + } + }); } + return Promise.resolve(); } function getUserGitSettings(user) { @@ -263,9 +282,8 @@ function setActiveProject(user, projectName) { var globalProjectSettings = settings.get("projects"); globalProjectSettings.activeProject = project.name; return settings.set("projects",globalProjectSettings).then(function() { - log.info(log._("storage.localfilesystem.changing-project",{project:activeProject||"none"})); + log.info(log._("storage.localfilesystem.projects.changing-project",{project:activeProject||"none"})); log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath})); - // console.log("Updated file targets to"); // console.log(flowsFullPath) // console.log(credentialsFile) @@ -346,11 +364,16 @@ function getFlows() { log.info(log._("storage.localfilesystem.user-dir",{path:settings.userDir})); if (activeProject) { return loadProject(activeProject).then(function() { - log.info(log._("storage.localfilesystem.active-project",{project:activeProject.name||"none"})); + log.info(log._("storage.localfilesystem.projects.active-project",{project:activeProject.name||"none"})); log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath})); return getFlows(); }); } else { + if (projectsEnabled) { + log.warn(log._("storage.localfilesystem.projects.no-active-project")) + } else { + projectLogMessages.forEach(log.warn); + } log.info(log._("storage.localfilesystem.flows-file",{path:flowsFullPath})); } }