date sanity to store in javascript/UTC but display in user/browser timezone

This commit is contained in:
Jeff Bryner 2014-07-25 10:52:42 -07:00
Родитель 5c0e9e8526
Коммит d716de4a69
5 изменённых файлов: 152 добавлений и 104 удалений

Просмотреть файл

@ -10,6 +10,12 @@ Jeff Bryner jbryner@mozilla.com
<!--new incident form --> <!--new incident form -->
<template name="addincidentform"> <template name="addincidentform">
<style>
.daterangepicker td{
color:black;
}
</style>
<form id="addincidentform" class="form-horizontal" style="margin: 0px 30% 20px;"> <form id="addincidentform" class="form-horizontal" style="margin: 0px 30% 20px;">
<legend>New Incident</legend> <legend>New Incident</legend>
<fieldset> <fieldset>
@ -17,23 +23,25 @@ Jeff Bryner jbryner@mozilla.com
<div class="control-group"> <div class="control-group">
<label class="control-label" for="summary">Incident Summary</label> <label class="control-label" for="summary">Incident Summary</label>
<div class="controls"> <div class="controls">
<input id="summary" name="summary" placeholder="summary" class="input-xlarge summary" required="" type="text"> <input id="summary" name="summary" placeholder="summary" class="input-xxlarge summary" required="" type="text">
</div> </div>
</div> </div>
<!-- date Opened --> <!-- date Opened -->
<div class="control-group"> <div class="control-group">
<label class="control-label" for="dateOpened">Date Opened</label> <label class="control-label" for="dateOpened">Date Opened</label>
<div class="controls"> <div class="controls">
<input class="input-xlarge dateOpened" name="dateOpened" id="dateOpened" type="text" placeholder="today" value="{{now}}"> <div class="input-prepend input-group">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="input dateOpened calendarfield" name="dateOpened" id="dateOpened" type="text" placeholder="today" value="{{uiDateFormat now}}">
</div>
</div> </div>
</div> </div>
<!-- Phase --> <!-- Phase -->
<div class="control-group"> <div class="control-group">
<label class="control-label" for="phase">Phase</label> <label class="control-label" for="phase">Phase</label>
<div class="controls"> <div class="controls">
<select id="phase" name="phase" class="input-xlarge"> <select id="phase" name="phase" class="input-xlarge">
<option >Identification</option> <option>Identification</option>
<option>Containment</option> <option>Containment</option>
<option>Eradication</option> <option>Eradication</option>
<option>Recovery</option> <option>Recovery</option>

Просмотреть файл

@ -72,7 +72,7 @@ Jeff Bryner jbryner@mozilla.com
<div class="controls"> <div class="controls">
<div class="input-prepend input-group"> <div class="input-prepend input-group">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span> <span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="input dateOpened calendarfield" name="dateOpened" id="dateOpened" type="text" placeholder="today" value="{{dateOpened}}"> <input class="input dateOpened calendarfield" name="dateOpened" id="dateOpened" type="text" placeholder="today" value="{{uiDateFormat dateOpened}}">
</div> </div>
</div> </div>
</div> </div>
@ -82,7 +82,7 @@ Jeff Bryner jbryner@mozilla.com
<div class="controls"> <div class="controls">
<div class="input-prepend input-group"> <div class="input-prepend input-group">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span> <span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="form-control dateClosed calendarfield" name="dateClosed" id="dateClosed" type="text" value="{{dateClosed}}"> <input class="form-control dateClosed calendarfield" name="dateClosed" id="dateClosed" type="text" value="{{uiDateFormat dateClosed}}">
</div> </div>
</div> </div>
</div> </div>
@ -117,20 +117,20 @@ Jeff Bryner jbryner@mozilla.com
<div class="controls"> <div class="controls">
<div class="input-prepend input-group input-append"> <div class="input-prepend input-group input-append">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span> <span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="form-control dateReported calendarfield" name="dateReported" id="dateReported" type="text" value="{{dateReported}}"> <input class="form-control dateReported calendarfield" name="dateReported" id="dateReported" type="text" value="{{uiDateFormat dateReported}}">
<span class="add-on" style="padding-right:12px">Reported</span> <span class="add-on" style="padding-right:12px">Reported</span>
</div> </div>
<div class="input-prepend input-group input-append"> <div class="input-prepend input-group input-append">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span> <span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="form-control dateVerified calendarfield" name="dateVerified" id="dateVerified" type="text" value="{{dateVerified}}"><span class="add-on" style="padding-right: 20px">Verified</span> <input class="form-control dateVerified calendarfield" name="dateVerified" id="dateVerified" type="text" value="{{uiDateFormat dateVerified}}"><span class="add-on" style="padding-right: 20px">Verified</span>
</div> </div>
<div class="input-prepend input-group input-append"> <div class="input-prepend input-group input-append">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span> <span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="form-control dateMitigated calendarfield" name="dateMitigated" id="dateMitigated" type="text" value="{{dateMitigated}}"><span class="add-on" style="padding-right:10px">Mitigated</span> <input class="form-control dateMitigated calendarfield" name="dateMitigated" id="dateMitigated" type="text" value="{{uiDateFormat dateMitigated}}"><span class="add-on" style="padding-right:10px">Mitigated</span>
</div> </div>
<div class="input-prepend input-group input-append"> <div class="input-prepend input-group input-append">
<span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span> <span class="add-on input-group-addon"><i class="icon-calendar fa fa-calendar"></i></span>
<input class="form-control dateContained calendarfield" name="dateContained" id="dateContained" type="text" value="{{dateContained}}"><span class="add-on" style="padding-right:7px">Contained</span> <input class="form-control dateContained calendarfield" name="dateContained" id="dateContained" type="text" value="{{uiDateFormat dateContained}}"><span class="add-on" style="padding-right:7px">Contained</span>
</div> </div>
</div> </div>

