add listing of saved reports

report-manager
Moe 2023-07-18 20:26:58 -07:00
parent 7fb6a974fd
commit a142063c64
5 changed files with 228 additions and 181 deletions

View File

@ -9117,6 +9117,7 @@ module.exports = function(s,config,lang){
"Created Reports": {
"name": lang["Created Reports"],
"color": "green",
"section-pre-class": "col-md-3",
"info": [
{
"field": lang.Monitor,
@ -9139,12 +9140,16 @@ module.exports = function(s,config,lang){
"attribute": `href="javascript:openTab('reportManagerForm')"`,
"btnContent": `<i class="fa fa-refresh"></i> &nbsp; ${lang['Submission Form']}`,
},
{
"fieldType": "div",
"id": "report-manager-list",
}
]
},
"Report Display": {
"color": "green",
"noHeader": true,
"noDefaultSectionClasses": true,
"section-pre-class": "col-md-9",
"info": [
{
"fieldType": "div",

View File

@ -38,7 +38,10 @@ module.exports = function(s,config,lang,app,io){
table: "Reports",
where: whereQuery,
})
return selectResponse
selectResponse.rows.forEach((row) => {
row.details = JSON.parse(row.details)
})
return selectResponse.rows
}
async function getNewReportId(groupKey, monitorId){
const newReportId = s.gid(25)
@ -109,6 +112,7 @@ module.exports = function(s,config,lang,app,io){
s.debugLog(`Copied Files!`)
const outputZipPath = `${tempDirectory}.zip`
const moveZipToPath = `${moveZipToDirectory}.zip`
s.debugLog(`Path to Zip`,tempDirectory)
s.debugLog(`outputZipPath`,outputZipPath)
s.debugLog(`Zipping...`,moveZipToPath)
// save files to zip
@ -244,7 +248,7 @@ module.exports = function(s,config,lang,app,io){
var videoSnapLegend = {}
videos.forEach((video) => {
var videoPath = s.getVideoDirectory(video) + video.filename
var frames = video.timelapseFrames || []
var frames = video.frames || []
videoPaths.push(videoPath)
videoSnapLegend[`${videoPath}`] = []
frames.forEach((frame) => {
@ -265,27 +269,20 @@ module.exports = function(s,config,lang,app,io){
*/
app.get([
config.webPaths.apiPrefix+':auth/reports/:ke',
config.webPaths.apiPrefix+':auth/reports/:ke/:id',
config.webPaths.apiPrefix+':auth/reports/:ke/:id/:reportId',
config.webPaths.apiPrefix+':auth/reports/:ke/:reportId',
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params, async function(user){
const response = {ok: true}
const monitorId = req.params.id
const monitorId = req.query.id || '_USER'
const groupKey = req.params.ke
const reportId = req.params.reportId
const canDoAction = hasApiPermission(user,groupKey,monitorId)
if(canDoAction){
try{
const reports = await getReports(groupKey,monitorId,reportId)
response.reports = reports
}catch(err){
response.ok = false
response.err = err
}
}else{
try{
const reports = await getReports(groupKey,monitorId,reportId)
response.reports = reports
}catch(err){
response.ok = false
response.msg = lang['Not Authorized']
response.err = err
}
s.closeJsonResponse(res,response)
},res,req);

View File

@ -0,0 +1,172 @@
$(document).ready(function(){
var theTab = $('#tab-reportManagerForm')
var theForm = theTab.find('form')
var videoSelectContainer = $('#report-manager-video-select')
var selectedContainer = $('#report-manager-video-selected')
var monitorsList = theTab.find('.monitors_list')
var dateSelector = theTab.find('.date_selector')
var searchField = $('#report-manager-search-tag')
function getFormDetails(form){
var theObject = {}
form.find('[detail]').each(function(n,v){
var el = $(this)
var key = el.attr('detail')
var value = el.val()
theObject[key] = value
})
return theObject
}
function saveReport(){
var form = theForm.serializeObject()
var videos = getAllSelectedVideos()
var details = getFormDetails(theForm)
var postData = Object.assign({
videos,
details,
},form);
$.post(getApiPrefix('reports'),postData,function(data){
console.log('reports response',data)
})
}
function emailReport(){}
function uploadReport(){}
function createVideoCard(video,classOverride){
var monitorId = video.mid
var startTime = video.time
var endTime = video.end
var {
day,
month,
year,
} = getDayPartsFromTime(startTime)
var firstFrame = video.timelapseFrames && video.timelapseFrames[0] ? video.timelapseFrames[0] : {href:''}
console.log(firstFrame,video.timelapseFrames)
var eventMatrixHtml = ``
eventMatrixHtml += `<div class="video-day-slice" data-mid="${video.mid}" data-time="${video.time}" style="width:100%;position:relative">`
if(video.events && video.events.length > 0){
$.each(video.events,function(n,theEvent){
var leftPercent = getPercentOfTimePositionFromVideo(video,theEvent)
eventMatrixHtml += `<div class="video-time-needle video-time-needle-event" style="margin-left:${leftPercent}%"></div>`
})
}
eventMatrixHtml += `</div>`
eventMatrixHtml += `<div class="video-day-slice-spacer"></div>`
var html = `
<div class="video-row video-time-card-container ${classOverride ? classOverride : `col-md-12 col-lg-6 mb-3`} search-row">
<div data-ke="${video.ke}" data-mid="${video.mid}" data-time="${video.time}" class="video-time-card shadow-sm px-0 ${definitions.Theme.isDark ? 'bg-dark' : 'bg-light'}">
<div class="video-time-header">
<div class="d-flex flex-row vertical-center ${definitions.Theme.isDark ? 'text-white' : ''}">
<div class="flex-grow-1 p-3">
<b>${loadedMonitors[monitorId] ? loadedMonitors[monitorId].name : monitorId}</b>
<div class="${definitions.Theme.isDark ? 'text-white' : ''}">
<span class="video-time-label">${formattedTime(startTime)} to ${formattedTime(endTime)}</span>
</div>
</div>
<div class="text-right p-3" style="background:rgba(0,0,0,0.5)">
<div class="text-center" style="font-size:20pt;font-weight:bold">${day}</div>
<div>${month}, ${year}</div>
</div>
</div>
<div class="px-3 pb-3">
<a class="btn btn-sm btn-success play-video" title="${lang.Play}"><i class=" fa fa-play-circle"></i></a>
</div>
</div>
<div class="text-center video-card-playback-view" style="position:relative">
<img class="video-time-img" src="${firstFrame.href}">
</div>
<div class="video-time-strip card-footer p-0">
<div class="flex-row d-flex" style="height:30px">${eventMatrixHtml}</div>
</div>
</div>
</div>`
return html
}
function loadVideoCards(videos){
var dateRange = getSelectedTime(dateSelector)
var startDate = dateRange.startDate
var endDate = dateRange.endDate
var monitorId = monitorsList.val()
var searchQuery = searchField.val()
getVideos({
monitorId,
startDate,
endDate,
searchQuery,
archived: false,
},function(data){
var html = ''
var videos = data.videos
loadedReportVideos = {}
$.each(videos,function(n,video){
loadedReportVideos[`${video.ke}${video.mid}${video.time}`] = video;
html += createVideoCard(video)
})
videoSelectContainer.html(html)
})
}
function getAllSelectedVideos(){
var selected = []
videoSelectContainer.find('.video-time-card.selected').each(function(){
var el = $(this)
var ke = el.attr('data-ke')
var mid = el.attr('data-mid')
var time = el.attr('data-time')
var video = loadedReportVideos[`${ke}${mid}${time}`]
selected.push({
ke,
mid,
time: video.time,
filename: video.filename,
details: video.details,
frames: video.timelapseFrames.map(item => {
return {
ke: item.ke,
mid: item.mid,
time: item.time,
filename: item.filename,
}
}),
events: video.events,
})
})
return selected
}
function loadVideoIntoVideoCard(playButton){
var timeCard = playButton.parents('.video-time-card')
var playBackContainer = timeCard.find('.video-card-playback-view')
var groupKey = timeCard.attr('data-ke')
var monitorId = timeCard.attr('data-mid')
var time = timeCard.attr('data-time')
var video = loadedReportVideos[`${groupKey}${monitorId}${time}`]
playBackContainer.html(`<video controls autoplay src="${video.href}"></video>`)
}
addOnTabOpen('reportManagerForm', function () {
loadVideoCards()
})
addOnTabAway('reportManagerForm', function () {
})
loadDateRangePicker(dateSelector,{
onChange: function(start, end, label) {
loadVideoCards()
}
})
loadDateRangePicker(theForm.find('[name="incidentTime"]'),{
singleDatePicker: true,
})
drawMonitorListToSelector(monitorsList.find('optgroup'))
videoSelectContainer.on('click','.video-time-card',function(){
var el = $(this)
el.toggleClass('selected')
})
videoSelectContainer.on('click','.play-video',function(){
var el = $(this)
loadVideoIntoVideoCard(el)
})
theForm.submit(function(e){
e.preventDefault()
saveReport()
return false;
})
})

View File

@ -1,172 +1,44 @@
$(document).ready(function(){
var theTab = $('#tab-reportManagerForm')
var theForm = theTab.find('form')
var videoSelectContainer = $('#report-manager-video-select')
var selectedContainer = $('#report-manager-video-selected')
var monitorsList = theTab.find('.monitors_list')
var dateSelector = theTab.find('.date_selector')
var searchField = $('#report-manager-search-tag')
function getFormDetails(form){
var theObject = {}
form.find('[detail]').each(function(n,v){
var el = $(this)
var key = el.attr('detail')
var value = el.val()
theObject[key] = value
})
return theObject
}
function saveReport(){
var form = theForm.serializeObject()
var videos = getAllSelectedVideos()
var details = getFormDetails(theForm)
var postData = Object.assign({
videos,
details,
},form);
$.post(getApiPrefix('reports'),postData,function(data){
console.log('reports response',data)
})
}
function emailReport(){}
function uploadReport(){}
function createVideoCard(video,classOverride){
var monitorId = video.mid
var startTime = video.time
var endTime = video.end
var {
day,
month,
year,
} = getDayPartsFromTime(startTime)
var firstFrame = video.timelapseFrames && video.timelapseFrames[0] ? video.timelapseFrames[0] : {href:''}
console.log(firstFrame,video.timelapseFrames)
var eventMatrixHtml = ``
eventMatrixHtml += `<div class="video-day-slice" data-mid="${video.mid}" data-time="${video.time}" style="width:100%;position:relative">`
if(video.events && video.events.length > 0){
$.each(video.events,function(n,theEvent){
var leftPercent = getPercentOfTimePositionFromVideo(video,theEvent)
eventMatrixHtml += `<div class="video-time-needle video-time-needle-event" style="margin-left:${leftPercent}%"></div>`
var theTab = $('#tab-reportManager')
var theList = $('#report-manager-list')
function getReports(reportId){
return new Promise((resolve) => {
$.getJSON(`${getApiPrefix(`reports`)}${reportId ? `/${reportId}` : ''}`,function(response){
resolve(response.reports)
})
}
eventMatrixHtml += `</div>`
eventMatrixHtml += `<div class="video-day-slice-spacer"></div>`
var html = `
<div class="video-row video-time-card-container ${classOverride ? classOverride : `col-md-12 col-lg-6 mb-3`} search-row">
<div data-ke="${video.ke}" data-mid="${video.mid}" data-time="${video.time}" class="video-time-card shadow-sm px-0 ${definitions.Theme.isDark ? 'bg-dark' : 'bg-light'}">
<div class="video-time-header">
<div class="d-flex flex-row vertical-center ${definitions.Theme.isDark ? 'text-white' : ''}">
<div class="flex-grow-1 p-3">
<b>${loadedMonitors[monitorId] ? loadedMonitors[monitorId].name : monitorId}</b>
<div class="${definitions.Theme.isDark ? 'text-white' : ''}">
<span class="video-time-label">${formattedTime(startTime)} to ${formattedTime(endTime)}</span>
</div>
</div>
<div class="text-right p-3" style="background:rgba(0,0,0,0.5)">
<div class="text-center" style="font-size:20pt;font-weight:bold">${day}</div>
<div>${month}, ${year}</div>
</div>
</div>
<div class="px-3 pb-3">
<a class="btn btn-sm btn-success play-video" title="${lang.Play}"><i class=" fa fa-play-circle"></i></a>
})
}
async function drawReports(){
var html = ''
var reports = await getReports()
console.log(reports)
$.each(reports,function(n,report){
console.log(report)
html += `<div class="card bg-darker mt-2">
<div class="card-header">
${report.name}
</div>
<div class="card-body">
<div>
${report.name}
</div>
<small class="d-block">
<b>${lang['Submitted By']} :</b> ${report.details.submittedBy}
</small>
<small class="d-block">
<b>${lang['Location of Incident']} :</b> ${report.details.locationOfIncident}
</small>
</div>
<div class="text-center video-card-playback-view" style="position:relative">
<img class="video-time-img" src="${firstFrame.href}">
</div>
<div class="video-time-strip card-footer p-0">
<div class="flex-row d-flex" style="height:30px">${eventMatrixHtml}</div>
</div>
</div>
</div>`
return html
}
function loadVideoCards(videos){
var dateRange = getSelectedTime(dateSelector)
var startDate = dateRange.startDate
var endDate = dateRange.endDate
var monitorId = monitorsList.val()
var searchQuery = searchField.val()
getVideos({
monitorId,
startDate,
endDate,
searchQuery,
archived: false,
},function(data){
var html = ''
var videos = data.videos
loadedReportVideos = {}
$.each(videos,function(n,video){
loadedReportVideos[`${video.ke}${video.mid}${video.time}`] = video;
html += createVideoCard(video)
})
videoSelectContainer.html(html)
</div>`
})
theList.html(html)
}
function getAllSelectedVideos(){
var selected = []
videoSelectContainer.find('.video-time-card.selected').each(function(){
var el = $(this)
var ke = el.attr('data-ke')
var mid = el.attr('data-mid')
var time = el.attr('data-time')
var video = loadedReportVideos[`${ke}${mid}${time}`]
selected.push({
ke,
mid,
time: video.time,
filename: video.filename,
details: video.details,
frames: video.timelapseFrames.map(item => {
return {
ke: item.ke,
mid: item.mid,
time: item.time,
filename: item.filename,
}
}),
events: video.events,
})
})
return selected
}
function loadVideoIntoVideoCard(playButton){
var timeCard = playButton.parents('.video-time-card')
var playBackContainer = timeCard.find('.video-card-playback-view')
var groupKey = timeCard.attr('data-ke')
var monitorId = timeCard.attr('data-mid')
var time = timeCard.attr('data-time')
var video = loadedReportVideos[`${groupKey}${monitorId}${time}`]
playBackContainer.html(`<video controls autoplay src="${video.href}"></video>`)
}
addOnTabOpen('reportManagerForm', function () {
loadVideoCards()
addOnTabOpen('reportManager', function () {
drawReports()
})
addOnTabAway('reportManagerForm', function () {
addOnTabReopen('reportManager', function () {
drawReports()
})
loadDateRangePicker(dateSelector,{
onChange: function(start, end, label) {
loadVideoCards()
}
})
loadDateRangePicker(theForm.find('[name="incidentTime"]'),{
singleDatePicker: true,
})
drawMonitorListToSelector(monitorsList.find('optgroup'))
videoSelectContainer.on('click','.video-time-card',function(){
var el = $(this)
el.toggleClass('selected')
})
videoSelectContainer.on('click','.play-video',function(){
var el = $(this)
loadVideoIntoVideoCard(el)
})
theForm.submit(function(e){
e.preventDefault()
saveReport()
return false;
addOnTabAway('reportManager', function () {
})
})

View File

@ -7,7 +7,7 @@
%>
<!-- Report Manager (Main) -->
<main class="page-tab pt-3" id="tab-reportManager">
<form class="dark">
<div class="dark row">
<%
var pageName = 'Report Manager';
Object.keys(define[pageName].blocks).forEach(function(blockKey){
@ -15,7 +15,7 @@
drawBlock(pageLayout)
})
%>
</form>
</div>
<link rel="stylesheet" href="<%-window.libURL%>assets/css/bs5.reportManager.css" />
<script src="<%-window.libURL%>assets/js/bs5.reportManager.js"></script>
</main>
@ -33,4 +33,5 @@
include stickySubmitBar.ejs
%>
</form>
<script src="<%-window.libURL%>assets/js/bs5.reportManager.form.js"></script>
</main>