WEBUI JS: updated status tab to the dynamic behaviour

This commit is contained in:
Jaroslav Kysela 2014-09-04 14:36:41 +02:00
parent 45667faa13
commit 44bbfd4940
2 changed files with 475 additions and 385 deletions

View file

@ -4,10 +4,8 @@
tvheadend.service_mapper_status_panel = null;
tvheadend.service_mapper_status = function()
tvheadend.service_mapper_status = function(panel, index)
{
var panel;
/* Fields */
var ok = new Ext.form.Label({
fieldLabel: 'Mapped',
@ -31,7 +29,7 @@ tvheadend.service_mapper_status = function()
});
/* Panel */
panel = new Ext.FormPanel({
var mpanel = new Ext.FormPanel({
method: 'get',
title: 'Service Mapper',
frame: true,
@ -72,9 +70,9 @@ tvheadend.service_mapper_status = function()
}
});
tvheadend.service_mapper_status_panel = panel;
return panel;
};
tvheadend.service_mapper_status_panel = mpanel;
tvheadend.paneladd(panel, mpanel, index);
}
/*
* Start mapping
@ -182,4 +180,4 @@ tvheadend.service_mapper = function(t, e, store, select)
});
win.show();
};
}

View file

@ -1,44 +1,19 @@
/**
*
*/
tvheadend.status_subs = function() {
tvheadend.subsStore = new Ext.data.JsonStore({
root: 'entries',
totalProperty: 'totalCount',
fields: [
{ name: 'id' },
{ name: 'hostname' },
{ name: 'username' },
{ name: 'title' },
{ name: 'channel' },
{ name: 'service' },
{ name: 'state' },
{ name: 'errors' },
{ name: 'in' },
{ name: 'out' },
{
name: 'start',
type: 'date',
dateFormat: 'U' /* unix time */
}
],
url: 'api/status/subscriptions',
autoLoad: true,
id: 'id'
});
tvheadend.comet.on('subscriptions', function(m) {
tvheadend.status_subs = function(panel, index)
{
var subs = null;
var store = null;
function update(m) {
if (m.reload != null)
tvheadend.subsStore.reload();
store.reload();
if (m.updateEntry != null) {
r = tvheadend.subsStore.getById(m.id);
r = store.getById(m.id);
if (typeof r === 'undefined') {
tvheadend.subsStore.reload();
store.reload();
return;
}
@ -49,379 +24,495 @@ tvheadend.status_subs = function() {
r.data.in = m.in;
r.data.out = m.out;
tvheadend.subsStore.afterEdit(r);
tvheadend.subsStore.fireEvent('updated', tvheadend.subsStore, r,
Ext.data.Record.COMMIT);
store.afterEdit(r);
store.fireEvent('updated', store, r, Ext.data.Record.COMMIT);
}
});
function renderDate(value) {
var dt = new Date(value);
return dt.format('D j M H:i');
}
function renderBw(value, item, store) {
var txt = parseInt(value / 125);
var href = 'javascript:tvheadend.subscription_bw_monitor(' + store.id + ');';
return '<a href="' + href + '">' + txt + '</a>';
function builder() {
if (subs)
return;
store = new Ext.data.JsonStore({
root: 'entries',
totalProperty: 'totalCount',
fields: [
{ name: 'id' },
{ name: 'hostname' },
{ name: 'username' },
{ name: 'title' },
{ name: 'channel' },
{ name: 'service' },
{ name: 'state' },
{ name: 'errors' },
{ name: 'in' },
{ name: 'out' },
{
name: 'start',
type: 'date',
dateFormat: 'U' /* unix time */
}
],
url: 'api/status/subscriptions',
autoLoad: true,
id: 'id'
});
tvheadend.subsStore = store;
tvheadend.comet.on('subscriptions', update);
function renderBw(value, item, record) {
var txt = parseInt(value / 125);
var href = 'javascript:tvheadend.subscription_bw_monitor(' + record.id + ');';
return '<a href="' + href + '">' + txt + '</a>';
}
var subsCm = new Ext.grid.ColumnModel([
{
width: 50,
id: 'hostname',
header: "Hostname",
dataIndex: 'hostname'
},
{
width: 50,
id: 'username',
header: "Username",
dataIndex: 'username'
},
{
width: 80,
id: 'title',
header: "Title",
dataIndex: 'title'
},
{
width: 50,
id: 'channel',
header: "Channel",
dataIndex: 'channel'
},
{
width: 200,
id: 'service',
header: "Service",
dataIndex: 'service'
},
{
width: 50,
id: 'start',
header: "Start",
dataIndex: 'start',
renderer: function(v) {
var dt = new Date(v);
return dt.format('D j M H:i');
}
},
{
width: 50,
id: 'state',
header: "State",
dataIndex: 'state'
},
{
width: 50,
id: 'errors',
header: "Errors",
dataIndex: 'errors'
},
{
width: 50,
id: 'in',
header: "Input (kb/s)",
dataIndex: 'in',
renderer: renderBw,
},
{
width: 50,
id: 'out',
header: "Output (kb/s)",
dataIndex: 'out',
renderer: renderBw
}
]);
subs = new Ext.grid.GridPanel({
border: false,
loadMask: true,
stripeRows: true,
disableSelection: true,
store: store,
cm: subsCm,
flex: 1,
viewConfig: {
forceFit: true
}
});
dpanel.add(subs);
dpanel.doLayout(false, true);
}
function destroyer() {
if (subs === null || !tvheadend.dynamic)
return;
dpanel.removeAll()
tvheadend.subsStore = null;
store.destroy();
store = null;
subs = null;
}
var subsCm = new Ext.grid.ColumnModel([
{
width: 50,
id: 'hostname',
header: "Hostname",
dataIndex: 'hostname'
},
{
width: 50,
id: 'username',
header: "Username",
dataIndex: 'username'
},
{
width: 80,
id: 'title',
header: "Title",
dataIndex: 'title'
},
{
width: 50,
id: 'channel',
header: "Channel",
dataIndex: 'channel'
},
{
width: 200,
id: 'service',
header: "Service",
dataIndex: 'service'
},
{
width: 50,
id: 'start',
header: "Start",
dataIndex: 'start',
renderer: renderDate
},
{
width: 50,
id: 'state',
header: "State",
dataIndex: 'state'
},
{
width: 50,
id: 'errors',
header: "Errors",
dataIndex: 'errors'
},
{
width: 50,
id: 'in',
header: "Input (kb/s)",
dataIndex: 'in',
renderer: renderBw
},
{
width: 50,
id: 'out',
header: "Output (kb/s)",
dataIndex: 'out',
renderer: renderBw
}
]);
var subs = new Ext.grid.GridPanel({
var dpanel = new Ext.Panel({
border: false,
loadMask: true,
stripeRows: true,
disableSelection: true,
header: false,
layout: 'fit',
title: 'Subscriptions',
iconCls: 'eye',
store: tvheadend.subsStore,
cm: subsCm,
flex: 1,
viewConfig: {
forceFit: true
}
iconCls: 'eye'
});
return subs;
tvheadend.paneladd(panel, dpanel, index);
tvheadend.panelreg(panel, dpanel, builder, destroyer);
};
/**
* Streams
*/
tvheadend.status_streams = function() {
tvheadend.status_streams = function(panel, index)
{
var grid = null;
var store = null;
tvheadend.streamStatusStore = new Ext.data.JsonStore({
root: 'entries',
totalProperty: 'totalCount',
fields: [
{ name: 'uuid' },
{ name: 'input' },
{ name: 'username' },
{ name: 'stream' },
{ name: 'subs' },
{ name: 'weight' },
{ name: 'signal' },
{ name: 'ber' },
{ name: 'unc' },
{ name: 'snr' },
{ name: 'bps' },
{ name: 'cc' },
{ name: 'te' },
{ name: 'signal_scale' },
{ name: 'snr_scale' },
{ name: 'ec_bit' },
{ name: 'tc_bit' },
{ name: 'ec_block' },
{ name: 'tc_block' }
],
url: 'api/status/inputs',
autoLoad: true,
id: 'uuid'
});
function update(m) {
if (m.reload != null) {
store.reload();
return;
}
if (m.update == null)
return;
var r = store.getById(m.uuid);
if (!r) {
store.reload();
return;
}
r.data.subs = m.subs;
r.data.weight = m.weight;
r.data.signal = m.signal;
r.data.ber = m.ber;
r.data.unc = m.unc;
r.data.snr = m.snr;
r.data.bps = m.bps;
r.data.cc = m.cc;
r.data.te = m.te;
r.data.signal_scale = m.signal_scale;
r.data.snr_scale = m.snr_scale;
r.data.ec_bit = m.ec_bit;
r.data.tc_bit = m.tc_bit;
r.data.ec_block = m.ec_block;
r.data.tc_block = m.tc_block;
function renderBw(value, item, store) {
var txt = parseInt(value / 1024);
var href = "javascript:tvheadend.stream_bw_monitor('" + store.id + "');";
return '<a href="' + href + '">' + txt + '</a>';
store.afterEdit(r);
store.fireEvent('updated', store, Ext.data.Record.COMMIT);
}
function renderBer(value, item, store) {
if (store.data.tc_bit == 0)
return value; // fallback (driver/vendor dependent ber)
function builder() {
if (grid)
return;
// ber = error_bit_count / total_bit_count
var ber = store.data.ec_bit / store.data.tc_bit;
return ber;
store = new Ext.data.JsonStore({
root: 'entries',
totalProperty: 'totalCount',
fields: [
{ name: 'uuid' },
{ name: 'input' },
{ name: 'username' },
{ name: 'stream' },
{ name: 'subs' },
{ name: 'weight' },
{ name: 'signal' },
{ name: 'ber' },
{ name: 'unc' },
{ name: 'snr' },
{ name: 'bps' },
{ name: 'cc' },
{ name: 'te' },
{ name: 'signal_scale' },
{ name: 'snr_scale' },
{ name: 'ec_bit' },
{ name: 'tc_bit' },
{ name: 'ec_block' },
{ name: 'tc_block' }
],
url: 'api/status/inputs',
autoLoad: true,
id: 'uuid'
});
tvheadend.streamStatusStore = store;
tvheadend.comet.on('input_status', update);
function renderBw(value, item, record) {
var txt = parseInt(value / 1024);
var href = "javascript:tvheadend.stream_bw_monitor('" + record.id + "');";
return '<a href="' + href + '">' + txt + '</a>';
}
function renderBer(value, item, store) {
if (store.data.tc_bit == 0)
return value; // fallback (driver/vendor dependent ber)
// ber = error_bit_count / total_bit_count
var ber = store.data.ec_bit / store.data.tc_bit;
return ber;
}
function renderPer(value, item, store) {
if (value == 0) // value: total_block_count
return '<span class="tvh-grid-unset">Unknown</span>';
// per = error_block_count / total_block_count
var per = store.data.ec_block / value;
return per;
}
var cm = new Ext.grid.ColumnModel([
{
width: 120,
header: "Input",
dataIndex: 'input'
},
{
width: 100,
header: "Stream",
dataIndex: 'stream'
},
{
width: 50,
header: "Subs #",
dataIndex: 'subs'
},
{
width: 50,
header: "Weight",
dataIndex: 'weight'
},
{
width: 50,
header: "Bandwidth (kb/s)",
dataIndex: 'bps',
renderer: renderBw
},
{
width: 50,
header: "BER",
dataIndex: 'ber',
renderer: renderBer
},
{
width: 50,
header: "PER",
dataIndex: 'tc_block',
renderer: renderPer
},
{
width: 50,
header: "Uncorrected Blocks",
dataIndex: 'unc'
},
{
width: 50,
header: "Transport Errors",
dataIndex: 'te'
},
{
width: 50,
header: "Continuity Errors",
dataIndex: 'cc'
}
]);
cm.config.push(new Ext.ux.grid.ProgressColumn({
header: "SNR",
dataIndex: 'snr',
width: 85,
colored: true,
ceiling: 65535,
tvh_renderer: function(v, p, record) {
var scale = record.get('snr_scale');
if (scale == 1)
return v;
if (scale == 2 && v > 0) {
var snr = v * 0.0001;
return snr.toFixed(1) + " dB";
}
return '<span class="tvh-grid-unset">Unknown</span>';
},
destroy: function() {
}
}));
cm.config.push(new Ext.ux.grid.ProgressColumn({
header: "Signal Strength",
dataIndex: 'signal',
width: 85,
colored: true,
ceiling: 65535,
tvh_renderer: function(v, p, record) {
var scale = record.get('snr_scale');
if (scale == 1)
return v;
if (scale == 2 && v > 0) {
var snr = v * 0.0001;
return snr.toFixed(1) + " dBm";
}
return '<span class="tvh-grid-unset">Unknown</span>';
},
destroy: function() {
}
}));
grid = new Ext.grid.GridPanel({
border: false,
loadMask: true,
stripeRows: true,
disableSelection: true,
store: store,
cm: cm,
flex: 1,
viewConfig: {
forceFit: true
}
});
dpanel.add(grid);
dpanel.doLayout(false, true);
}
function renderPer(value, item, store) {
if (value == 0) // value: total_block_count
return '<span class="tvh-grid-unset">Unknown</span>';
// per = error_block_count / total_block_count
var per = store.data.ec_block / value;
return per;
function destroyer() {
if (grid === null || !tvheadend.dynamic)
return;
dpanel.removeAll()
tvheadend.streamStatusStore = null;
store.destroy();
store = null;
grid = null;
}
var cm = new Ext.grid.ColumnModel([
{
width: 120,
header: "Input",
dataIndex: 'input'
},
{
width: 100,
header: "Stream",
dataIndex: 'stream'
},
{
width: 50,
header: "Subs #",
dataIndex: 'subs'
},
{
width: 50,
header: "Weight",
dataIndex: 'weight'
},
{
width: 50,
header: "Bandwidth (kb/s)",
dataIndex: 'bps',
renderer: renderBw
},
{
width: 50,
header: "BER",
dataIndex: 'ber',
renderer: renderBer
},
{
width: 50,
header: "PER",
dataIndex: 'tc_block',
renderer: renderPer
},
{
width: 50,
header: "Uncorrected Blocks",
dataIndex: 'unc'
},
{
width: 50,
header: "Transport Errors",
dataIndex: 'te'
},
{
width: 50,
header: "Continuity Errors",
dataIndex: 'cc'
}
]);
cm.config.push(new Ext.ux.grid.ProgressColumn({
header: "SNR",
dataIndex: 'snr',
width: 85,
colored: true,
ceiling: 65535,
tvh_renderer: function(v, p, record) {
var scale = record.get('snr_scale');
if (scale == 1)
return v;
if (scale == 2 && v > 0) {
var snr = v * 0.0001;
return snr.toFixed(1) + " dB";
}
return '<span class="tvh-grid-unset">Unknown</span>';
}
}));
cm.config.push(new Ext.ux.grid.ProgressColumn({
header: "Signal Strength",
dataIndex: 'signal',
width: 85,
colored: true,
ceiling: 65535,
tvh_renderer: function(v, p, record) {
var scale = record.get('snr_scale');
if (scale == 1)
return v;
if (scale == 2 && v > 0) {
var snr = v * 0.0001;
return snr.toFixed(1) + " dBm";
}
return '<span class="tvh-grid-unset">Unknown</span>';
}
}));
tvheadend.comet.on('input_status', function(m) {
if (m.reload != null)
tvheadend.streamStatusStore.reload();
if (m.update != null) {
var r = tvheadend.streamStatusStore.getById(m.uuid);
if (r) {
r.data.subs = m.subs;
r.data.weight = m.weight;
r.data.signal = m.signal;
r.data.ber = m.ber;
r.data.unc = m.unc;
r.data.snr = m.snr;
r.data.bps = m.bps;
r.data.cc = m.cc;
r.data.te = m.te;
r.data.signal_scale = m.signal_scale;
r.data.snr_scale = m.snr_scale;
r.data.ec_bit = m.ec_bit;
r.data.tc_bit = m.tc_bit;
r.data.ec_block = m.ec_block;
r.data.tc_block = m.tc_block;
tvheadend.streamStatusStore.afterEdit(r);
tvheadend.streamStatusStore.fireEvent('updated',
tvheadend.streamStatusStore,
r,
Ext.data.Record.COMMIT);
} else {
tvheadend.streamStatusStore.reload();
}
}
});
var panel = new Ext.grid.GridPanel({
var dpanel = new Ext.Panel({
border: false,
loadMask: true,
stripeRows: true,
disableSelection: true,
header: false,
layout: 'fit',
title: 'Stream',
iconCls: 'hardware',
store: tvheadend.streamStatusStore,
cm: cm,
flex: 1,
viewConfig: {
forceFit: true
}
iconCls: 'hardware'
});
return panel;
tvheadend.paneladd(panel, dpanel, index);
tvheadend.panelreg(panel, dpanel, builder, destroyer);
};
/**
*
*/
tvheadend.status_conns = function() {
tvheadend.status_conns = function(panel, index) {
var store = new Ext.data.JsonStore({
root: 'entries',
totalProperty: 'totalCount',
fields: [
{ name: 'id' },
{ name: 'type' },
{ name: 'peer' },
{ name: 'user' },
{
name: 'started',
type: 'date',
dateFormat: 'U' /* unix time */
}
],
url: 'api/status/connections',
autoLoad: true,
id: 'id'
});
var grid = null;
var store = null;
tvheadend.comet.on('connections', function(m) {
function update(m) {
if (m.reload != null)
store.reload();
});
function renderDate(value) {
var dt = new Date(value);
return dt.format('Y-m-d H:i:s');
}
var cm = new Ext.grid.ColumnModel([{
width: 50,
id: 'type',
header: "Type",
dataIndex: 'type'
}, {
width: 50,
id: 'peer',
header: "IP Address",
dataIndex: 'peer'
}, {
width: 50,
id: 'user',
header: "Username",
dataIndex: 'user'
}, {
width: 50,
id: 'started',
header: "Started",
dataIndex: 'started',
renderer: renderDate
}]);
function builder() {
if (grid)
return;
var panel = new Ext.grid.GridPanel({
border: false,
loadMask: true,
stripeRows: true,
disableSelection: true,
title: 'Connections',
iconCls: 'eye',
store: store,
cm: cm,
flex: 1,
viewConfig: {
forceFit: true
store = new Ext.data.JsonStore({
root: 'entries',
totalProperty: 'totalCount',
fields: [
{ name: 'id' },
{ name: 'type' },
{ name: 'peer' },
{ name: 'user' },
{
name: 'started',
type: 'date',
dateFormat: 'U' /* unix time */
}
],
url: 'api/status/connections',
autoLoad: true,
id: 'id'
});
tvheadend.comet.on('connections', update);
function renderDate(value) {
var dt = new Date(value);
return dt.format('Y-m-d H:i:s');
}
var cm = new Ext.grid.ColumnModel([{
width: 50,
id: 'type',
header: "Type",
dataIndex: 'type'
}, {
width: 50,
id: 'peer',
header: "IP Address",
dataIndex: 'peer'
}, {
width: 50,
id: 'user',
header: "Username",
dataIndex: 'user'
}, {
width: 50,
id: 'started',
header: "Started",
dataIndex: 'started',
renderer: renderDate
}]);
grid = new Ext.grid.GridPanel({
border: false,
loadMask: true,
stripeRows: true,
disableSelection: true,
store: store,
cm: cm,
flex: 1,
viewConfig: {
forceFit: true
}
});
dpanel.add(grid);
dpanel.doLayout(false, true);
}
function destroyer() {
if (grid === null || !tvheadend.dynamic)
return;
dpanel.removeAll()
store.destroy();
store = null;
grid = null;
}
var dpanel = new Ext.Panel({
border: false,
header: false,
layout: 'fit',
title: 'Connections',
iconCls: 'eye'
});
return panel;
tvheadend.paneladd(panel, dpanel, index);
tvheadend.panelreg(panel, dpanel, builder, destroyer);
};
tvheadend.status = function() {
@ -430,13 +521,12 @@ tvheadend.status = function() {
autoScroll: true,
activeTab: 0,
iconCls: 'eye',
items: [
new tvheadend.status_streams,
new tvheadend.status_subs,
new tvheadend.status_conns,
new tvheadend.service_mapper_status
]
items: [],
});
tvheadend.status_streams(panel);
tvheadend.status_subs(panel);
tvheadend.status_conns(panel);
tvheadend.service_mapper_status(panel);
return panel;
};
@ -510,8 +600,9 @@ tvheadend.subscription_bw_monitor = function(id) {
var task = {
interval: 1000,
run: function() {
r = tvheadend.subsStore.getById(id);
if (typeof r === 'undefined') {
var store = tvheadend.subsStore;
var r = store ? store.getById(id) : null;
if (!store || typeof r === 'undefined') {
chart.stop();
Ext.TaskMgr.stop(task);
return;
@ -600,10 +691,11 @@ tvheadend.stream_bw_monitor = function(id) {
});
var task = {
interval: 1000,
interval: 10000,
run: function() {
r = tvheadend.streamStatusStore.getById(id);
if (typeof r === 'undefined') {
var store = tvheadend.streamStatusStore;
var r = store ? store.getById(id) : null;
if (!store || typeof r === 'undefined') {
chart.stop();
Ext.TaskMgr.stop(task);
return;