fleet-contractor/Site/AssetView/AssetsTimeline.aspx
2023-04-28 12:22:26 +08:00

543 lines
22 KiB
Plaintext

<%@ Page Title="" Language="C#" MasterPageFile="~/AssetView/AssetViewBase.master" AutoEventWireup="true" CodeFile="AssetsTimeline.aspx.cs" Inherits="AssetView_AssetsTimeline" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
<link href="<%=GetFileUrlWithVersion("../css/jquery.datetimepicker.css")%>" rel="stylesheet" />
<script src="<%=GetFileUrlWithVersion("../js/jquery.datetimepicker.full.js")%>"></script>
<link href="<%=Common.GenerateUrl("../css/tabcontrol.css") %>" rel="stylesheet" />
<script src="<%=GetFileUrlWithVersion("../js/controls.js")%>" type="text/javascript"></script>
<script src="<%=GetFileUrlWithVersion("../Maintenance/js/inputdatactr.js")%>" type="text/javascript"></script>
<style type="text/css">
html {
overflow-x: hidden;
}
.titlePane {
background-color: #444444;
color: #FFFFFF;
line-height: 24px;
padding-left: 6px;
border-radius: 5px 5px 0px 0px;
-webkit-border-radius: 5px 5px 0px 0px;
cursor: default;
}
.titleButton {
position: absolute;
top: 2px;
cursor: pointer;
}
.titleButton:before {
padding-right: 8px;
font-family: 'FontAwesome';
}
.titleButton.close {
right: 3px;
background-position: 0 0;
width: 12px;
height: 17px;
font-size: 15px;
}
.table-container {
margin: 4px 10px 0 26px;
}
.table-timeline {
width: 100%;
border-spacing: 0;
table-layout: fixed;
}
.table-timeline th {
width: 4.17%;
border-right: 1px solid white;
background: #444;
color: white;
font-weight: normal;
font-size: 13px;
height: 26px;
}
.table-timeline th,
.table-timeline td {
padding: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#tds-timeline td {
height: 30px;
position: relative;
}
#tds-timeline div {
height: 26px;
position: absolute;
background: #64965a;
top: 2px;
border-radius: 6px;
}
#tds-timeline div.no-start {
border-radius: 0 6px 6px 0;
}
#tds-timeline div.no-end {
border-radius: 6px 0 0 6px;
}
#tab_timeline {
overflow-y: auto;
}
</style>
<script type="text/javascript">
_network.root = '<%=Page.ResolveUrl("~/")%>';
var wids = [];
var grid;
var currentdate = "<%=CurrentDate %>";
function assetrequest(method, param, callback, error) {
_network.request("AssetView/SingleAssetView.aspx", -1, method, param, callback, error || function (e) {
console.log(e);
});
}
function fillWidths() {
var ths = $('#tr-header').children();
for (var i = 0; i < ths.length; i++) {
wids[i] = $(ths[i]).outerWidth();
}
}
$(function () {
fillWidths();
var resizeTimeline = function () {
fillWidths();
var trs = $('#tds-timeline').children('tr');
for (var n = 0; n < trs.length; n++) {
var ds = $(trs[n]).children('td').children();
for (var i = 0; i < ds.length; i++) {
var div = $(ds[i]);
var start = parseFloat(div.attr('start'));
var end = parseFloat(div.attr('end'));
var left = getOffset(start, wids);
var right = getOffset(end, wids);
var w = right - left - 1;
if (w < 1) { w = 1; }
div.css({
left: left,
width: w
});
}
}
};
$(window).resize(function () {
resizeTimeline();
var height = $(window).height() - 70;
$('#tab_timeline').css('height', height);
$('#tab_grid').css('height', height);
grid.resize();
});
$('#date-selector').datetimepicker({
timepicker: false,
format: 'm/d/Y',
scrollMonth: false,
scrollTime: false,
scrollInput: false,
}).val(new DateFormatter().formatDate(new Date(currentdate), 'm/d/Y'));
$('#tab_container').tab({
onclick: function (t, n) {
n();
var key = t.attr('data-href')
$('#' + key).css('height', $(window).height() - 70);
if (key === 'tab_grid') {
grid.resize();
} else {
resizeTimeline();
}
}
});
grid = new GridView('#tab_grid');
grid.columns = [
{
key: 'name',
caption: GetTextByKey('P_MA_ASSETNAME', 'Asset Name'),
width: 180
},
{
key: 'vin',
caption: GetTextByKey('P_MA_VIN', 'VIN/SN'),
width: 160
},
{
key: 'make',
caption: GetTextByKey('P_MA_MAKENAME', 'Make Name'),
width: 100
},
{
key: 'model',
caption: GetTextByKey('P_MA_MODELNAME', 'Model Name'),
width: 100
},
{ key: 'h0', caption: '12AM-1AM', width: 94, align: 'right' },
{ key: 'h1', caption: '1AM-2AM', width: 94, align: 'right' },
{ key: 'h2', caption: '2AM-3AM', width: 94, align: 'right' },
{ key: 'h3', caption: '3AM-4AM', width: 94, align: 'right' },
{ key: 'h4', caption: '4AM-5AM', width: 94, align: 'right' },
{ key: 'h5', caption: '5AM-6AM', width: 94, align: 'right' },
{ key: 'h6', caption: '6AM-7AM', width: 94, align: 'right' },
{ key: 'h7', caption: '7AM-8AM', width: 94, align: 'right' },
{ key: 'h8', caption: '8AM-9AM', width: 94, align: 'right' },
{ key: 'h9', caption: '9AM-10AM', width: 94, align: 'right' },
{ key: 'h10', caption: '10AM-11AM', width: 94, align: 'right' },
{ key: 'h11', caption: '11AM-12PM', width: 94, align: 'right' },
{ key: 'h12', caption: '12PM-1PM', width: 94, align: 'right' },
{ key: 'h13', caption: '1PM-2PM', width: 94, align: 'right' },
{ key: 'h14', caption: '2PM-3PM', width: 94, align: 'right' },
{ key: 'h15', caption: '3PM-4PM', width: 94, align: 'right' },
{ key: 'h16', caption: '4PM-5PM', width: 94, align: 'right' },
{ key: 'h17', caption: '5PM-6PM', width: 94, align: 'right' },
{ key: 'h18', caption: '6PM-7PM', width: 94, align: 'right' },
{ key: 'h19', caption: '7PM-8PM', width: 94, align: 'right' },
{ key: 'h20', caption: '8PM-9PM', width: 94, align: 'right' },
{ key: 'h21', caption: '9PM-10PM', width: 94, align: 'right' },
{ key: 'h22', caption: '10PM-11PM', width: 94, align: 'right' },
{ key: 'h23', caption: '11PM-12AM', width: 94, align: 'right' }
];
grid.canMultiSelect = false;
grid.init();
});
var pcid;
var loading;
function getAssetTimeline(cid, date) {
if (loading) {
return;
}
pcid = cid || '';
var assets = window.parent.allAssets;
if (assets == null) {
return;
}
var selecteds = assets.filter(function (a) { return a.State.Selected }).sort(function (a, b) {
if (a.DisplayName == b.DisplayName) {
return 0;
}
return a.DisplayName > b.DisplayName ? 1 : -1;
});
var parent = $('#tds-timeline').empty();
var idsparent = $('#asset-ids').empty();
loading = true;
$('.maskbg').fadeIn(100);
grid.setData([]);
doGetAssetTimeline(selecteds, 0, parent, idsparent, date);
}
function doGetAssetTimeline(selecteds, start, parent, idsparent, date) {
var endIndex = start + 10000;
var ids = selecteds.slice(start, endIndex).map(function (a) { return a.ID });
if (ids.length <= 0) {
var source = grid.source;
var total = {
name: GetTextByKey('P_MA_TOTALCOLON', 'Total:') + ' ' + source.length,
model: $('<span></span>').css('float', 'right').text(GetTextByKey('P_MA_TOTALRUNTIMECOLON', 'Total Runtime:'))[0].outerHTML
};
for (var h = 0; h < 24; h++) {
var seconds = source.reduce(function (current, s) {
var n = s.Values['s' + h];
return isNaN(n) ? current : current + n;
}, 0);
if (seconds > 0) {
var run =
String(Math.floor(seconds / 3600)).padStart(2, '0') + ':' +
String(Math.floor((seconds % 3600) / 60)).padStart(2, '0') + ':' +
String(Math.round(seconds % 60)).padStart(2, '0');
total['h' + h] = run;
}
}
grid.total = total;
grid.init();
loading = false;
$('.maskbg').fadeOut(100);
return;
}
var params = [pcid, ids, date];
assetrequest('GetAssetsOnOffTimeline', params.join(String.fromCharCode(170)), function (data) {
var source = [];
for (var n = 0; n < data.length; n++) {
var item = $('<td colspan="24"></td>');
var onoff = data[n];
var a = selecteds.filter(function (a) { return a.ID == onoff.AssetId })[0];
var name = (a && a.DisplayName) || onoff.AssetId;
var it = {
name: name,
vin: a.VIN,
make: a.Make,
model: a.Model
};
var idtd = $('<td style="height: 30px"></td>').text(name).attr('title', name);
idsparent.append($('<tr></tr>').append(idtd));
for (var i = 0; i < onoff.Items.length; i++) {
var div = $('<div></div>');
var startSeconds = onoff.Items[i].Start;
var endSeconds = onoff.Items[i].End;
var start = startSeconds / 3600;
var end = endSeconds / 3600;
if (endSeconds > startSeconds) {
var startHour = Math.floor(start);
var endHour = Math.ceil(end);
for (var h = startHour; h < endHour; h++) {
var hourStartSeconds = h * 3600;
var hourEndSeconds = (h + 1) * 3600;
if (startSeconds > hourStartSeconds) {
hourStartSeconds = startSeconds;
}
if (hourEndSeconds - endSeconds >= 1) {
hourEndSeconds = endSeconds;
}
var totalSeconds = hourEndSeconds - hourStartSeconds;
if (it['s' + h] == null) {
it['s' + h] = totalSeconds;
} else {
it['s' + h] += totalSeconds;
}
}
}
var title = [];
if (onoff.Items[i].HasOn) {
title.push('On: ' + hoursToString(startSeconds));
} else {
div.addClass('no-start');
}
if (onoff.Items[i].HasOff) {
title.push('Off: ' + hoursToString(endSeconds));
} else {
div.addClass('no-end');
}
div.attr({
start: start,
end: end,
title: title.join('\n')
});
var left = getOffset(start, wids);
var right = getOffset(end, wids);
var w = right - left - 1;
if (w < 1) { w = 1; }
div.css({
left: left,
width: w
});
item.append(div);
}
for (var h = 0; h < 24; h++) {
var totalSeconds = it['s' + h];
if (totalSeconds == null) {
continue;
}
var text;
if (totalSeconds >= 3600) {
text = '01:00:00';
} else {
text =
'00:' +
String(Math.floor(totalSeconds / 60)).padStart(2, '0') + ':' +
String(Math.round(totalSeconds % 60)).padStart(2, '0');
}
it['h' + h] = text;
}
source.push({ Values: it });
parent.append($('<tr></tr>').append(item));
}
source = grid.source.concat(source);
grid.setData(source);
setTimeout(function () {
doGetAssetTimeline(selecteds, endIndex, parent, idsparent, date);
}, 0);
});
}
function hoursToString(seconds) {
var s = Math.floor(seconds % 60);
seconds = Math.floor(seconds / 60);
var m = Math.round(seconds % 60);
var h = Math.floor(seconds / 60);
return (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s;
}
function OnRefresh(cid, dt) {
//getAssetTimeline(cid, dt || $('#date-selector').val());
pcid = cid;
$('#tds-timeline').empty();
$('#asset-ids').empty();
}
function OnClose() {
window.parent.closePopupView();
}
function OnDateChanged() {
var date = $('#date-selector').val();
if (date == "") {
showAlert(GetTextByKey("P_WO_XXXXXX", "The date is required."), alerttitle);
return false;
}
if (!checkDate(date)) {
showAlert(GetTextByKey("P_WO_XXXXXX", "The date is incorrect."), alerttitle);
return false;
}
getAssetTimeline(pcid, date);
}
function getOffset(pos, wids) {
var n = Math.floor(pos);
var p = 0;
for (var i = 0; i < n; i++) {
p += wids[i];
}
p += wids[n] * (pos - n);
return p;
}
function OnExport() {
var date = $('#date-selector').val();
if (date == "") {
showAlert(GetTextByKey("P_WO_XXXXXX", "The date is required."), alerttitle);
return false;
}
if (!checkDate(date)) {
showAlert(GetTextByKey("P_WO_XXXXXX", "The date is incorrect."), alerttitle);
return false;
}
var assets = window.parent.allAssets;
if (assets == null) {
return;
}
var selecteds = assets.filter(function (a) { return a.State.Selected }).sort(function (a, b) {
if (a.DisplayName == b.DisplayName) {
return 0;
}
return a.DisplayName > b.DisplayName ? 1 : -1;
});
var ids = selecteds.map(function (a) { return a.ID });
var params = ["timeline", pcid, JSON.stringify(ids), date];
var data = new FormData();
data.append('type', 'set');
data.append('ClientData', JSON.stringify(params));
$.ajax({
url: "../ExportToFile.aspx",
type: 'POST',
dataType: 'json',
processData: false,
contentType: false,
data: data,
success: function (data) {
if (data && data != "")
window.open("../ExportToFile.aspx?type=exp&key=" + data);
},
error: function (err) {
}
});
}
function tabchange(index) {
if (index == 0) {
$("#btnexporttimelineexcel").hide();
}
else if (index == 1) {
if (!canExport) {
$("#btnexporttimelineexcel").hide();
}
else {
$("#btnexporttimelineexcel").show();
}
}
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<div class="titlePane">
<span>&nbsp;</span>
<span class="iconclose titleButton close" onclick="OnClose();" style="z-index: 600"></span>
</div>
<div id="tab_container" style="position: relative">
<ul class="tab_header" style="padding-top: 8px">
<li data-href="tab_timeline" class="selected" onclick="tabchange(0)" data-lgid="P_MV_TIMELINE">Timeline</li>
<li data-href="tab_grid" onclick="tabchange(1)" data-lgid="P_GRID_TITLE">Utilization by Hour</li>
<li style="clear: both"></li>
</ul>
<div id="tab_timeline" data-page="tab_timeline">
<div class="table-container">
<div style="width: 100px; float: left">
<table class="table-timeline">
<thead>
<tr>
<th>&nbsp;</th>
</tr>
</thead>
<tbody id="asset-ids">
<%--<tr><td style="height: 30px" data-lgid="P_MV_ONOFFEVENTS">On/Off Events</td></tr>--%>
</tbody>
</table>
</div>
<div style="margin-left: 100px">
<table class="table-timeline">
<thead>
<tr id="tr-header">
<th>0:00</th>
<th>1:00</th>
<th>2:00</th>
<th>3:00</th>
<th>4:00</th>
<th>5:00</th>
<th>6:00</th>
<th>7:00</th>
<th>8:00</th>
<th>9:00</th>
<th>10:00</th>
<th>11:00</th>
<th>12:00</th>
<th>13:00</th>
<th>14:00</th>
<th>15:00</th>
<th>16:00</th>
<th>17:00</th>
<th>18:00</th>
<th>19:00</th>
<th>20:00</th>
<th>21:00</th>
<th>22:00</th>
<th>23:00</th>
</tr>
</thead>
<tbody id="tds-timeline"></tbody>
</table>
</div>
</div>
</div>
<div id="tab_grid" data-page="tab_grid" style="box-sizing: border-box"></div>
</div>
<div style="position: absolute; right: 6px; top: 30px">
<input type="text" id="date-selector" style="height: 26px; box-sizing: border-box" autocomplete="off" />
<span class="sbutton iconrefresh" onclick="OnDateChanged();" data-lgid="P_APICRE_REFRESH">Refresh</span>
<span id="btnexporttimelineexcel" class="sbutton iconexport" onclick="OnExport();" style="display: none;" data-lgid="P_MR_EXPORTTOEXCEL">Export to Excel</span>
</div>
<div id="mask_bg" class="maskbg" style="display: none; z-index: 550;">
<div class="loading c-spin"></div>
</div>
</asp:Content>