From 4f48715ea00eecf0dfbf990365325ef73c3ae426 Mon Sep 17 00:00:00 2001 From: Max Ogden Date: Sat, 21 Mar 2015 13:51:11 -0700 Subject: [PATCH] add individual detail pages --- configure.html | 5 +- configure.js | 82 +++++++++++++++++++++++--------- configure.mustache | 10 ---- configure.tmpl | 35 ++++++++++++++ detail.tmpl | 42 +++++++++++++++++ index.js | 115 +++++++++++++++++++++++++++------------------ package.json | 5 +- test/config.json | 4 +- 8 files changed, 217 insertions(+), 81 deletions(-) delete mode 100644 configure.mustache create mode 100644 configure.tmpl create mode 100644 detail.tmpl diff --git a/configure.html b/configure.html index cd2c23d..def21b1 100644 --- a/configure.html +++ b/configure.html @@ -2,11 +2,12 @@ -
+
diff --git a/configure.js b/configure.js index a5ccf1c..4992094 100644 --- a/configure.js +++ b/configure.js @@ -1,12 +1,32 @@ var ipc = require('ipc') -var mustache = require('mustache') +var Ractive = require('ractive') +var page = require('page') var fs = require('fs') +var $ = require('jquery') -var template = fs.readFileSync('./configure.mustache').toString() -var container = document.querySelector('.app') +Ractive.DEBUG = false -ipc.on('status', function(data) { - data = data.map(function(d) { +var templates = { + configure: fs.readFileSync('./configure.tmpl').toString(), + detail: fs.readFileSync('./detail.tmpl').toString() +} + +var state = {} + +$(document).on('click', '.processAction', function(e) { + var action = e.currentTarget.attributes['data-action'].value + var procNameAttr = e.currentTarget.attributes['data-name'] + var data = {task: action} + if (procNameAttr) data.name = procNameAttr.value + ipc.send('task', data) +}) + +$(document).on('click', '.btn.quit', function(e) { + ipc.send('terminate') +}) + +ipc.on('got-all', function gotAll (data) { + data = data.map(function map (d) { if (d.uptime) { d.classes = "btn-positive" d.message = "Running" @@ -21,24 +41,44 @@ ipc.on('status', function(data) { d.message = "Not Running" return d }) - var output = mustache.render(template, {items: data}) - container.innerHTML = output - - addEvents() + state.configure.set({items: data}) }) -ipc.send('update-me') - -function addEvents() { - var startAll = document.querySelector('.start-all') - var stopAll = document.querySelector('.stop-all') - var restartAll = document.querySelector('.restart-all') - var buttons = [startAll, stopAll, restartAll] +ipc.on('got-one', function gotOne (data) { + state.detail.set(data) +}) - buttons.forEach(function (button) { - button.addEventListener('mousedown', function(e) { - var action = e.target.attributes['data-action'].value - ipc.send('task', {task: action}) +var routes = { + configure: function(ctx, next) { + ctx.template = templates.configure + state.configure = render(ctx, {loading: true}) + ipc.send('get-all') + ipc.once('status', function() { + next() + }) + }, + detail: function(ctx, next) { + ctx.template = templates.detail + state.detail = render(ctx, {loading: true}) + ipc.send('get-one', {name: ctx.params.name}) + ipc.once('status', function() { + next() }) + } +} + +// set up routes +page('/', routes.configure) +page('/detail/:name', routes.detail) + +// initialize router +page.start() +page('/') + +function render(ctx) { + return new Ractive({ + el: "#container", + template: ctx.template, + data: ctx.data }) -} \ No newline at end of file +} diff --git a/configure.mustache b/configure.mustache deleted file mode 100644 index 9cf52c1..0000000 --- a/configure.mustache +++ /dev/null @@ -1,10 +0,0 @@ - -
- - - -
\ No newline at end of file diff --git a/configure.tmpl b/configure.tmpl new file mode 100644 index 0000000..f976e95 --- /dev/null +++ b/configure.tmpl @@ -0,0 +1,35 @@ + + \ No newline at end of file diff --git a/detail.tmpl b/detail.tmpl new file mode 100644 index 0000000..6090e11 --- /dev/null +++ b/detail.tmpl @@ -0,0 +1,42 @@ +
+ + + +

{{name}}

+
+
+ +
\ No newline at end of file diff --git a/index.js b/index.js index 4eafc5b..7fbe0a0 100644 --- a/index.js +++ b/index.js @@ -16,85 +16,107 @@ var icon, menu, configure, about app.on('ready', function() { app.dock.hide() - + var atomScreen = require('screen') + var size = atomScreen.getPrimaryDisplay() + + var canQuit = false app.on('will-quit', function(e) { + if (canQuit) return true configure = undefined e.preventDefault() }) - // main.js var template = [] var iconPath = path.join(__dirname, 'images', 'Status.png') var configFile = './test/config.json' var conf = require(configFile) var dir = path.dirname(configFile) + conf.exec = {cwd: path.resolve(dir)} conf.logs = path.resolve(path.join(dir, conf.logs || 'logs')) conf.pids = path.resolve(path.join(dir, conf.pids || 'pids')) + mkdir(conf.logs) mkdir(conf.pids) conf.mon = path.join(__dirname, 'mon') + + // start all once + start([], function started (err) { + if (err) return console.log("error starting processes: " + err.message) + console.log("started all processes") + }) + icon = new Tray(iconPath) + + icon.on('clicked', function(e) { + if (configure && configure.isVisible()) return hideConfigure() + showConfigure() + }) - var menuTemplate = [ - { - label: 'Configure...', - click: function() { - showConfigure() - } - }, - { - type: 'separator' - }, - { - label: 'About', - click: function() { - showAbout() - } - }, - { - label: 'Quit', - click: function() { - app.terminate() - } - } - ] + ipc.on('terminate', function terminate (ev) { + canQuit = true + app.terminate() + }) - showConfigure() + ipc.on('get-all', function getAll (ev, data) { + getStatus() + }) - menu = Menu.buildFromTemplate(menuTemplate) - icon.setContextMenu(menu) + ipc.on('get-one', function getOne (ev, data) { + getStatus(null, data.name) + }) - ipc.on('update-me', updateStatus) ipc.on('task', function task (ev, data) { - if (data.task === "startAll") startAll(updateStatus) - if (data.task === "stopAll") stopAll(updateStatus) - if (data.task === "restartAll") restartAll(updateStatus) + if (data.task === "startAll") start([], getStatus) + if (data.task === "stopAll") stop([], getStatus) + if (data.task === "restartAll") restart([], getStatus) + if (data.task === "start") start([data.name], updateSingle) + if (data.task === "stop") stop([data.name], updateSingle) + if (data.task === "restart") restart([data.name], updateSingle) + + function updateSingle() { + getStatus(null, data.name) + } }) function showConfigure() { - if (configure) return configure.show( ) + if (configure) { + getStatus() + return configure.show() + } configure = new BrowserWindow({ width: 400, height: 400, - show: true + show: true, + frame: false }) + configure.setPosition(size.workArea.width - 500, size.workArea.y) + configure.on('blur', hideConfigure) configure.loadUrl('file://' + __dirname + '/configure.html') } - function updateStatus() { + function hideConfigure() { + if (configure) return configure.hide() + } + + function getStatus(err, procName) { + if (err) throw err if (!configure) return - debug('update status...') + debug('get proc status...') var status = [] var group = new Mongroup(conf) - group.procs.forEach(function(proc) { + var procs = group.procs + if (procName) procs = procs.filter(function filter (proc) { + return proc.name === procName + }) + procs.forEach(function(proc) { var state = proc.state() var uptime if (state === 'alive') uptime = ms(Date.now() - proc.mtime(), { long: true }) - var item = { + cmd: proc.cmd, name: proc.name, state: state, pid: proc.pid @@ -105,28 +127,29 @@ app.on('ready', function() { status.push(item) }) - configure.webContents.send('status', status) + if (procName) configure.webContents.send('got-one', status[0]) + else configure.webContents.send('got-all', status) } - function restartAll(cb) { - stopAll(function (err1) { - startAll(function (err2) { + function restart(procs, cb) { + stop(procs, function (err1) { + start(procs, function (err2) { if (cb) cb(err1 || err2) }) }) } - function startAll(cb) { + function start(procs, cb) { var group = new Mongroup(conf) - group.start([], function (err) { + group.start(procs, function (err) { if (err) return cb(err) cb() }) } - function stopAll(cb) { + function stop(procs, cb) { var group = new Mongroup(conf) - group.stop([], 'SIGQUIT', function (err) { + group.stop(procs, 'SIGQUIT', function (err) { if (cb) return cb(err) cb() }) diff --git a/package.json b/package.json index 87a315a..3bdfef2 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,13 @@ "dependencies": { "auto-launch": "^0.1.15", "debug": "^2.1.3", + "jquery": "^2.1.3", "mkdirp": "^0.5.0", "mongroup": "maxogden/node-mongroup#monbin", "ms": "^0.7.0", "mustache": "^1.1.0", - "npm-execspawn": "^1.0.6" + "npm-execspawn": "^1.0.6", + "page": "^1.6.1", + "ractive": "^0.7.1" } } diff --git a/test/config.json b/test/config.json index 4a1e672..bd235f7 100644 --- a/test/config.json +++ b/test/config.json @@ -2,6 +2,8 @@ "logs": "./meta/logs", "pids": "./meta/pids", "processes": { - "web-1": "http-server ." + "web-1": "http-server .", + "web-2": "http-server . -p 8085", + "web-3": "http-server . -p 8090" } } \ No newline at end of file