Просмотреть файл

@ -38,7 +38,7 @@ if (Meteor.isClient) {
Template.incidents.events({ Template.incidents.events({
"click": function(e,t){ "click": function(e,t){
if (this._id != undefined){ if (this._id != undefined){
Session.set('displayMessage','Starting edit for incident._id: ' + this._id); //Session.set('displayMessage','Starting edit for incident._id: ' + this._id);
Router.go('/incident/' + this._id + '/edit'); Router.go('/incident/' + this._id + '/edit');
} }
} }
@ -46,24 +46,11 @@ if (Meteor.isClient) {
Template.incidents.rendered = function(){ Template.incidents.rendered = function(){
Meteor.subscribe("incidents-summary"); Deps.autorun(function() {
Meteor.subscribe("incidents-summary");
});
}; };
//edit helpers
Template.editincidentform.helpers({
incident: function() {
return incidents.findOne(Session.get('incidentID'));
},
eachSort: function(context,options){
var ret = "";
for(var i=0, j=context.length; i<j; i++) {
ret = ret + options.fn(context.sort()[i]);
}
return ret;
}
});
var incidentRevision = function() { var incidentRevision = function() {
this.save = function(e, template) { this.save = function(e, template) {
@ -71,17 +58,19 @@ if (Meteor.isClient) {
incidentSaveTimer.clear(); incidentSaveTimer.clear();
// tags are saved in real realtime (without timer) // tags are saved in real realtime (without timer)
// other tabs are saved as they are changed
// this is only for the main tab
var incidentobj = { var incidentobj = {
summary: template.find("#summary").value, summary: template.find("#summary").value,
description: template.find("#description").value, description: template.find("#description").value,
dateOpened: template.find("#dateOpened").value, dateOpened: dateOrNull(template.find("#dateOpened").value),
dateClosed: template.find("#dateClosed").value, dateClosed: dateOrNull(template.find("#dateClosed").value),
phase: template.find("#phase").value, phase: template.find("#phase").value,
dateReported: template.find("#dateReported").value, dateReported: dateOrNull(template.find("#dateReported").value),
dateVerified: template.find("#dateVerified").value, dateVerified: dateOrNull(template.find("#dateVerified").value),
dateMitigated: template.find("#dateMitigated").value, dateMitigated: dateOrNull(template.find("#dateMitigated").value),
dateContained: template.find("#dateContained").value dateContained: dateOrNull(template.find("#dateContained").value)
} }
incidents.update(Session.get('incidentID'), incidents.update(Session.get('incidentID'),
@ -114,13 +103,13 @@ if (Meteor.isClient) {
template.find("#summary").value = incident.summary; template.find("#summary").value = incident.summary;
template.find("#description").value = incident.description; template.find("#description").value = incident.description;
template.find("#dateOpened").value = incident.dateOpened; template.find("#dateOpened").value = dateFormat(incident.dateOpened);
template.find("#dateClosed").value = incident.dateClosed; template.find("#dateClosed").value = dateFormat(incident.dateClosed);
template.find("#phase").value = incident.phase; template.find("#phase").value = incident.phase;
template.find("#dateReported").value = incident.dateReported; template.find("#dateReported").value = dateFormat(incident.dateReported);
template.find("#dateVerified").value = incident.dateVerified; template.find("#dateVerified").value = dateFormat(incident.dateVerified);
template.find("#dateMitigated").value = incident.dateMitigated; template.find("#dateMitigated").value = dateFormat(incident.dateMitigated);
template.find("#dateContained").value = incident.dateContained; template.find("#dateContained").value = dateFormat(incident.dateContained);
} }
} }
@ -135,13 +124,13 @@ if (Meteor.isClient) {
template.find("#summary").value = incident.summary; template.find("#summary").value = incident.summary;
template.find("#description").value = incident.description; template.find("#description").value = incident.description;
template.find("#dateOpened").value = incident.dateOpened; template.find("#dateOpened").value = dateFormat(incident.dateOpened);
template.find("#dateClosed").value = incident.dateClosed; template.find("#dateClosed").value = dateFormat(incident.dateClosed);
template.find("#phase").value = incident.phase; template.find("#phase").value = incident.phase;
template.find("#dateReported").value = incident.dateReported; template.find("#dateReported").value = dateFormat(incident.dateReported);
template.find("#dateVerified").value = incident.dateVerified; template.find("#dateVerified").value = dateFormat(incident.dateVerified);
template.find("#dateMitigated").value = incident.dateMitigated; template.find("#dateMitigated").value = dateFormat(incident.dateMitigated);
template.find("#dateContained").value = incident.dateContained; template.find("#dateContained").value = dateFormat(incident.dateContained);
} }
} }
@ -186,7 +175,6 @@ if (Meteor.isClient) {
e.preventDefault(); //allow the drag e.preventDefault(); //allow the drag
}, },
"keyup .tagfilter":function(e,template){ "keyup .tagfilter":function(e,template){
//console.log(e);
//var letter_pressed = String.fromCharCode(e.keyCode); //var letter_pressed = String.fromCharCode(e.keyCode);
//console.log(template.find("#tagfilter").value); //console.log(template.find("#tagfilter").value);
Session.set('verisfilter',template.find("#tagfilter").value); Session.set('verisfilter',template.find("#tagfilter").value);
@ -194,7 +182,6 @@ if (Meteor.isClient) {
}, },
"drop .tags": function(e){ "drop .tags": function(e){
e.preventDefault(); e.preventDefault();
//console.log(e)
tagtext = e.originalEvent.dataTransfer.getData("text/plain"); tagtext = e.originalEvent.dataTransfer.getData("text/plain");
//e.target.textContent=droptag //e.target.textContent=droptag
//console.log(tagtext) //console.log(tagtext)
@ -368,70 +355,83 @@ if (Meteor.isClient) {
} }
}); });
Template.editincidentform.rendered = function() { Template.editincidentform.rendered = function() {
if (typeof console !== 'undefined') { initDatePickers=function(){
console.log('load edit incident form ' + Session.get('incidentID')); //init the date pickers.
} $('#dateClosed').daterangepicker({
//init the date pickers. singleDatePicker: true,
$('#dateClosed').daterangepicker({ timePicker:true,
singleDatePicker: true, timePickerIncrement:1,
timePicker:true, format: 'MM/DD/YYYY hh:mm:ss A',
timePickerIncrement:1, startDate: dateOrNull($('#dateClosed').val() ) || moment()
format: 'MM/DD/YYYY hh:mm:ss A', });
startDate: moment() $('#dateOpened').daterangepicker({
}); singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: dateOrNull($('#dateOpened').val() ) || moment()
});
$('#dateReported').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: dateOrNull($('#dateReported').val() ) || moment()
});
$('#dateVerified').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: dateOrNull($('#dateVerified').val() ) || moment()
});
$('#dateMitigated').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: dateOrNull($('#dateMitigated').val() ) || moment()
});
$('#dateContained').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: dateOrNull($('#dateContained').val() ) || moment()
});
};
//set up reactive data
Deps.autorun(function() {
//Meteor.subscribe("incidents-details",Session.get('incidentID'));
Meteor.subscribe("incidents-details",Session.get('incidentID'), onReady=function(){
initDatePickers();
});
}); //end deps.autorun
};
Template.addincidentform.rendered = function() {
$('#dateOpened').daterangepicker({ $('#dateOpened').daterangepicker({
singleDatePicker: true, singleDatePicker: true,
timePicker:true, timePicker:true,
timePickerIncrement:1, timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A', format: 'MM/DD/YYYY hh:mm:ss A',
startDate: moment() startDate: moment()
}); });
$('#dateReported').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: moment()
});
$('#dateVerified').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: moment()
});
$('#dateMitigated').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: moment()
});
$('#dateContained').daterangepicker({
singleDatePicker: true,
timePicker:true,
timePickerIncrement:1,
format: 'MM/DD/YYYY hh:mm:ss A',
startDate: moment()
});
//set up reactive data
Deps.autorun(function() {
Meteor.subscribe("incidents-details",Session.get('incidentID'));
}); //end deps.autorun
}; };
//add incident events //add incident events
Template.addincidentform.events({ Template.addincidentform.events({
"submit form": function(event, template) { "submit form": function(event, template) {
event.preventDefault(); event.preventDefault();
incidents.insert({ newIncident=models.incident();
summary: template.find("#summary").value, newIncident.summary= template.find("#summary").value,
dateOpened: template.find("#dateOpened").value, newIncident.dateOpened=dateOrNull(template.find("#dateOpened").value),
phase: template.find("#phase").value newIncident.phase=template.find("#phase").value
}); newid=incidents.insert(newIncident);
//TODO; reroute to full blown edit form after this minimal input is complete //reroute to full blown edit form after this minimal input is complete
Router.go('/incidents/') Router.go('/incident/' + newid + '/edit');
} }
}); });

