Clean state again. With user friendly features

This commit is contained in:
Dominic Bosch 2014-04-27 13:20:08 +02:00
parent 1ba352987e
commit df39fe2043
13 changed files with 316 additions and 215 deletions

View file

@ -229,6 +229,7 @@ storeRule = ( user, oBody, callback ) =>
# This is how a rule is stored in the database # This is how a rule is stored in the database
rule = rule =
id: oBody.id id: oBody.id
eventtype: oBody.eventtype
eventname: oBody.eventname eventname: oBody.eventname
eventstart: oBody.eventstart eventstart: oBody.eventstart
eventinterval: oBody.eventinterval eventinterval: oBody.eventinterval

View file

@ -273,7 +273,7 @@ processEvent = ( evt ) =>
fSearchAndInvokeAction node[arrPath[depth]], arrPath, funcName, evt, depth + 1 fSearchAndInvokeAction node[arrPath[depth]], arrPath, funcName, evt, depth + 1
@log.info 'EN | Processing event: ' + evt.eventname @log.info 'EN | Processing event: ' + evt.eventname
fCheckEventForUser = ( userName, oUser ) -> fCheckEventForUser = ( userName, oUser ) =>
for ruleName, oMyRule of oUser for ruleName, oMyRule of oUser
ruleEvent = oMyRule.rule.eventname ruleEvent = oMyRule.rule.eventname

View file

@ -81,7 +81,7 @@ fLoadModule = ( msg ) ->
fAnonymous = () -> fAnonymous = () ->
db.eventPollers.getModule msg.user, arrName[ 0 ], ( err, obj ) -> db.eventPollers.getModule msg.user, arrName[ 0 ], ( err, obj ) ->
if not obj if not obj
log.warn "EP | Strange... no module retrieved: #{ arrName[0] }" log.info "EP | No module retrieved for #{ arrName[0] }, must be a custom event or Webhook"
else else
# we compile the module and pass: # we compile the module and pass:
dynmod.compileString obj.data, # code dynmod.compileString obj.data, # code

View file

