Skip to content

Commit b100585

Browse files
DeltaMikeCharlieFlole998
authored andcommitted
Update WebUI to allow debug/trace subsystem selection from a list.
1 parent 223f83b commit b100585

3 files changed

Lines changed: 353 additions & 0 deletions

File tree

‎src/webui/static/app/ext.css‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,14 @@
476476
background-image: url(../icons/networks.png) !important;
477477
}
478478

479+
.delete {
480+
background-image: url(../icons/delete.png) !important;
481+
}
482+
483+
.list {
484+
background-image: url(../icons/list.png) !important;
485+
}
486+
479487
.muxes {
480488
background-image: url(../icons/muxes.png) !important;
481489
}

‎src/webui/static/app/tvhlog.js‎

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,355 @@ tvheadend.tvhlog = function(panel, index) {
1212
tracesubs.setDisabled(!trace.getValue() || trace.disabled);
1313
}
1414

15+
//START SUBSYSTEM SELECTION WINDOW CODE
16+
17+
//Define some variables local to this module.
18+
let debugSubsystemsSaved = "";
19+
let traceSubsystemsSaved = "";
20+
21+
let debugBoxUI = {};
22+
let traceBoxUI = {};
23+
24+
let subsystemStore = {};
25+
26+
//Create a button to show in the TVH config/debug toolbar.
27+
//When pressed, this will display the subsystem selection window.
28+
let subsystemsButton = {
29+
name: 'subsys',
30+
builder: function() {
31+
return new Ext.Toolbar.Button({
32+
tooltip: _('Select trace/debug options from a list of subsystems.'),
33+
iconCls: 'list',
34+
text: _('Select Subsystems'),
35+
disabled: false
36+
});
37+
},
38+
callback: function(conf, e, store, select) {
39+
40+
//Get a list of the subsystems currently entered
41+
//Do it this way instead of looking at the current status from
42+
//the API because the user may be in the middle of a manual change
43+
//and it would be polite to preserve those manual changes.
44+
let debugBox = document.getElementsByName("debugsubs");
45+
let traceBox = document.getElementsByName("tracesubs");
46+
47+
//These are the existing text UI text boxes.
48+
debugBoxUI = debugBox[0];
49+
traceBoxUI = traceBox[0];
50+
51+
//Save the initial UI text box values for a potential
52+
//reset at a later time.
53+
debugSubsystemsSaved = debugBoxUI.value;
54+
traceSubsystemsSaved = traceBoxUI.value;
55+
56+
//Break down the existing text box values into arrays.
57+
let debugArray = debugBoxUI.value.split(",");
58+
let traceArray = traceBoxUI.value.split(",");
59+
60+
//Grab the list of subsystems from the server.
61+
//Note that this is an asynchronous call and the
62+
//rest of the module needs to be contained within
63+
//the 'success' method in order to work.
64+
let subsystemList = Ext.Ajax.request({
65+
url: 'api/tvhlog/subsystem/grid',
66+
success: function(d) {
67+
68+
//Parse the results of the call and extract the 'entries'.
69+
let subsystemResponse = JSON.parse(d.responseText);
70+
subsystemList = subsystemResponse.entries;
71+
72+
//Add 'all' to the beginning of the list.
73+
//Subsystem 'all' is not a valid subsystem per-se,
74+
//however, TVH uses it internally to enable all subsystems.
75+
let tempSub = {
76+
id: -1,
77+
subsystem: 'all',
78+
description: _('All subsystems'),
79+
debug: false,
80+
trace: false
81+
};
82+
subsystemList.unshift(tempSub);
83+
84+
//Load the starting conditions from the text boxes
85+
//because the user may have already made some manual changes.
86+
let i = 0;
87+
88+
while (i < subsystemList.length) {
89+
subsystemList[i].debug = debugArray.includes(subsystemList[i].subsystem);
90+
subsystemList[i].trace = traceArray.includes(subsystemList[i].subsystem);
91+
i++;
92+
}
93+
94+
//Create the reset buttons for the bottom of the window.
95+
let buttons = [];
96+
buttons.push(new Ext.Toolbar.Button({
97+
handler: function() {
98+
windowButtons(10)
99+
},
100+
iconCls: 'delete',
101+
text: _('Clear Debug'),
102+
tooltip: _('Clear all debug subsystems.'),
103+
}));
104+
buttons.push(new Ext.Toolbar.Button({
105+
handler: function() {
106+
windowButtons(11)
107+
},
108+
iconCls: 'delete',
109+
text: _('Clear Trace'),
110+
tooltip: _('Clear all trace subsystems.'),
111+
}));
112+
buttons.push(new Ext.Toolbar.Button({
113+
handler: function() {
114+
windowButtons(0)
115+
},
116+
iconCls: 'undo',
117+
text: _('Restore Debug'),
118+
tooltip: _('Restore the debug subsystems to their initial state.'),
119+
}));
120+
buttons.push(new Ext.Toolbar.Button({
121+
handler: function() {
122+
windowButtons(1)
123+
},
124+
iconCls: 'undo',
125+
text: _('Restore Trace'),
126+
tooltip: _('Restore the trace subsystems to their initial state.'),
127+
}));
128+
129+
//This array will contain all of the elements to be
130+
//rendered onto the subsystem selection window.
131+
let windowItems = [];
132+
133+
//Create the data store that feeds the grid.
134+
//It takes the JSON response from TVH as its source.
135+
subsystemStore = new Ext.data.JsonStore({
136+
root: 'entries',
137+
data: subsystemResponse,
138+
autoLoad: true,
139+
id: 'id',
140+
fields: ['debug', 'trace', 'subsystem', 'description'],
141+
remoteSort: false,
142+
});
143+
144+
//Take a boolean field and display checkboxes instead
145+
//using existing ExtJS styles to match the TVH look-and-feel.
146+
function subsystemBooleanRenderer(val) {
147+
if (val) {
148+
return '<div class="x-grid3-check-col-on">&nbsp;</div>';
149+
} else {
150+
return '<div class="x-grid3-check-col">&nbsp;</div>';
151+
}
152+
}
153+
154+
//Define the column mode to be used. Note the custom
155+
//rendering for the boolean fields.
156+
let subsystemColumnModel = new Ext.grid.ColumnModel({
157+
columns: [{
158+
header: _("Debug"),
159+
width: 50,
160+
id: 'debug',
161+
renderer: subsystemBooleanRenderer
162+
},
163+
{
164+
header: _("Trace"),
165+
width: 50,
166+
id: 'trace',
167+
renderer: subsystemBooleanRenderer
168+
},
169+
{
170+
header: _("Subsystem"),
171+
width: 80,
172+
id: 'subsystem'
173+
},
174+
{
175+
header: _("Description"),
176+
width: 280,
177+
id: 'description'
178+
}
179+
],
180+
defaults: {
181+
sortable: false,
182+
menuDisabled: true,
183+
width: 100
184+
}
185+
});
186+
187+
188+
//Read through all of the subsystems and build a UI string.
189+
function getSubsystemString(checkList) {
190+
let debugList = [];
191+
let traceList = [];
192+
193+
i = 0;
194+
while (i < checkList.length) {
195+
196+
if (checkList[i].debug) {
197+
debugList.push(checkList[i].subsystem);
198+
}
199+
200+
if (checkList[i].trace) {
201+
traceList.push(checkList[i].subsystem);
202+
}
203+
204+
i++;
205+
}
206+
207+
return {
208+
debug: debugList.toString(),
209+
trace: traceList.toString()
210+
};
211+
212+
} //END getSubsystemString
213+
214+
215+
//Take the supplied strings and update the UI text boxes.
216+
function updateSubsystemUI(stringValues) {
217+
debugBoxUI.value = stringValues.debug;
218+
traceBoxUI.value = stringValues.trace;
219+
}
220+
221+
//Taking the row and column coordinates of the grid cell,
222+
//update the boolean values for each debug/trace and then
223+
//update the UI.
224+
function updateSubsystemActions(row, column) {
225+
226+
let myRecord;
227+
228+
//Toggle the debug subsystem
229+
if (column == 0) {
230+
subsystemList[row].debug = !subsystemList[row].debug;
231+
myRecord = subsystemStore.getAt(row);
232+
myRecord.set('debug', subsystemList[row].debug);
233+
}
234+
235+
//Toggle the trace subsystem
236+
if (column == 1) {
237+
subsystemList[row].trace = !subsystemList[row].trace;
238+
myRecord = subsystemStore.getAt(row);
239+
myRecord.set('trace', subsystemList[row].trace);
240+
}
241+
242+
//Toggle both subsystems
243+
if (column == 2) {
244+
245+
//If either is off, turn them both on
246+
if (!subsystemList[row].debug || !subsystemList[row].trace) {
247+
subsystemList[row].debug = true;
248+
subsystemList[row].trace = true;
249+
} else {
250+
subsystemList[row].debug = false;
251+
subsystemList[row].trace = false;
252+
}
253+
254+
myRecord = subsystemStore.getAt(row);
255+
myRecord.set('debug', subsystemList[row].debug);
256+
myRecord.set('trace', subsystemList[row].trace);
257+
}
258+
259+
//Update the existing UI text fields with the new values.
260+
updateSubsystemUI(getSubsystemString(subsystemList));
261+
} //END updateSubsystemActions
262+
263+
//Reset the subsystem selection to its original value.
264+
function resetSubsystems(propertyName, textBoxUI, newValues) {
265+
266+
let newArray = newValues.split(",");
267+
268+
//Reset the text box to the previous values
269+
textBoxUI.value = newValues;
270+
271+
//Loop through all of the subsystems and update their state
272+
//in the array and the store based on the saved state.
273+
let i = 0;
274+
while (i < subsystemList.length) {
275+
276+
subsystemList[i][propertyName] = newArray.includes(subsystemList[i].subsystem);
277+
let myRecord = subsystemStore.getAt(i);
278+
myRecord.set(propertyName, subsystemList[i][propertyName]);
279+
i++;
280+
} //END while loop
281+
} //END reset subsystems
282+
283+
284+
//Handle the buttons at the bottom of the window.
285+
function windowButtons(button) {
286+
287+
if (button == 0) {
288+
resetSubsystems("debug", debugBoxUI, debugSubsystemsSaved);
289+
}
290+
291+
if (button == 1) {
292+
resetSubsystems("trace", traceBoxUI, traceSubsystemsSaved);
293+
}
294+
295+
if (button == 10) {
296+
resetSubsystems("debug", debugBoxUI, "");
297+
}
298+
299+
if (button == 11) {
300+
resetSubsystems("trace", traceBoxUI, "");
301+
}
302+
303+
304+
} //End window button handlers.
305+
306+
307+
//Creeate the grid to be shown on the subsystem selection window.
308+
let grid = new Ext.grid.GridPanel({
309+
flex: 1,
310+
autoWidth: true,
311+
autoScroll: true,
312+
stripeRows: true,
313+
store: subsystemStore,
314+
cm: subsystemColumnModel,
315+
border: false,
316+
viewConfig: {
317+
markDirty: false //Hide the red tag that highlights changed records.
318+
},
319+
listeners: {
320+
cellclick: function(gridView, htmlElement, columnIndex, dataRecord) {
321+
updateSubsystemActions(htmlElement, columnIndex);
322+
}
323+
} //END listeners
324+
});
325+
326+
//Add the grid to the list of items to be rendered on the window.
327+
windowItems.push(grid);
328+
329+
//Create a window to display the list of subsystems.
330+
let windowHeight = Ext.getBody().getViewSize().height - 150;
331+
let subsysWin = new Ext.Window({
332+
title: _('Select Subsystems'),
333+
iconCls: 'debug',
334+
layout: 'fit',
335+
width: 500,
336+
height: windowHeight,
337+
constrainHeader: true,
338+
buttons: buttons,
339+
buttonAlign: 'center',
340+
autoScroll: true,
341+
items: windowItems
342+
});
343+
344+
//Display the subsystem selection window.
345+
subsysWin.show();
346+
347+
}, //END AJAX OK
348+
failure: function(response, options) {
349+
Ext.MessageBox.alert(_('Listing Subsystems'), response.statusText);
350+
return "";
351+
}
352+
}); //END Ajax request for subsystems list.
353+
} //END button callback.
354+
}; //END button object.
355+
356+
//END SUBSYSTEM SELECTION WINDOW CODE
357+
358+
//This is the standard debug config screen.
15359
tvheadend.idnode_simple(panel, {
16360
url: 'api/tvhlog/config',
17361
title: _('Configuration'),
18362
iconCls: 'debug',
363+
tbar: [subsystemsButton], //Add the button to list the subsystems
19364
tabIndex: index,
20365
comet: 'tvhlog_conf',
21366
labelWidth: 180,

‎src/webui/static/icons/list.png‎

572 Bytes
Loading

0 commit comments

Comments
 (0)