diff --git a/core/menu_util.js b/core/menu_util.js index 79fc1e80..905c8564 100644 --- a/core/menu_util.js +++ b/core/menu_util.js @@ -66,6 +66,13 @@ function loadMenu(name, client, cb) { function getFormConfig(menuConfig, mciMap, cb) { + assert(menuConfig); + + if(!menuConfig.form) { + cb(new Error('No form section specified for menu')); + return; + } + async.filter( menuConfig.form, function check(form, callback) { @@ -75,12 +82,14 @@ function getFormConfig(menuConfig, mciMap, cb) { } var count = form.mciReq.length; - for(var i = 0; i < count; ++i) { - if(!mciMap[form.mciReq[i]]) { - callback(false); + if(Object.keys(mciMap).length === count) { + for(var i = 0; i < count; ++i) { + if(!mciMap[form.mciReq[i]]) { + callback(false); + } } + callback(true); } - callback(true); }, function filtered(form) { if(form.length > 0) { diff --git a/core/view_controller.js b/core/view_controller.js index cfd2c030..e5a1f216 100644 --- a/core/view_controller.js +++ b/core/view_controller.js @@ -1,13 +1,16 @@ /* jslint node: true */ 'use strict'; +// ENiGMA½ +var MCIViewFactory = require('./mci_view_factory.js').MCIViewFactory; +var menuUtil = require('./menu_util.js'); +var Log = require('./logger.js').log; + var events = require('events'); var util = require('util'); var assert = require('assert'); -var MCIViewFactory = require('./mci_view_factory.js').MCIViewFactory; -var menuUtil = require('./menu_util.js'); - var async = require('async'); +var ld = require('lodash'); exports.ViewController = ViewController; @@ -62,7 +65,7 @@ function ViewController(client, formId) { { id : 0, submitId : 1, - values : { + value : { "1" : "hurp", "2" : [ 'a', 'b', ... ], "3 " 2, @@ -73,7 +76,7 @@ function ViewController(client, formId) { var formData = { id : self.formId, submitId : self.focusedView.id, - values : {}, + value : {}, }; var viewData; @@ -81,10 +84,10 @@ function ViewController(client, formId) { try { viewData = self.views[id].getViewData(); if(typeof viewData !== 'undefined') { - formData.values[id] = viewData; + formData.value[id] = viewData; } } catch(e) { - console.log(e); + Log.error(e); // :TODO: Log better ;) } } @@ -203,23 +206,26 @@ ViewController.prototype.loadFromMCIMap = function(mciMap) { }); }; -ViewController.prototype.loadFromMCIMapAndConfig = function(mciMap, menuConfig, cb) { +ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) { + assert(options.mciMap); + var factory = new MCIViewFactory(this.client); var self = this; async.waterfall( [ function getFormConfig(callback) { - menuUtil.getFormConfig(menuConfig, mciMap, function onFormConfig(err, formConfig) { + menuUtil.getFormConfig(options.menuConfig, options.mciMap, function onFormConfig(err, formConfig) { if(err) { - // :TODO: Log about missing form config -- this is not fatal, however + Log.warn(err, 'Unable to load menu configuration'); } + callback(null, formConfig); }); }, function createViewsFromMCIMap(formConfig, callback) { - async.each(Object.keys(mciMap), function onMciEntry(name, eachCb) { - var mci = mciMap[name]; + async.each(Object.keys(options.mciMap), function onMciEntry(name, eachCb) { + var mci = options.mciMap[name]; var view = factory.createFromMCI(mci); if(view) { @@ -236,28 +242,59 @@ ViewController.prototype.loadFromMCIMapAndConfig = function(mciMap, menuConfig, }); }, function applyFormConfig(formConfig, callback) { - async.each(Object.keys(formConfig.mci), function onMciConf(mci, eachCb) { - var viewId = parseInt(mci[2]); // :TODO: what about auto-generated ID's? Do they simply not apply to menu configs? - var mciConf = formConfig.mci[mci]; + if(formConfig) { + async.each(Object.keys(formConfig.mci), function onMciConf(mci, eachCb) { + var viewId = parseInt(mci[2]); // :TODO: what about auto-generated ID's? Do they simply not apply to menu configs? + var mciConf = formConfig.mci[mci]; - // :TODO: Break all of this up ... and/or better way of doing it - if(mciConf.items) { - self.getView(viewId).setItems(mciConf.items); + // :TODO: Break all of this up ... and/or better way of doing it + if(mciConf.items) { + self.getView(viewId).setItems(mciConf.items); + } + + if(mciConf.submit) { + self.getView(viewId).submit = true; // :TODO: should really be actual value + } + + if(mciConf.focus) { + self.switchFocus(viewId); + } + + + eachCb(null); + }, + function eachMciConfComplete(err) { + callback(err, formConfig); + }); + } else { + callback(null); + } + }, + function mapMenuSubmit(formConfig, callback) { + if(formConfig) { + // + // If we have a 'submit' section, create a submit handler + // and map the various entries to menus/etc. + // + if(formConfig.submit && formConfig.submit.length > 0) { + self.on('submit', function onSubmit(formData) { + Log.debug( { formData : formData }, 'Submit form'); + + for(var c = 0; c < formConfig.submit.length; ++c) { + console.log(formConfig.submit[c]); + + if(ld.isEqual(formData.value, formConfig.submit[c].value)) { + self.client.gotoMenuModule(formConfig.submit[c].menu); + break; + } + + // :TODO: Match various wildcards, etc. + } + }); } - - if(mciConf.submit) { - self.getView(viewId).submit = true; // :TODO: should really be actual value - } - - if(mciConf.focus) { - self.switchFocus(viewId); - } - - eachCb(null); - }, - function eachMciConfComplete(err) { - callback(err); - }); + } else { + callback(null); + } } ], function complete(err) { diff --git a/mods/art/LOGIN1.ANS b/mods/art/LOGIN1.ANS new file mode 100644 index 00000000..8264bc48 Binary files /dev/null and b/mods/art/LOGIN1.ANS differ diff --git a/mods/login.js b/mods/login.js new file mode 100644 index 00000000..55557e65 --- /dev/null +++ b/mods/login.js @@ -0,0 +1,48 @@ +/* jslint node: true */ +'use strict'; + +var ansi = require('../core/ansi_term.js'); +var art = require('../core/art.js'); +var user = require('../core/user.js'); +var theme = require('../core/theme.js'); +var MenuModule = require('../core/menu_module.js').MenuModule; +var ViewController = require('../core/view_controller.js').ViewController; + +//var async = require('async'); + +// :TODO: clean up requires + +exports.moduleInfo = { + name : 'Login', + desc : 'Login Module', + author : 'NuSkooler', +}; + +exports.getModule = LoginModule; + + +function LoginModule(menuConfig) { + MenuModule.call(this, menuConfig); +} + +require('util').inherits(LoginModule, MenuModule); + +LoginModule.prototype.enter = function(client) { + LoginModule.super_.prototype.enter.call(this, client); +}; + +LoginModule.prototype.beforeArt = function() { + LoginModule.super_.prototype.beforeArt.call(this); + + this.client.term.write(ansi.resetScreen()); +}; + +LoginModule.prototype.mciReady = function(mciMap) { + LoginModule.super_.prototype.mciReady.call(this, mciMap); + + var self = this; + + var vc = self.addViewController(new ViewController(self.client)); + vc.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) { + }); +}; \ No newline at end of file diff --git a/mods/menu.json b/mods/menu.json index 8f3ac6e0..61793136 100644 --- a/mods/menu.json +++ b/mods/menu.json @@ -4,6 +4,7 @@ */ "matrix" : { "art" : "matrix", + // :TODO: Not currently supporting more than form 0. Should probably do that! "form" : [ { "mciReq" : [ "VM1" ], @@ -11,12 +12,35 @@ "VM1" : { "submit" : true, "focus" : true, + // :TODO: need a good way to localize these ... Standard Orig->Lookup seems good. "items" : [ "Login", "Apply", "Log Off" ] } - } + }, + /* + Some Examples: + VerticalMenu: { id: 0, submitId: 1, value: { '1': 1 } } + + Another concept: + + "menu" : "@helper.js/logoff" -> calls helper.js::logoff(...) + + */ + "submit" : [ + { + "value" : { "1" : 0 }, + "menu" : "login" + }, + { + "value" : { "1" : 1 }, + "menu" : "apply" + }, + { + "value" : { "1" : 2 }, + "menu" : "logoff" + } + ] } ] - //"module" : "matrix" }, "login" : { "art" : "login", diff --git a/mods/standard_menu.js b/mods/standard_menu.js index e8467949..afae7fe8 100644 --- a/mods/standard_menu.js +++ b/mods/standard_menu.js @@ -37,11 +37,13 @@ StandardMenuModule.prototype.mciReady = function(mciMap) { var self = this; var vc = self.addViewController(new ViewController(self.client)); - vc.loadFromMCIMapAndConfig(mciMap, self.menuConfig, function onViewReady(err) { + vc.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) { if(err) { console.log(err); } else { - // vc.switchFocus(1); + /* vc.on('submit', function onFormSubmit(formData) { + console.log(formData); + });*/ } }); @@ -117,8 +119,8 @@ StandardMenuModule.prototype.mciReady = function(mciMap) { }; if(0 === form.id && 1 === form.submitId) { - console.log(viewModuleMap[form.values[1]]); - self.client.gotoMenuModule(viewModuleMap[form.values[1]]); + console.log(viewModuleMap[form.value[1]]); + self.client.gotoMenuModule(viewModuleMap[form.value[1]]); } });