Просмотреть файл

@ -11,12 +11,39 @@ Anthony Verez averez@mozilla.com
if (Meteor.isClient) { if (Meteor.isClient) {
//defaults: //defaults:
Meteor.startup(function () { Meteor.startup(function () {
Session.set('verisfilter',''); Session.set('verisfilter','');
Session.set('alertsearchtext',''); Session.set('alertsearchtext','');
}); });
//helper functions for UI templates
//and other client javascript routines
dateOrNull=function(maybeDate){
adate=moment(maybeDate);
if (adate.isValid()) {
return adate.toDate();
}else{
return null;
}
};
dateFormat=function(adate){
mdate=moment(adate || null);
if (mdate.isValid()) {
dformat='MM/DD/YYYY hh:mm:ss A';
return mdate.format(dformat);
}else{
return '';
}
};
//debug/testing functions //debug/testing functions
debugLog=function(logthis){
if (typeof console !== 'undefined') {
console.log(logthis);
}
};
Template.hello.greeting = function () { Template.hello.greeting = function () {
if (typeof console !== 'undefined') if (typeof console !== 'undefined')
console.log("mozdef starting"); console.log("mozdef starting");
@ -35,6 +62,10 @@ if (Meteor.isClient) {
Meteor.call('loadKibanaDashboards'); Meteor.call('loadKibanaDashboards');
return kibanadashboards.find(); return kibanadashboards.find();
}; };
UI.registerHelper('uiDateFormat',function(adate){
return dateFormat(adate);
});
//helper functions for handlebars //helper functions for handlebars
UI.registerHelper('now', function() { UI.registerHelper('now', function() {

Просмотреть файл

@ -88,7 +88,16 @@ if (Meteor.isServer) {
Meteor.publish("incidents-summary", function () { Meteor.publish("incidents-summary", function () {
return incidents.find({}, {limit:100}); return incidents.find({},
{fields: {
_id:1,
summary:1,
phase:1,
dateOpened:1,
dateClosed:1
},
sort: {dateOpened: -1},
limit:100});
}); });
Meteor.publish("incidents-details",function(incidentid){ Meteor.publish("incidents-details",function(incidentid){