|
|
|
@ -45,16 +45,20 @@ var dashboardTmpl = template.Must(template.New("dashboard").Parse(`<!DOCTYPE htm
|
|
|
|
<div class="rvt-m-bottom-lg">
|
|
|
|
<div class="rvt-m-bottom-lg">
|
|
|
|
<button class="rvt-button rvt-button--secondary" type="button" id="download-csv">Download CSV Report</button>
|
|
|
|
<button class="rvt-button rvt-button--secondary" type="button" id="download-csv">Download CSV Report</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="rvt-m-bottom-md">
|
|
|
|
|
|
|
|
<label class="rvt-label" for="table-search">Search</label>
|
|
|
|
|
|
|
|
<input class="rvt-input" type="search" id="table-search" placeholder="Filter results...">
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<div style="overflow-x:auto;">
|
|
|
|
<div style="overflow-x:auto;">
|
|
|
|
<table class="rvt-table rvt-table--cells" id="report-table">
|
|
|
|
<table class="rvt-table rvt-table--cells" id="report-table">
|
|
|
|
<thead>
|
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<tr>
|
|
|
|
<th scope="col">Date Submitted</th>
|
|
|
|
<th scope="col" data-col="0" style="cursor:pointer;white-space:nowrap;">Date Submitted <span class="sort-ind">↕</span></th>
|
|
|
|
<th scope="col">Name</th>
|
|
|
|
<th scope="col" data-col="1" style="cursor:pointer;white-space:nowrap;">Name <span class="sort-ind">↕</span></th>
|
|
|
|
<th scope="col">Title</th>
|
|
|
|
<th scope="col">Title</th>
|
|
|
|
<th scope="col">Description</th>
|
|
|
|
<th scope="col">Description</th>
|
|
|
|
<th scope="col">Hyperlink</th>
|
|
|
|
<th scope="col">Hyperlink</th>
|
|
|
|
<th scope="col">Type</th>
|
|
|
|
<th scope="col" data-col="5" style="cursor:pointer;white-space:nowrap;">Type <span class="sort-ind">↕</span></th>
|
|
|
|
</tr>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<tbody>
|
|
|
|
@ -76,52 +80,96 @@ var dashboardTmpl = template.Must(template.New("dashboard").Parse(`<!DOCTYPE htm
|
|
|
|
{{end}}
|
|
|
|
{{end}}
|
|
|
|
</main>
|
|
|
|
</main>
|
|
|
|
<script>
|
|
|
|
<script>
|
|
|
|
var dlBtn = document.getElementById('download-csv');
|
|
|
|
(function() {
|
|
|
|
if (dlBtn) {
|
|
|
|
var table = document.getElementById('report-table');
|
|
|
|
dlBtn.addEventListener('click', function() {
|
|
|
|
var allRows = table ? Array.prototype.slice.call(table.querySelectorAll('tbody tr')) : [];
|
|
|
|
var now = new Date();
|
|
|
|
var sortState = {col: -1, dir: 1};
|
|
|
|
var p = function(n) { return n < 10 ? '0' + n : '' + n; };
|
|
|
|
|
|
|
|
var stamp = '' + now.getFullYear() + p(now.getMonth()+1) + p(now.getDate()) + p(now.getHours()) + p(now.getMinutes()) + p(now.getSeconds());
|
|
|
|
|
|
|
|
var filename = 'Faculty_Activity_Report-' + stamp + '.csv';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function esc(val) {
|
|
|
|
function getCellText(row, col) {
|
|
|
|
val = val || '';
|
|
|
|
var cells = row.querySelectorAll('td');
|
|
|
|
if (val.indexOf('|') !== -1 || val.indexOf('"') !== -1 || val.indexOf('\n') !== -1) {
|
|
|
|
return cells[col] ? cells[col].textContent.trim() : '';
|
|
|
|
return '"' + val.replace(/"/g, '""') + '"';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
function apply() {
|
|
|
|
|
|
|
|
var term = (document.getElementById('table-search').value || '').toLowerCase();
|
|
|
|
|
|
|
|
var rows = allRows.filter(function(row) {
|
|
|
|
|
|
|
|
if (!term) return true;
|
|
|
|
|
|
|
|
return Array.prototype.some.call(row.querySelectorAll('td'), function(cell) {
|
|
|
|
|
|
|
|
return cell.textContent.toLowerCase().indexOf(term) !== -1;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
if (sortState.col >= 0) {
|
|
|
|
|
|
|
|
rows.sort(function(a, b) {
|
|
|
|
|
|
|
|
var av = getCellText(a, sortState.col).toLowerCase();
|
|
|
|
|
|
|
|
var bv = getCellText(b, sortState.col).toLowerCase();
|
|
|
|
|
|
|
|
return av < bv ? -sortState.dir : av > bv ? sortState.dir : 0;
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var tbody = table.querySelector('tbody');
|
|
|
|
|
|
|
|
while (tbody.firstChild) tbody.removeChild(tbody.firstChild);
|
|
|
|
|
|
|
|
rows.forEach(function(r) { tbody.appendChild(r); });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var lines = ['sep=|'];
|
|
|
|
var searchInput = document.getElementById('table-search');
|
|
|
|
lines.push(['Date Submitted', 'Name', 'Title', 'Description', 'Hyperlink', 'Type'].map(esc).join('|'));
|
|
|
|
if (searchInput) searchInput.addEventListener('input', apply);
|
|
|
|
|
|
|
|
|
|
|
|
var rows = document.querySelectorAll('#report-table tbody tr');
|
|
|
|
if (table) {
|
|
|
|
rows.forEach(function(row) {
|
|
|
|
Array.prototype.forEach.call(table.querySelectorAll('th[data-col]'), function(th) {
|
|
|
|
var cells = row.querySelectorAll('td');
|
|
|
|
th.addEventListener('click', function() {
|
|
|
|
var fields = [];
|
|
|
|
var col = parseInt(th.getAttribute('data-col'), 10);
|
|
|
|
cells.forEach(function(cell, i) {
|
|
|
|
sortState.dir = sortState.col === col ? sortState.dir * -1 : 1;
|
|
|
|
if (i === 4) {
|
|
|
|
sortState.col = col;
|
|
|
|
var a = cell.querySelector('a');
|
|
|
|
Array.prototype.forEach.call(table.querySelectorAll('.sort-ind'), function(ind) { ind.textContent = '⇕'; });
|
|
|
|
fields.push(esc(a ? a.href : ''));
|
|
|
|
th.querySelector('.sort-ind').textContent = sortState.dir === 1 ? '↑' : '↓';
|
|
|
|
} else {
|
|
|
|
apply();
|
|
|
|
fields.push(esc(cell.textContent.trim()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
lines.push(fields.join('|'));
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var csv = lines.join('\r\n');
|
|
|
|
var dlBtn = document.getElementById('download-csv');
|
|
|
|
var blob = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
|
|
|
|
if (dlBtn) {
|
|
|
|
var url = URL.createObjectURL(blob);
|
|
|
|
dlBtn.addEventListener('click', function() {
|
|
|
|
var a = document.createElement('a');
|
|
|
|
var now = new Date();
|
|
|
|
a.href = url;
|
|
|
|
var p = function(n) { return n < 10 ? '0' + n : '' + n; };
|
|
|
|
a.download = filename;
|
|
|
|
var stamp = '' + now.getFullYear() + p(now.getMonth()+1) + p(now.getDate()) + p(now.getHours()) + p(now.getMinutes()) + p(now.getSeconds());
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
|
|
|
a.click();
|
|
|
|
function esc(val) {
|
|
|
|
document.body.removeChild(a);
|
|
|
|
val = val || '';
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
if (val.indexOf('|') !== -1 || val.indexOf('"') !== -1 || val.indexOf('\n') !== -1) {
|
|
|
|
});
|
|
|
|
return '"' + val.replace(/"/g, '""') + '"';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var lines = ['sep=|'];
|
|
|
|
|
|
|
|
lines.push(['Date Submitted', 'Name', 'Title', 'Description', 'Hyperlink', 'Type'].map(esc).join('|'));
|
|
|
|
|
|
|
|
Array.prototype.forEach.call(table.querySelectorAll('tbody tr'), function(row) {
|
|
|
|
|
|
|
|
var cells = row.querySelectorAll('td');
|
|
|
|
|
|
|
|
var fields = [];
|
|
|
|
|
|
|
|
Array.prototype.forEach.call(cells, function(cell, i) {
|
|
|
|
|
|
|
|
if (i === 4) {
|
|
|
|
|
|
|
|
var a = cell.querySelector('a');
|
|
|
|
|
|
|
|
fields.push(esc(a ? a.href : ''));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
fields.push(esc(cell.textContent.trim()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
lines.push(fields.join('|'));
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var csv = lines.join('\r\n');
|
|
|
|
|
|
|
|
var blob = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
|
|
|
|
|
|
|
|
var url = URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
var a = document.createElement('a');
|
|
|
|
|
|
|
|
a.href = url;
|
|
|
|
|
|
|
|
a.download = 'Faculty_Activity_Report-' + stamp + '.csv';
|
|
|
|
|
|
|
|
document.body.appendChild(a);
|
|
|
|
|
|
|
|
a.click();
|
|
|
|
|
|
|
|
document.body.removeChild(a);
|
|
|
|
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})();
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</body>
|
|
|
|
</html>`))
|
|
|
|
</html>`))
|
|
|
|
|