@ -321,6 +321,7 @@ Components Manager
var args, arr, epModId, eventInfo, id, oFuncArgs, oParams, params, rule, strRule; var args, arr, epModId, eventInfo, id, oFuncArgs, oParams, params, rule, strRule;
rule = { rule = {
id: oBody.id, id: oBody.id,
eventtype: oBody.eventtype,
eventname: oBody.eventname, eventname: oBody.eventname,
eventstart: oBody.eventstart, eventstart: oBody.eventstart,
eventinterval: oBody.eventinterval, eventinterval: oBody.eventinterval,

View file

@ -357,7 +357,7 @@ Engine
ruleEvent += '_created:' + oMyRule.rule.timestamp; ruleEvent += '_created:' + oMyRule.rule.timestamp;
} }
if (evt.eventname === ruleEvent && validConditions(evt, oMyRule.rule, userName, ruleName)) { if (evt.eventname === ruleEvent && validConditions(evt, oMyRule.rule, userName, ruleName)) {
this.log.info('EN | EVENT FIRED: ' + evt.eventname + ' for rule ' + ruleName); _this.log.info('EN | EVENT FIRED: ' + evt.eventname + ' for rule ' + ruleName);
_results.push((function() { _results.push((function() {
var _i, _len, _ref, _results1; var _i, _len, _ref, _results1;
_ref = oMyRule.rule.actions; _ref = oMyRule.rule.actions;

View file

@ -88,7 +88,7 @@ Dynamic Modules
fAnonymous = function() { fAnonymous = function() {
return db.eventPollers.getModule(msg.user, arrName[0], function(err, obj) { return db.eventPollers.getModule(msg.user, arrName[0], function(err, obj) {
if (!obj) { if (!obj) {
return log.warn("EP | Strange... no module retrieved: " + arrName[0]); return log.info("EP | No module retrieved for " + arrName[0] + ", must be a custom event or Webhook");
} else { } else {
return dynmod.compileString(obj.data, msg.user, msg.rule, arrName[0], obj.lang, "eventpoller", db.eventPollers, function(result) { return dynmod.compileString(obj.data, msg.user, msg.rule, arrName[0], obj.lang, "eventpoller", db.eventPollers, function(result) {
var nd, now, oUser, start; var nd, now, oUser, start;

View file

@ -34,22 +34,34 @@ el = $( '<select>' ).attr( 'type', 'text' )
el.change () -> fFetchEventParams $( this ).val() el.change () -> fFetchEventParams $( this ).val()
domSelectEventPoller.append $( '<h4>' ).text( 'Event Poller Name : ' ).append el domSelectEventPoller.append $( '<h4>' ).text( 'Event Poller Name : ' ).append el
domInputStartTime = $( '<div>' ).attr( 'class', 'indent20' ).html "Start Time : domInputEventTiming = $( '<div>' ).attr( 'class', 'indent20' )
<input id=\"input_start\" type=\"text\" /> <b>\"hh:mm\"</b>, default = 12:00" table = $( '<table>' ).appendTo domInputEventTiming
tr = $( '<tr>' ).appendTo table
tr.append $( '<td>' ).text "Start Time : "
tr.append $( '<td>' ).append $( '<input>' ).attr( 'id', 'input_start' ).attr( 'type', 'text' )
tr.append $( '<td>' ).html " <b>\"hh:mm\"</b>, default = 12:00"
domInputInterval = $( '<div>' ).attr( 'class', 'indent20' ).html "Interval : tr = $( '<tr>' ).appendTo table
<input id=\"input_interval\" type=\"text\" /> <b>\"days hours:minutes\"</b>, default = 10 minutes" tr.append $( '<td>' ).text "Interval : "
tr.append $( '<td>' ).append $( '<input>' ).attr( 'id', 'input_interval' ).attr( 'type', 'text' )
tr.append $( '<td>' ).html " <b>\"days hours:minutes\"</b>, default = 10 minutes"
domEventPollerParameters = $( '<div>' ).attr 'id', 'event_poller_params' domEventPollerParameters = $( '<div>' ).attr 'id', 'event_poller_params'
domTableSelectedActions = $( '<table> ' ).attr( 'id', 'selected_actions' ) domSectionSelectedActions = $( '<div>' )
domDivActionUserParams = $( '<div>' ).attr( 'id', 'action_invoker_params' ) domSectionSelectedActions.append $( '<div>' ).html "<b>Selected Actions:</b>"
$( '#action_parameters' ).append $( '<div>' ).html "<b>Selected Actions:</b>" domSectionSelectedActions.append $( '<table> ' ).attr( 'id', 'selected_actions' )
$( '#action_parameters' ).append domTableSelectedActions domSectionSelectedActions.hide()
$( '#action_parameters' ).append $( '<div>' ).html "<br><br><b>Required Parameters:</b><br><br>"
$( '#action_parameters' ).append domDivActionUserParams
$( '#action_parameters' ).append $( '<div>' ).html "<br><br>"
domSectionActionParameters = $( '<div>' )
domSectionActionParameters.append $( '<div>' ).html "<br><br><b>Required Parameters:</b><br><br>"
domSectionActionParameters.append $( '<div>' ).attr( 'id', 'action_invoker_params' )
domSectionActionParameters.append $( '<div>' ).html "<br><br>"
domSectionActionParameters.hide()
fClearInfo = () ->
$( '#info' ).text ''
$( '#info' ).attr 'class', 'neutral'
fDisplayError = ( msg ) -> fDisplayError = ( msg ) ->
window.scrollTo 0, 0 window.scrollTo 0, 0
@ -64,23 +76,22 @@ fFailedRequest = ( msg ) ->
fDisplayError msg fDisplayError msg
fIssueRequest = ( args ) -> fIssueRequest = ( args ) ->
$( '#info' ).text '' fClearInfo()
$.post( '/usercommand', args.data ) $.post( '/usercommand', args.data )
.done args.done .done args.done
.fail args.fail .fail args.fail
# Convert a time string ( d h:m ) to a date # Convert a time string ( d h:m ) to a date
fConvertTimeToDate = ( str ) -> fConvertTimeToDate = ( str ) ->
txtStart = $( '#input_start' ).val()
dateConv = new Date() dateConv = new Date()
if not txtStart if not str
dateConv.setHours 12 dateConv.setHours 12
dateConv.setMinutes 0 dateConv.setMinutes 0
else else
arrInp = txtStart.split ':' arrInp = str.split ':'
# There's only one string entered: hour # There's only one string entered: hour
if arrInp.length is 1 if arrInp.length is 1
txtHr = txtStart txtHr = str
dateConv.setMinutes 0 dateConv.setMinutes 0
else else
txtHr = arrInp[ 0 ] txtHr = arrInp[ 0 ]
@ -189,8 +200,7 @@ fPrepareEventType = ( eventtype ) ->
else else
$( '#event_parameters' ).append domSelectEventPoller $( '#event_parameters' ).append domSelectEventPoller
$( '#event_parameters' ).append domInputStartTime $( '#event_parameters' ).append domInputEventTiming.show()
$( '#event_parameters' ).append domInputInterval
$( '#select_eventpoller option' ).remove() $( '#select_eventpoller option' ).remove()
for id, events of oEps for id, events of oEps
@ -206,8 +216,6 @@ fPrepareEventType = ( eventtype ) ->
# Fetch the required Event Poller parameters # Fetch the required Event Poller parameters
fFetchEventParams = ( name ) -> fFetchEventParams = ( name ) ->
console.log 'fetching event params'
console.log name
$( '#event_poller_params *' ).remove() $( '#event_poller_params *' ).remove()
if name if name
$( '#event_parameters' ).append domEventPollerParameters $( '#event_parameters' ).append domEventPollerParameters
@ -223,7 +231,6 @@ fFetchEventParams = ( name ) ->
fDisplayEventParams = ( id ) -> fDisplayEventParams = ( id ) ->
( data ) -> ( data ) ->
console.log 'displaying event parameters'
if data.message if data.message
oParams = JSON.parse data.message oParams = JSON.parse data.message
table = $ '<table>' table = $ '<table>'
@ -250,8 +257,6 @@ fFillEventParams = ( moduleId ) ->
body: JSON.stringify body: JSON.stringify
id: moduleId id: moduleId
done: ( data ) -> done: ( data ) ->
console.log 'filling event params: '
console.log data
oParams = JSON.parse data.message oParams = JSON.parse data.message
for param, oParam of oParams for param, oParam of oParams
par = $( "#event_poller_params tr" ).filter () -> par = $( "#event_poller_params tr" ).filter () ->
@ -269,7 +274,6 @@ fFetchEventFunctionArgs = ( arrName ) ->
body: JSON.stringify body: JSON.stringify
id: arrName[ 0 ] id: arrName[ 0 ]
done: ( data ) -> done: ( data ) ->
console.log 'fetching event function arguments: '
if data.message if data.message
oParams = JSON.parse data.message oParams = JSON.parse data.message
if oParams[ arrName[ 1 ] ] if oParams[ arrName[ 1 ] ]
@ -286,21 +290,18 @@ fFetchEventFunctionArgs = ( arrName ) ->
td = $( '<td>' ).appendTo tr td = $( '<td>' ).appendTo tr
td.append $( '<input>' ).attr 'type', 'text' td.append $( '<input>' ).attr 'type', 'text'
tr.append td tr.append td
fIssueRequest fIssueRequest
data: data:
command: 'get_event_poller_user_arguments' command: 'get_event_poller_user_arguments'
body: JSON.stringify body: JSON.stringify
ruleId: $( '#input_id' ).val() ruleId: $( '#input_id' ).val()
moduleId: moduleId moduleId: arrName[ 0 ]
done: fAddEventUserArgs moduleId done: fAddEventUserArgs arrName[ 1 ]
fail: fFailedRequest 'Error fetching event poller function arguments' fail: fFailedRequest 'Error fetching event poller function arguments'
fAddEventUserArgs = ( name ) -> fAddEventUserArgs = ( name ) ->
( data ) -> ( data ) ->
console.log 'filling event funcction arguments: '
console.log data
for key, arrFuncs of data.message for key, arrFuncs of data.message
par = $ "#event_poller_params" par = $ "#event_poller_params"
for oFunc in JSON.parse arrFuncs for oFunc in JSON.parse arrFuncs
@ -327,11 +328,7 @@ fAddSelectedAction = ( name ) ->
td = $( '<td>' ).attr( 'class', 'funcMappings').appendTo tr td = $( '<td>' ).attr( 'class', 'funcMappings').appendTo tr
fFetchActionFunctionArgs td, arrName fFetchActionFunctionArgs td, arrName
if arrName[ 0 ] not in arrEls if arrName[ 0 ] not in arrEls
div = $( '<div>' ).appendTo $( '#action_invoker_params' ) fFetchActionParams arrName[ 0 ]
subdiv = $( '<div> ').appendTo div
subdiv.append $( '<div>' )
.attr( 'class', 'modName underlined' ).text arrName[ 0 ]
fFetchActionParams div, arrName[ 0 ]
$( "#select_actions option" ).each () -> $( "#select_actions option" ).each () ->
if $( this ).text() is name if $( this ).text() is name
$( this ).remove() $( this ).remove()
@ -339,7 +336,7 @@ fAddSelectedAction = ( name ) ->
fFillActionFunction arrName[ 0 ] fFillActionFunction arrName[ 0 ]
setTimeout fDelayed, 300 setTimeout fDelayed, 300
fFetchActionParams = ( div, modName ) -> fFetchActionParams = ( modName ) ->
fIssueRequest fIssueRequest
data: data:
command: 'get_action_invoker_params' command: 'get_action_invoker_params'
@ -348,20 +345,26 @@ fFetchActionParams = ( div, modName ) ->
done: ( data ) -> done: ( data ) ->
if data.message if data.message
oParams = JSON.parse data.message oParams = JSON.parse data.message
table = $ '<table>' if JSON.stringify( oParams ) isnt '{}'
div.append table domSectionActionParameters.show()
fAppendActionParam = ( name, shielded ) -> div = $( '<div>' ).appendTo $( '#action_invoker_params' )
tr = $( '<tr>' ) subdiv = $( '<div> ').appendTo div
tr.append $( '<td>' ).css 'width', '20px' subdiv.append $( '<div>' )
tr.append $( '<td>' ).attr( 'class', 'key').text name .attr( 'class', 'modName underlined' ).text modName
inp = $( '<input>' ) table = $ '<table>'
if shielded div.append table
inp.attr( 'type', 'password' ) for name, shielded of oParams
else tr = $( '<tr>' )
inp.attr( 'type', 'text' ) tr.append $( '<td>' ).css 'width', '20px'
tr.append $( '<td>' ).text(' : ').append inp tr.append $( '<td>' ).attr( 'class', 'key').text name
table.append tr inp = $( '<input>' )
fAppendActionParam name, sh for name, sh of oParams if shielded
inp.attr( 'type', 'password' )
else
inp.attr( 'type', 'text' )
tr.append $( '<td>' ).text(' : ').append inp
table.append tr
fail: fFailedRequest 'Error fetching action invoker params' fail: fFailedRequest 'Error fetching action invoker params'
fFetchActionFunctionArgs = ( tag, arrName ) -> fFetchActionFunctionArgs = ( tag, arrName ) ->
@ -450,6 +453,21 @@ fOnLoad = () ->
editor.getSession().setMode "ace/mode/json" editor.getSession().setMode "ace/mode/json"
editor.setShowPrintMargin false editor.setShowPrintMargin false
$( '#fill_example' ).click () ->
editor.setValue """
[
{
"selector": ".nested_property",
"type": "string",
"operator": "<=",
"compare": "has this value"
}
]
"""
$( '#action_parameters' ).append domSectionSelectedActions
$( '#action_parameters' ).append domSectionActionParameters
$( '#input_id' ).focus() $( '#input_id' ).focus()
@ -503,32 +521,32 @@ fOnLoad = () ->
$( '#select_actions' ).on 'change', () -> $( '#select_actions' ).on 'change', () ->
$( '#action_parameters' ).append domTableSelectedActions domSectionSelectedActions.show()
opt = $ 'option:selected', this opt = $ 'option:selected', this
fAddSelectedAction opt.text() fAddSelectedAction opt.text()
$( '#selected_actions' ).on 'click', 'img', () -> $( '#selected_actions' ).on 'click', 'img', () ->
console.log 'click'
act = $( this ).closest( 'td' ).siblings( '.title' ).text() act = $( this ).closest( 'td' ).siblings( '.title' ).text()
arrName = act.split ' -> ' arrName = act.split ' -> '
i = 0
nMods = 0 nMods = 0
# Check whether we're the only function left that was selected from this module # Check whether we're the only function left that was selected from this module
$( "#selected_actions td.title" ).each () -> $( "#selected_actions td.title" ).each () ->
i++
arrNm = $( this ).text().split ' -> ' arrNm = $( this ).text().split ' -> '
nMods++ if arrNm[ 0 ] is arrName[ 0 ] nMods++ if arrNm[ 0 ] is arrName[ 0 ]
# If we are the last selected action we detach the whole action parameter section
if i is 1
$( '#action_parameters > *' ).detach()
if nMods is 1 if nMods is 1
$('#action_invoker_params > div').each () -> $('#action_invoker_params > div').each () ->
if $( this ).children( 'div.modName' ).text() is arrName[ 0 ] if $( this ).children( 'div.modName' ).text() is arrName[ 0 ]
$( this ).remove() $( this ).remove()
# Hide if nothing to show
if $('#selected_actions td.title').length is 0
domSectionSelectedActions.hide()
if $('#action_invoker_params > div').length is 0
domSectionActionParameters.hide()
opt = $( '<option>' ).text act opt = $( '<option>' ).text act
$( '#select_actions' ).append opt $( '#select_actions' ).append opt
$( this ).closest( 'tr' ).remove() $( this ).closest( 'tr' ).remove()
@ -538,7 +556,7 @@ fOnLoad = () ->
$( '#but_submit' ).click () -> $( '#but_submit' ).click () ->
window.scrollTo 0, 0 window.scrollTo 0, 0
$( '#info' ).text '' fClearInfo()
try try
if $( '#input_id' ).val() is '' if $( '#input_id' ).val() is ''
@ -562,6 +580,7 @@ fOnLoad = () ->
eventname = $( '#select_eventhook' ).val() eventname = $( '#select_eventhook' ).val()
when 'Event Poller' when 'Event Poller'
eventname = $( '#select_eventpoller' ).val()
ep = {} ep = {}
$( "#event_poller_params tr" ).each () -> $( "#event_poller_params tr" ).each () ->
key = $( this ).children( '.key' ).text() key = $( this ).children( '.key' ).text()
@ -579,9 +598,9 @@ fOnLoad = () ->
ep[ key ].value = val ep[ key ].value = val
evtFuncs = {} evtFuncs = {}
evtFuncs[ eventId ] = [] evtFuncs[ eventname ] = []
$( '#event_poller_params tr.funcMappings' ).each () -> $( '#event_poller_params tr.funcMappings' ).each () ->
evtFuncs[ eventId ].push evtFuncs[ eventname ].push
argument: $( 'div.funcarg', this ).text() argument: $( 'div.funcarg', this ).text()
value: $( 'input[type=text]', this ).val() value: $( 'input[type=text]', this ).val()
@ -654,26 +673,26 @@ fOnLoad = () ->
else else
fFailedRequest( "#{ obj.id } not stored!" ) err fFailedRequest( "#{ obj.id } not stored!" ) err
if $( '#select_event_type' ) is 'Event Poller' if $( '#select_event_type' ).val() is 'Event Poller'
start = fConvertTimeToDate $( '#input_start' ).val().toISOString() start = fConvertTimeToDate( $( '#input_start' ).val() ).toISOString()
mins = fConvertDayHourToMinutes $( '#input_interval' ).val() mins = fConvertDayHourToMinutes $( '#input_interval' ).val()
obj = obj =
console.log obj command: 'forge_rule'
body: JSON.stringify
id: $( '#input_id' ).val()
eventtype: eventtype
eventname: eventname
eventparams: ep
eventstart: start
eventinterval: mins
eventfunctions: evtFuncs
conditions: conds
actions: acts
actionparams: ap
actionfunctions: actFuncs
fIssueRequest fIssueRequest
data: data: obj
command: 'forge_rule'
body: JSON.stringify
id: $( '#input_id' ).val()
eventname: eventId
eventparams: ep
eventstart: start
eventinterval: mins
eventfunctions: evtFuncs
conditions: conds
actions: acts
actionparams: ap
actionfunctions: actFuncs
done: ( data ) -> done: ( data ) ->
$( '#info' ).text data.message $( '#info' ).text data.message
$( '#info' ).attr 'class', 'success' $( '#info' ).attr 'class', 'success'
@ -686,35 +705,52 @@ fOnLoad = () ->
# Edit a Rule # Edit a Rule
# ----------- # -----------
if oParams.id if oParams.id
obj =
command: 'get_rule'
data: JSON.stringify
id: oParams.id
fIssueRequest fIssueRequest
data: obj data:
command: 'get_rule'
body: JSON.stringify
id: oParams.id
done: ( data ) -> done: ( data ) ->
oRule = JSON.parse data.message oRule = JSON.parse data.message
if oRule if oRule
$( '#input_id' ).val oRule.id $( '#input_id' ).val oRule.id
# Event # Event
$( '#select_event' ).val oRule.eventname fPrepareEventType oRule.eventtype
if $( '#select_event' ).val() isnt '' switch oRule.eventtype
fFetchEventParams oRule.eventname when 'Event Poller'
fPlaceAndPaintInterval() $( '#select_event' ).val oRule.eventname
if $( '#select_event' ).val() isnt ''
fFetchEventParams oRule.eventname
$( '#input_event' ).val oRule.eventname
d = new Date oRule.eventstart
mins = d.getMinutes()
if mins.toString().length is 1
mins = '0' + mins
$( '#input_start', domInputEventTiming ).val d.getHours() + ':' + mins
$( '#input_interval', domInputEventTiming ).val oRule.eventinterval
$( '#input_event' ).val oRule.eventname else
d = new Date oRule.eventstart window.scrollTo 0, 0
mins = d.getMinutes() $( '#info' ).text 'Error loading Rule: Your Event Poller does not exist anymore!'
if mins.toString().length is 1 $( '#info' ).attr 'class', 'error'
mins = '0' + mins
$( '#input_start' ).val d.getHours() + ':' + mins when 'Webhook'
$( '#input_interval' ).val oRule.eventinterval $( '#select_eventhook' ).val oRule.eventname
if $( '#select_eventhook' ).val() is ''
window.scrollTo 0, 0
$( '#info' ).text 'Your Webhook does not exist anymore!'
$( '#info' ).attr 'class', 'error'
when 'Custom Event'
$( '#input_eventname' ).val oRule.eventname
# Conditions # Conditions
editor.setValue JSON.stringify oRule.conditions, undefined, 2 editor.setValue JSON.stringify oRule.conditions, undefined, 2
# Actions # Actions
domSectionSelectedActions.show()
for action in oRule.actions for action in oRule.actions
arrName = action.split ' -> ' arrName = action.split ' -> '
fAddSelectedAction action fAddSelectedAction action

View file

@ -10,6 +10,9 @@ if oParams.id
hostUrl = [ location.protocol, '//', location.host ].join '' hostUrl = [ location.protocol, '//', location.host ].join ''
fClearInfo = () ->
$( '#info' ).text ''
$( '#info' ).attr 'class', 'neutral'
fDisplayError = ( msg ) -> fDisplayError = ( msg ) ->
window.scrollTo 0, 0 window.scrollTo 0, 0
@ -18,7 +21,7 @@ fDisplayError = ( msg ) ->
fIssueRequest = ( args ) -> fIssueRequest = ( args ) ->
$( '#info' ).text '' fClearInfo()
$.post( '/usercommand', args.body ) $.post( '/usercommand', args.body )
.done args.done .done args.done
.fail args.fail .fail args.fail
@ -87,7 +90,7 @@ fOnLoad = () ->
# Register button action # Register button action
$( '#but_submit' ).click -> $( '#but_submit' ).click ->
$( '#info' ).text '' fClearInfo()
hookname = $( '#inp_hookname' ).val() hookname = $( '#inp_hookname' ).val()
if hookname is '' if hookname is ''

View file

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.7.1 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var arrKV, arrParams, domDivActionUserParams, domEventPollerParameters, domInputEventName, domInputInterval, domInputStartTime, domSelectEventPoller, domSelectWebhook, domTableSelectedActions, el, fAddActionUserArgs, fAddActionUserParams, fAddEventUserArgs, fAddSelectedAction, fConvertDayHourToMinutes, fConvertTimeToDate, fDisplayError, fDisplayEventParams, fFailedRequest, fFetchActionFunctionArgs, fFetchActionParams, fFetchEventFunctionArgs, fFetchEventParams, fFillActionFunction, fFillEventParams, fIssueRequest, fOnLoad, fPrepareEventType, oParams, param, strPublicKey, _i, _len, var arrKV, arrParams, domEventPollerParameters, domInputEventName, domInputEventTiming, domSectionActionParameters, domSectionSelectedActions, domSelectEventPoller, domSelectWebhook, el, fAddActionUserArgs, fAddActionUserParams, fAddEventUserArgs, fAddSelectedAction, fClearInfo, fConvertDayHourToMinutes, fConvertTimeToDate, fDisplayError, fDisplayEventParams, fFailedRequest, fFetchActionFunctionArgs, fFetchActionParams, fFetchEventFunctionArgs, fFetchEventParams, fFillActionFunction, fFillEventParams, fIssueRequest, fOnLoad, fPrepareEventType, oParams, param, strPublicKey, table, tr, _i, _len,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
strPublicKey = ''; strPublicKey = '';
@ -41,25 +41,50 @@
domSelectEventPoller.append($('<h4>').text('Event Poller Name : ').append(el)); domSelectEventPoller.append($('<h4>').text('Event Poller Name : ').append(el));
domInputStartTime = $('<div>').attr('class', 'indent20').html("Start Time : <input id=\"input_start\" type=\"text\" /> <b>\"hh:mm\"</b>, default = 12:00"); domInputEventTiming = $('<div>').attr('class', 'indent20');
domInputInterval = $('<div>').attr('class', 'indent20').html("Interval : <input id=\"input_interval\" type=\"text\" /> <b>\"days hours:minutes\"</b>, default = 10 minutes"); table = $('<table>').appendTo(domInputEventTiming);
tr = $('<tr>').appendTo(table);
tr.append($('<td>').text("Start Time : "));
tr.append($('<td>').append($('<input>').attr('id', 'input_start').attr('type', 'text')));
tr.append($('<td>').html(" <b>\"hh:mm\"</b>, default = 12:00"));
tr = $('<tr>').appendTo(table);
tr.append($('<td>').text("Interval : "));
tr.append($('<td>').append($('<input>').attr('id', 'input_interval').attr('type', 'text')));
tr.append($('<td>').html(" <b>\"days hours:minutes\"</b>, default = 10 minutes"));
domEventPollerParameters = $('<div>').attr('id', 'event_poller_params'); domEventPollerParameters = $('<div>').attr('id', 'event_poller_params');
domTableSelectedActions = $('<table> ').attr('id', 'selected_actions'); domSectionSelectedActions = $('<div>');
domDivActionUserParams = $('<div>').attr('id', 'action_invoker_params'); domSectionSelectedActions.append($('<div>').html("<b>Selected Actions:</b>"));
$('#action_parameters').append($('<div>').html("<b>Selected Actions:</b>")); domSectionSelectedActions.append($('<table> ').attr('id', 'selected_actions'));
$('#action_parameters').append(domTableSelectedActions); domSectionSelectedActions.hide();
$('#action_parameters').append($('<div>').html("<br><br><b>Required Parameters:</b><br><br>")); domSectionActionParameters = $('<div>');
$('#action_parameters').append(domDivActionUserParams); domSectionActionParameters.append($('<div>').html("<br><br><b>Required Parameters:</b><br><br>"));
$('#action_parameters').append($('<div>').html("<br><br>")); domSectionActionParameters.append($('<div>').attr('id', 'action_invoker_params'));
domSectionActionParameters.append($('<div>').html("<br><br>"));
domSectionActionParameters.hide();
fClearInfo = function() {
$('#info').text('');
return $('#info').attr('class', 'neutral');
};
fDisplayError = function(msg) { fDisplayError = function(msg) {
window.scrollTo(0, 0); window.scrollTo(0, 0);
@ -78,21 +103,20 @@
}; };
fIssueRequest = function(args) { fIssueRequest = function(args) {
$('#info').text(''); fClearInfo();
return $.post('/usercommand', args.data).done(args.done).fail(args.fail); return $.post('/usercommand', args.data).done(args.done).fail(args.fail);
}; };
fConvertTimeToDate = function(str) { fConvertTimeToDate = function(str) {
var arrInp, dateConv, h, intHour, intMin, m, txtHr, txtStart; var arrInp, dateConv, h, intHour, intMin, m, txtHr;
txtStart = $('#input_start').val();
dateConv = new Date(); dateConv = new Date();
if (!txtStart) { if (!str) {
dateConv.setHours(12); dateConv.setHours(12);
dateConv.setMinutes(0); dateConv.setMinutes(0);
} else { } else {
arrInp = txtStart.split(':'); arrInp = str.split(':');
if (arrInp.length === 1) { if (arrInp.length === 1) {
txtHr = txtStart; txtHr = str;
dateConv.setMinutes(0); dateConv.setMinutes(0);
} else { } else {
txtHr = arrInp[0]; txtHr = arrInp[0];
@ -202,8 +226,7 @@
return $('#select_event_type').val(''); return $('#select_event_type').val('');
} else { } else {
$('#event_parameters').append(domSelectEventPoller); $('#event_parameters').append(domSelectEventPoller);
$('#event_parameters').append(domInputStartTime); $('#event_parameters').append(domInputEventTiming.show());
$('#event_parameters').append(domInputInterval);
$('#select_eventpoller option').remove(); $('#select_eventpoller option').remove();
for (id in oEps) { for (id in oEps) {
events = oEps[id]; events = oEps[id];
@ -226,8 +249,6 @@
fFetchEventParams = function(name) { fFetchEventParams = function(name) {
var arr; var arr;
console.log('fetching event params');
console.log(name);
$('#event_poller_params *').remove(); $('#event_poller_params *').remove();
if (name) { if (name) {
$('#event_parameters').append(domEventPollerParameters); $('#event_parameters').append(domEventPollerParameters);
@ -248,8 +269,7 @@
fDisplayEventParams = function(id) { fDisplayEventParams = function(id) {
return function(data) { return function(data) {
var i, inp, name, shielded, table, tr; var i, inp, name, shielded;
console.log('displaying event parameters');
if (data.message) { if (data.message) {
oParams = JSON.parse(data.message); oParams = JSON.parse(data.message);
table = $('<table>'); table = $('<table>');
@ -286,8 +306,6 @@
}, },
done: function(data) { done: function(data) {
var oParam, par, _results; var oParam, par, _results;
console.log('filling event params: ');
console.log(data);
oParams = JSON.parse(data.message); oParams = JSON.parse(data.message);
_results = []; _results = [];
for (param in oParams) { for (param in oParams) {
@ -315,8 +333,7 @@
}) })
}, },
done: function(data) { done: function(data) {
var functionArgument, table, td, tr, _j, _len1, _ref; var functionArgument, td, _j, _len1, _ref;
console.log('fetching event function arguments: ');
if (data.message) { if (data.message) {
oParams = JSON.parse(data.message); oParams = JSON.parse(data.message);
if (oParams[arrName[1]]) { if (oParams[arrName[1]]) {
@ -342,10 +359,10 @@
command: 'get_event_poller_user_arguments', command: 'get_event_poller_user_arguments',
body: JSON.stringify({ body: JSON.stringify({
ruleId: $('#input_id').val(), ruleId: $('#input_id').val(),
moduleId: moduleId moduleId: arrName[0]
}) })
}, },
done: fAddEventUserArgs(moduleId) done: fAddEventUserArgs(arrName[1])
}); });
} }
} }
@ -356,9 +373,7 @@
fAddEventUserArgs = function(name) { fAddEventUserArgs = function(name) {
return function(data) { return function(data) {
var arrFuncs, key, oFunc, par, tr, _ref, _results; var arrFuncs, key, oFunc, par, _ref, _results;
console.log('filling event funcction arguments: ');
console.log(data);
_ref = data.message; _ref = data.message;
_results = []; _results = [];
for (key in _ref) { for (key in _ref) {
@ -383,7 +398,7 @@
}; };
fAddSelectedAction = function(name) { fAddSelectedAction = function(name) {
var arrEls, arrName, div, fDelayed, img, subdiv, table, td, tr, _ref; var arrEls, arrName, fDelayed, img, td, _ref;
arrName = name.split(' -> '); arrName = name.split(' -> ');
arrEls = $("#action_invoker_params div.modName").map(function() { arrEls = $("#action_invoker_params div.modName").map(function() {
return $(this).text(); return $(this).text();
@ -396,10 +411,7 @@
td = $('<td>').attr('class', 'funcMappings').appendTo(tr); td = $('<td>').attr('class', 'funcMappings').appendTo(tr);
fFetchActionFunctionArgs(td, arrName); fFetchActionFunctionArgs(td, arrName);
if (_ref = arrName[0], __indexOf.call(arrEls, _ref) < 0) { if (_ref = arrName[0], __indexOf.call(arrEls, _ref) < 0) {
div = $('<div>').appendTo($('#action_invoker_params')); fFetchActionParams(arrName[0]);
subdiv = $('<div> ').appendTo(div);
subdiv.append($('<div>')).attr('class', 'modName underlined').text(arrName[0]);
fFetchActionParams(div, arrName[0]);
} }
$("#select_actions option").each(function() { $("#select_actions option").each(function() {
if ($(this).text() === name) { if ($(this).text() === name) {
@ -412,7 +424,7 @@
return setTimeout(fDelayed, 300); return setTimeout(fDelayed, 300);
}; };
fFetchActionParams = function(div, modName) { fFetchActionParams = function(modName) {
return fIssueRequest({ return fIssueRequest({
data: { data: {
command: 'get_action_invoker_params', command: 'get_action_invoker_params',
@ -421,31 +433,33 @@
}) })
}, },
done: function(data) { done: function(data) {
var fAppendActionParam, name, sh, table, _results; var div, inp, name, shielded, subdiv, _results;
if (data.message) { if (data.message) {
oParams = JSON.parse(data.message); oParams = JSON.parse(data.message);
table = $('<table>'); if (JSON.stringify(oParams) !== '{}') {
div.append(table); domSectionActionParameters.show();
fAppendActionParam = function(name, shielded) { div = $('<div>').appendTo($('#action_invoker_params'));
var inp, tr; subdiv = $('<div> ').appendTo(div);
tr = $('<tr>'); subdiv.append($('<div>')).attr('class', 'modName underlined').text(modName);
tr.append($('<td>').css('width', '20px')); table = $('<table>');
tr.append($('<td>').attr('class', 'key').text(name)); div.append(table);
inp = $('<input>'); _results = [];
if (shielded) { for (name in oParams) {
inp.attr('type', 'password'); shielded = oParams[name];
} else { tr = $('<tr>');
inp.attr('type', 'text'); tr.append($('<td>').css('width', '20px'));
tr.append($('<td>').attr('class', 'key').text(name));
inp = $('<input>');
if (shielded) {
inp.attr('type', 'password');
} else {
inp.attr('type', 'text');
}
tr.append($('<td>').text(' : ').append(inp));
_results.push(table.append(tr));
} }
tr.append($('<td>').text(' : ').append(inp)); return _results;
return table.append(tr);
};
_results = [];
for (name in oParams) {
sh = oParams[name];
_results.push(fAppendActionParam(name, sh));
} }
return _results;
} }
}, },
fail: fFailedRequest('Error fetching action invoker params') fail: fFailedRequest('Error fetching action invoker params')
@ -461,7 +475,7 @@
}) })
}, },
done: function(data) { done: function(data) {
var functionArgument, table, td, tr, _j, _len1, _ref, _results; var functionArgument, td, _j, _len1, _ref, _results;
if (data.message) { if (data.message) {
oParams = JSON.parse(data.message); oParams = JSON.parse(data.message);
if (oParams[arrName[1]]) { if (oParams[arrName[1]]) {
@ -533,7 +547,7 @@
fAddActionUserArgs = function(name) { fAddActionUserArgs = function(name) {
return function(data) { return function(data) {
var arrFuncs, key, oFunc, par, tr, _ref, _results; var arrFuncs, key, oFunc, par, _ref, _results;
_ref = data.message; _ref = data.message;
_results = []; _results = [];
for (key in _ref) { for (key in _ref) {
@ -560,7 +574,7 @@
}; };
fOnLoad = function() { fOnLoad = function() {
var editor, obj; var editor;
fIssueRequest({ fIssueRequest({
data: { data: {
command: 'get_public_key' command: 'get_public_key'
@ -582,6 +596,11 @@
editor.setTheme("ace/theme/monokai"); editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/json"); editor.getSession().setMode("ace/mode/json");
editor.setShowPrintMargin(false); editor.setShowPrintMargin(false);
$('#fill_example').click(function() {
return editor.setValue("\n[\n {\n \"selector\": \".nested_property\",\n \"type\": \"string\",\n \"operator\": \"<=\",\n \"compare\": \"has this value\"\n }\n]");
});
$('#action_parameters').append(domSectionSelectedActions);
$('#action_parameters').append(domSectionActionParameters);
$('#input_id').focus(); $('#input_id').focus();
$('#select_event_type').change(function() { $('#select_event_type').change(function() {
return fPrepareEventType($(this).val()); return fPrepareEventType($(this).val());
@ -644,28 +663,22 @@
}); });
$('#select_actions').on('change', function() { $('#select_actions').on('change', function() {
var opt; var opt;
$('#action_parameters').append(domTableSelectedActions); domSectionSelectedActions.show();
opt = $('option:selected', this); opt = $('option:selected', this);
return fAddSelectedAction(opt.text()); return fAddSelectedAction(opt.text());
}); });
$('#selected_actions').on('click', 'img', function() { $('#selected_actions').on('click', 'img', function() {
var act, arrName, i, nMods, opt; var act, arrName, nMods, opt;
console.log('click');
act = $(this).closest('td').siblings('.title').text(); act = $(this).closest('td').siblings('.title').text();
arrName = act.split(' -> '); arrName = act.split(' -> ');
i = 0;
nMods = 0; nMods = 0;
$("#selected_actions td.title").each(function() { $("#selected_actions td.title").each(function() {
var arrNm; var arrNm;
i++;
arrNm = $(this).text().split(' -> '); arrNm = $(this).text().split(' -> ');
if (arrNm[0] === arrName[0]) { if (arrNm[0] === arrName[0]) {
return nMods++; return nMods++;
} }
}); });
if (i === 1) {
$('#action_parameters > *').detach();
}
if (nMods === 1) { if (nMods === 1) {
$('#action_invoker_params > div').each(function() { $('#action_invoker_params > div').each(function() {
if ($(this).children('div.modName').text() === arrName[0]) { if ($(this).children('div.modName').text() === arrName[0]) {
@ -673,6 +686,12 @@
} }
}); });
} }
if ($('#selected_actions td.title').length === 0) {
domSectionSelectedActions.hide();
}
if ($('#action_invoker_params > div').length === 0) {
domSectionActionParameters.hide();
}
opt = $('<option>').text(act); opt = $('<option>').text(act);
$('#select_actions').append(opt); $('#select_actions').append(opt);
return $(this).closest('tr').remove(); return $(this).closest('tr').remove();
@ -680,7 +699,7 @@
$('#but_submit').click(function() { $('#but_submit').click(function() {
var actFuncs, acts, ap, conds, ep, err, eventname, eventtype, evtFuncs, fCheckOverwrite, mins, obj, start; var actFuncs, acts, ap, conds, ep, err, eventname, eventtype, evtFuncs, fCheckOverwrite, mins, obj, start;
window.scrollTo(0, 0); window.scrollTo(0, 0);
$('#info').text(''); fClearInfo();
try { try {
if ($('#input_id').val() === '') { if ($('#input_id').val() === '') {
$('#input_id').focus(); $('#input_id').focus();
@ -704,6 +723,7 @@
eventname = $('#select_eventhook').val(); eventname = $('#select_eventhook').val();
break; break;
case 'Event Poller': case 'Event Poller':
eventname = $('#select_eventpoller').val();
ep = {}; ep = {};
$("#event_poller_params tr").each(function() { $("#event_poller_params tr").each(function() {
var encryptedParam, key, shielded, val; var encryptedParam, key, shielded, val;
@ -725,9 +745,9 @@
} }
}); });
evtFuncs = {}; evtFuncs = {};
evtFuncs[eventId] = []; evtFuncs[eventname] = [];
$('#event_poller_params tr.funcMappings').each(function() { $('#event_poller_params tr.funcMappings').each(function() {
return evtFuncs[eventId].push({ return evtFuncs[eventname].push({
argument: $('div.funcarg', this).text(), argument: $('div.funcarg', this).text(),
value: $('input[type=text]', this).val() value: $('input[type=text]', this).val()
}); });
@ -808,27 +828,28 @@
} }
}; };
}; };
if ($('#select_event_type') === 'Event Poller') { if ($('#select_event_type').val() === 'Event Poller') {
start = fConvertTimeToDate($('#input_start').val().toISOString()); start = fConvertTimeToDate($('#input_start').val()).toISOString();
mins = fConvertDayHourToMinutes($('#input_interval').val()); mins = fConvertDayHourToMinutes($('#input_interval').val());
} }
obj = console.log(obj); obj = {
command: 'forge_rule',
body: JSON.stringify({
id: $('#input_id').val(),
eventtype: eventtype,
eventname: eventname,
eventparams: ep,
eventstart: start,
eventinterval: mins,
eventfunctions: evtFuncs,
conditions: conds,
actions: acts,
actionparams: ap,
actionfunctions: actFuncs
})
};
return fIssueRequest({ return fIssueRequest({
data: { data: obj,
command: 'forge_rule',
body: JSON.stringify({
id: $('#input_id').val(),
eventname: eventId,
eventparams: ep,
eventstart: start,
eventinterval: mins,
eventfunctions: evtFuncs,
conditions: conds,
actions: acts,
actionparams: ap,
actionfunctions: actFuncs
})
},
done: function(data) { done: function(data) {
$('#info').text(data.message); $('#info').text(data.message);
return $('#info').attr('class', 'success'); return $('#info').attr('class', 'success');
@ -843,33 +864,51 @@
} }
}); });
if (oParams.id) { if (oParams.id) {
obj = {
command: 'get_rule',
data: JSON.stringify({
id: oParams.id
})
};
return fIssueRequest({ return fIssueRequest({
data: obj, data: {
command: 'get_rule',
body: JSON.stringify({
id: oParams.id
})
},
done: function(data) { done: function(data) {
var action, arrName, d, mins, oRule, _j, _len1, _ref, _results; var action, arrName, d, mins, oRule, _j, _len1, _ref, _results;
oRule = JSON.parse(data.message); oRule = JSON.parse(data.message);
if (oRule) { if (oRule) {
$('#input_id').val(oRule.id); $('#input_id').val(oRule.id);
$('#select_event').val(oRule.eventname); fPrepareEventType(oRule.eventtype);
if ($('#select_event').val() !== '') { switch (oRule.eventtype) {
fFetchEventParams(oRule.eventname); case 'Event Poller':
fPlaceAndPaintInterval(); $('#select_event').val(oRule.eventname);
if ($('#select_event').val() !== '') {
fFetchEventParams(oRule.eventname);
$('#input_event').val(oRule.eventname);
d = new Date(oRule.eventstart);
mins = d.getMinutes();
if (mins.toString().length === 1) {
mins = '0' + mins;
}
$('#input_start', domInputEventTiming).val(d.getHours() + ':' + mins);
$('#input_interval', domInputEventTiming).val(oRule.eventinterval);
} else {
window.scrollTo(0, 0);
$('#info').text('Error loading Rule: Your Event Poller does not exist anymore!');
$('#info').attr('class', 'error');
}
break;
case 'Webhook':
$('#select_eventhook').val(oRule.eventname);
if ($('#select_eventhook').val() === '') {
window.scrollTo(0, 0);
$('#info').text('Your Webhook does not exist anymore!');
$('#info').attr('class', 'error');
}
break;
case 'Custom Event':
$('#input_eventname').val(oRule.eventname);
} }
$('#input_event').val(oRule.eventname);
d = new Date(oRule.eventstart);
mins = d.getMinutes();
if (mins.toString().length === 1) {
mins = '0' + mins;
}
$('#input_start').val(d.getHours() + ':' + mins);
$('#input_interval').val(oRule.eventinterval);
editor.setValue(JSON.stringify(oRule.conditions, void 0, 2)); editor.setValue(JSON.stringify(oRule.conditions, void 0, 2));
domSectionSelectedActions.show();
_ref = oRule.actions; _ref = oRule.actions;
_results = []; _results = [];
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {

View file

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.7.1 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var arrKV, arrParams, fDisplayError, fFailedRequest, fIssueRequest, fOnLoad, fProcessWebhookList, fShowWebhookUsage, fUpdateWebhookList, hostUrl, oParams, param, _i, _len; var arrKV, arrParams, fClearInfo, fDisplayError, fFailedRequest, fIssueRequest, fOnLoad, fProcessWebhookList, fShowWebhookUsage, fUpdateWebhookList, hostUrl, oParams, param, _i, _len;
arrParams = window.location.search.substring(1).split('&'); arrParams = window.location.search.substring(1).split('&');
@ -18,6 +18,11 @@
hostUrl = [location.protocol, '//', location.host].join(''); hostUrl = [location.protocol, '//', location.host].join('');
fClearInfo = function() {
$('#info').text('');
return $('#info').attr('class', 'neutral');
};
fDisplayError = function(msg) { fDisplayError = function(msg) {
window.scrollTo(0, 0); window.scrollTo(0, 0);
$('#info').text("Error: " + msg); $('#info').text("Error: " + msg);
@ -25,7 +30,7 @@
}; };
fIssueRequest = function(args) { fIssueRequest = function(args) {
$('#info').text(''); fClearInfo();
return $.post('/usercommand', args.body).done(args.done).fail(args.fail); return $.post('/usercommand', args.body).done(args.done).fail(args.fail);
}; };
@ -98,7 +103,7 @@
fUpdateWebhookList(fShowWebhookUsage); fUpdateWebhookList(fShowWebhookUsage);
$('#but_submit').click(function() { $('#but_submit').click(function() {
var hookname; var hookname;
$('#info').text(''); fClearInfo();
hookname = $('#inp_hookname').val(); hookname = $('#inp_hookname').val();
if (hookname === '') { if (hookname === '') {
return fDisplayError('Please provide an Event Name for your new Webhook!'); return fDisplayError('Please provide an Event Name for your new Webhook!');

View file

@ -10,6 +10,6 @@
} }
</div> </div>
</div> </div>
<button id="but_prepare" style="width:200px">Prepare a Rule for this Event</button> <button id="but_prepare" style="width:300px">Prepare a Rule for this Event</button>
<br> <br>
<button id="but_submit" style="width:200px">Push Event into System</button> <button id="but_submit" style="width:300px">Push Event into System</button>

View file

@ -17,7 +17,7 @@
<tr><td> <tr><td>
<h2>CONDITIONS</h2> <h2>CONDITIONS</h2>
<div id="conditions"> <div id="conditions">
Refer to <a target="_blank" href="https://github.com/harthur/js-select#selectors">js-select selectors</a> for valid selectors! Refer to <a target="_blank" href="https://github.com/harthur/js-select#selectors">js-select selectors</a> for valid selectors!<br>
<div id="editor_conditions"> <div id="editor_conditions">
[ [
{ {
@ -29,6 +29,7 @@ Refer to <a target="_blank" href="https://github.com/harthur/js-select#selectors
] ]
</div> </div>
</div> </div>
<button class="outent20" id="fill_example">Fill with example condition</button>
</td></tr> </td></tr>
<tr><td> <tr><td>
@ -36,5 +37,6 @@ Refer to <a target="_blank" href="https://github.com/harthur/js-select#selectors
<select id="select_actions"><option></option></select> <select id="select_actions"><option></option></select>
<br><br> <br><br>
<div id="action_parameters"></div> <div id="action_parameters"></div>
<button id="but_submit">save</button> <br><br>
<button id="but_submit">Save Rule</button>
</td></tr></table> </td></tr></table>

View file

@ -31,10 +31,18 @@ input[type=password]:focus {
border: 1px solid rgba(81, 203, 238, 1); border: 1px solid rgba(81, 203, 238, 1);
} }
button {
font-size: 1.2em;
}
.indent20 { .indent20 {
padding-left: 20px; padding-left: 20px;
} }
.outent20 {
margin-left: 20px;
}
#mobile { #mobile {
margin: 10px 20px 10px 20px; margin: 10px 20px 10px 20px;
} }
@ -65,6 +73,7 @@ input[type=password]:focus {
} }
#info { #info {
height: 20px;
padding-left: 20px; padding-left: 20px;
line-height: 2em; line-height: 2em;
font-family: Tahoma, sans-serif; font-family: Tahoma, sans-serif;
@ -72,6 +81,11 @@ input[type=password]:focus {
font-weight: bold; font-weight: bold;
} }
.neutral {
background-color: #EEF;
color: #050;
}
.success { .success {
background-color: #CFC; background-color: #CFC;
color: #050; color: #050;