WIP reorganization

This commit is contained in:
Erik Ziegler committed 2018-12-12 09:10:39 +01:00
1 parent 6706dfe634
commit 054e37dfb7
266 files changed
+98 -620

No files matched your search

@@ -0,0 +1,188 @@
<template name="hipaaAuditLog">
<ul id="hipaaAuditLog" class="list-group">
{{#each hipaaAudit}}
{{> hipaaEntry}}
{{/each}}
</ul>
</template>
<template name="hipaaEntry">
{{#if logMessageType 'init'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-gears fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> initialized HIPAA Audit Log.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'access'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-database fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> accessed record(s) <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'create'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-plus-circle fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
{{#if hasPatientInfo}}
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> created record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection, regarding patient <span class="patientName" style="{{getHighlightColor}}">{{getPatientName}}</span>.
{{else}}
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> created record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
{{/if}}
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'modify'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-pencil fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
{{#if hasPatientInfo}}
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> modified record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection, regarding patient <span class="patientName" style="{{getHighlightColor}}">{{getPatientName}}</span>.
{{else}}
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> modified record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
{{/if}}
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'clone'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-code-fork fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> cloned record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'delete'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-minus-circle fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> deleted record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'denied'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-warning fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> was denied access to record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'viewed'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-eye fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
{{#if hasPatientInfo}}
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> viewed record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection, regarding patient <span class="patientName" style="{{getHighlightColor}}">{{getPatientName}}</span>.
{{else}}
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> viewed record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
{{/if}}
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'publish'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-rss fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> published record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'unpublish'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-circle-o fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> unpublished record <span class="mongoRecordId" style="{{getHighlightColor}}">{{getRecordId}}</span> in the <span class="collectionName" style="{{getHighlightColor}}">{{getCollectionName}}</span> collection.
</div>
</div>
</li>
{{/if}}
{{#if logMessageType 'error'}}
<li class="hipaaAuditItem list-group-item">
<div class="media">
<div class="media-icon">
<i class="fa fa-bomb fa-2x"></i>
</div>
<div class="media-body">
<span class="small gray">{{entryTimestamp}}</span><br>
<span class="userName" style="{{getHighlightColor}}">{{userName}}</span> received a data access error while performing an action!<br>
<span class="error">{{getErrorMessage}}</span>
</div>
</div>
</li>
{{/if}}
</template>
@@ -0,0 +1,160 @@
//Hipaa = new Meteor.Collection("hipaa");
Session.setDefault("hipaaSearchFilter", '');
Session.setDefault("hipaaTypeFilter", '');
// search window defaults to seven days in the past and one day in the future
Session.setDefault("beginDateFilter", new Date(moment().subtract(7, "days")).toISOString());
Session.setDefault("endDateFilter", new Date(moment().add(1, "days")).toISOString());
Template.hipaaAuditLog.onRendered(function () {
Session.set("ribbonWidth", $('#hipaaRibbon').width());
});
Template.hipaaAuditLog.helpers({
getHipaaSearchFilter: function () {
return Session.get('hipaaSearchFilter');
},
hipaaAudit: function () {
// return HipaaLog.find();
return HipaaLog.find({
$or: [
{
userName: {
$regex: Session.get('hipaaSearchFilter'),
$options: 'i'
}
},
{
patientName: {
$regex: Session.get('hipaaSearchFilter'),
$options: 'i'
}
},
{
recordId: {
$regex: Session.get('hipaaSearchFilter'),
$options: 'i'
}
},
{
collectionName: {
$regex: Session.get('hipaaSearchFilter'),
$options: 'i'
}
}
],
eventType: {
$regex: Session.get("hipaaTypeFilter"),
$options: 'i'
},
timestamp: {
$lte: new Date(Session.get('endDateFilter')),
$gte: new Date(Session.get('beginDateFilter'))
}
}, {
sort: {
timestamp: -1
}
});
}
});
Template.hipaaAuditLog.events({
"keyup #hipaaSearchFilter": function (event, template) {
Session.set("hipaaSearchFilter", $('#hipaaSearchFilter').val());
},
"click .userName": function(event, template) {
var userName = $(event.currentTarget).text();
Session.set('hipaaSearchFilter', userName);
},
"click .patientName": function(event, template) {
var patientName = $(event.currentTarget).text();
var patientNameRegex = patientName.replace(/[!@#$%^&*()+=\-[\]\\';,./{}|":<>?~_]/g, "\\$&");
Session.set('hipaaSearchFilter', patientNameRegex);
},
"click .mongoRecordId": function(event, template) {
var mongoRecordId = $(event.currentTarget).text();
Session.set('hipaaSearchFilter', mongoRecordId);
},
"click .collectionName": function(event, template) {
var collectionName = $(event.currentTarget).text();
Session.set('hipaaSearchFilter', collectionName);
}
});
//==================================================================================================
// HIPAA EVENT RECORD
Template.hipaaEntry.helpers({
getHighlightColor: function () {
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
if (hipaaAuditLog) {
return "color:" + hipaaAuditLog.highlightColor;
} else {
return null;
}
},
getUserName: function () {
if (this.userName) {
return this.userName;
} else {
return "---";
}
},
getPatientName: function () {
if (this.patientName) {
return this.patientName;
} else {
return "---";
}
},
hasPatientInfo: function () {
if (this.patientName) {
return true;
} else {
return false;
}
},
getErrorMessage: function () {
if (this.message) {
return this.message;
} else {
return "---";
}
},
getCollectionName: function () {
if (this.collectionName) {
return this.collectionName;
} else {
return "---";
}
},
getRecordId: function () {
if (this.recordId) {
return this.recordId;
} else {
return "---";
}
},
entryTimestamp: function () {
return moment(this.timestamp).format("YYYY, MMM DD, hh:mm A");
},
entryTime: function () {
return moment(this.timestamp).format("HH:MM A");
},
entryDate: function () {
return moment(this.timestamp).format("YYYY, MMM DD");
},
logMessageType: function (eventType) {
if (this.eventType === eventType) {
return true;
} else {
return false;
}
}
});
@@ -0,0 +1,54 @@
#hipaaAuditLog{
color: #fff;
width: 100%;
.hipaaAuditItem {
border: none;
background-color: black;
list-style: none;
padding: 10px;
line-height: 25px;
// There's a CSS rule on ohif-user-management that's changing the .hipaaAuditItem border style (w/ !important)
&:first-child {
border-top: none !important;
}
&:not(:first-child) {
border-top: 1px solid #436270;
}
border-bottom: 1px solid #436270;
&:nth-child(even) {
background-color: #151a1f;
}
&:hover, &:active, &.active {
background-color: #2c363f;
color: white;
}
.item-icon {
top: 12px;
position: relative;
}
.media-icon {
float: left;
top: 12px;
width: 40px;
text-align: center;
position: relative;
margin-right: 10px;
}
}
.gray{
color: gray;
}
.userName, .patientName, .mongoRecordId, .collectionName{
cursor: pointer;
}
}
@@ -0,0 +1,13 @@
<template name="hipaaCloseButton">
<div class="close-btn">
{{#if header}}
<button type="button" class="close">
<span>&times;</span>
</button>
{{else}}
<button type="button" class="btn btn-default">
Close
</button>
{{/if}}
</div>
</template>
@@ -0,0 +1,12 @@
Template.hipaaCloseButton.events({
'click button': function() {
var history = window.history;
if(history.length > 0) {
history.go(-1);
}
else {
window.location = '/'
}
}
});
@@ -0,0 +1,44 @@
@tableTextSecondaryColor: #91b9cd;
.close-btn {
text-align: right;
padding: 5px 5px 0;
&:before,
&:after {
display: table;
content: " ";
clear: both;
}
.close {
color: @tableTextSecondaryColor;
opacity: 1;
&.close:hover, &.close:focus {
color: #fff;
opacity: 1;
}
}
.btn-default {
margin-bottom: 5px;
margin-right: 5%;
}
}
@media only screen and (max-width: 1161px) {
.close-btn {
.btn-default {
margin-right: 3%;
}
}
}
@media only screen and (max-width: 991px) {
.close-btn {
.btn-default {
margin-right: 1%;
}
}
}
@@ -0,0 +1,26 @@
<template name="hipaaLogPage">
<div id="hipaaLogPage" class="page">
<div class="hipaaHeader clearfix">
<div class="header pull-left">
Audit Log
</div>
<div class="pull-right">
{{> hipaaCloseButton header="true" }}
</div>
</div>
{{> hipaaRibbon }}
<div class="container">
<div class="row">
{{> hipaaAuditLog}}
</div>
</div>
{{#if hasCloseButtons}}
{{> hipaaCloseButton }}
{{/if}}
</div>
</template>
@@ -0,0 +1,17 @@
Router.route("/audit", {
name:"hipaaAuditLogRoute",
template:"hipaaLogPage"
});
Template.hipaaLogPage.helpers({
hasCloseButtons: function() {
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
return hipaaAuditLog && hipaaAuditLog.closeButton;
}
});
// We probably don't need this, but the subscription in subscriptions.js doesn't seem to be working?
Template.hipaaLogPage.onCreated(function() {
this.subscribe('HipaaLog');
})
@@ -0,0 +1,52 @@
@tableTextSecondaryColor: #91b9cd;
@hipaaHeaderHeight: 75px;
@hipaaHeaderBgColor: #151a1f;
#hipaaLogPage {
background-color: #000;
.hipaaHeader {
background-color: @hipaaHeaderBgColor;
height: @hipaaHeaderHeight;
margin-bottom: 2px;
padding: 0 20px;
& > div {
display: inline-block;
}
.header {
font-size: 22px;
font-weight: 300;
color: @tableTextSecondaryColor;
line-height: @hipaaHeaderHeight;
}
}
.container {
margin: 0;
padding: 0 5%;
width: 100%;
& > div.row {
margin: 0;
}
}
}
@media only screen and (max-width: 1161px) {
#hipaaLogPage {
.container {
padding: 0 3%;
}
}
}
@media only screen and (max-width: 991px) {
#hipaaLogPage {
.container {
padding: 0 1%;
}
}
}
@@ -0,0 +1,28 @@
<template name="hipaaRibbon">
<div id="hipaaRibbon" class="row {{getRibbonClass}}">
<div class="filter col-xs-12 col-sm-4 col-md-6">
<span>User</span>
<div class="btn-group">
<input type="text" name="hipaaSearchFilter" id="hipaaSearchFilter" value="{{getHipaaSearchFilter}}" class="form-control">
<span id="searchClear" class="glyphicon glyphicon-remove-circle"></span>
</div>
</div>
<div class="filter col-xs-4 col-sm-3 col-md-2 text-center">
<span>Begin Date</span>
<input type="date" id="beginDateInput" class="{{getInputClass}}" value="{{getBeginDate}}">
</div>
<div class="filter col-xs-4 col-sm-3 col-md-2 text-center">
<span>End Date</span>
<input type="date" id="endDateInput" class="{{getInputClass}}" value="{{getEndDate}}">
</div>
<div class="filter col-xs-4 col-sm-2 text-center">
<span>Action</span>
<select id="actionFilter" name="actionFilter" class="{{getSelectClass}}">
<option id="filterCreatedButton" value="create">Created</option>
<option id="filterModifiedButton" value="modify">Modified</option>
<option id="filterViewedButton" value="viewed">Viewed</option>
<option id="filterAllButton" selected value="">All</option>
</select>
</div>
</div>
</template>
@@ -0,0 +1,75 @@
Template.hipaaRibbon.events({
'keyup #hipaaSearchFilter': function () {
Session.set("hipaaSearchFilter", $('#hipaaSearchFilter').val());
},
"change #beginDateInput": function (event, template) {
Session.set("beginDateFilter", $('#beginDateInput').val() + "T00:00:00.000Z");
},
"change #endDateInput": function (event, template) {
Session.set("endDateFilter", $('#endDateInput').val() + "T00:00:00.000Z");
},
'change #actionFilter': function(e) {
var actionType = e.currentTarget.value;
Session.set("hipaaTypeFilter", actionType);
},
'click #filterCreatedButton': function () {
Session.set("hipaaTypeFilter", 'create');
},
'click #filterModifiedButton': function () {
Session.set("hipaaTypeFilter", 'modify');
},
'click #filterViewedButton': function () {
Session.set("hipaaTypeFilter", 'viewed');
},
'click #filterAllButton': function () {
Session.set("hipaaTypeFilter", '');
},
'click #searchClear': function() {
Session.set("hipaaSearchFilter", '');
}
});
var ribbonBreakPoint = 760;
Meteor.startup(function(){
$(window).resize(function(evt) {
Session.set("ribbonWidth", $('#hipaaRibbon').width());
});
});
Template.hipaaRibbon.helpers({
getRibbonClass: function () {
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
if (hipaaAuditLog && hipaaAuditLog.classes) {
return hipaaAuditLog.classes.ribbon;
} else {
return null;
}
},
getSelectClass: function () {
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
if (hipaaAuditLog && hipaaAuditLog.classes) {
return hipaaAuditLog.classes.select;
} else {
return null;
}
},
getInputClass: function () {
var hipaaAuditLog = Session.get('HipaaAuditLogConfig');
if (hipaaAuditLog && hipaaAuditLog.classes) {
return hipaaAuditLog.classes.input;
} else {
return null;
}
},
getHipaaSearchFilter: function () {
return Session.get('hipaaSearchFilter');
},
getBeginDate: function () {
return moment(Session.get("beginDateFilter")).format("YYYY-MM-DD");
},
getEndDate: function () {
return moment(Session.get("endDateFilter")).format("YYYY-MM-DD");
}
});
@@ -0,0 +1,113 @@
@tableTextPrimaryColor: white;
@tableTextSecondaryColor: #91b9cd;
@inputBackgroundColor: #2c363f;
@inputPlaceholderColor: lightgray;
@hipaaRibbonBgColor: #151a1f;
#hipaaRibbon {
background-color: @hipaaRibbonBgColor;
border-bottom: solid 1px #6fbde2;
color: @tableTextPrimaryColor;
margin: 0 0 2px;
padding: 20px 5%;
.filter {
> span {
font-size: 15px;
display: block;
padding: 5px;
}
min-height: 70px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
&:not(:last-child) {
padding-right: 0;
}
}
input[type="date"] {
padding-left: 10px;
}
select {
display: inline-block;
}
input, select {
height: 40px;
padding: 20px;
cursor: pointer;
border: none;
background-color: @inputBackgroundColor;
color: @inputPlaceholderColor;
font-size: 10pt;
font-weight: normal;
width: 100%;
border-radius: 4px;
box-sizing: border-box;
transition: all 0.15s ease;
-webkit-transition: all 0.15s ease;
&:active, &:hover {
background-color: @inputBackgroundColor;
}
}
.btn-group {
width: 100%;
#hipaaSearchFilter{
padding-right: 35px;
}
#searchClear {
position: absolute;
right: 14px;
top: 0;
bottom: 0;
height: 14px;
margin: auto;
font-size: 14px;
cursor: pointer;
color: #ccc;
}
}
}
@media only screen and (max-width: 1161px) {
#hipaaRibbon {
padding: 20px 3%;
}
}
@media only screen and (max-width: 991px) {
#hipaaRibbon {
padding: 20px 1%;
}
}
@media only screen and (max-width: 767px) {
#hipaaRibbon {
.filter {
&:first-child {
padding-bottom: 15px;
}
&:nth-child(2) {
padding-left: 0;
}
}
}
}
@@ -0,0 +1 @@
Meteor.subscribe('HipaaLog');