mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-06 05:01:14 -07:00
Multiselect user filters (#2090)
* Extract user filter generation code into method * Extend make_user_cond to allow lists of user IDs * Update documentation for stats APIs to indicate handling of ID lists * Use multiselect dropdown for user filter on graphs page Use standard concatenation Fix select style Move settings to JS constructor Change text for no users checked Don't call selectAll on page init Add it back Remove attributes Fix emptiness check Allow deselect all Only refresh if user id changed * Show "N users" starting at 2 users Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> * Use helper function split_strip Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> * Move make_user_cond at bottom and make private * Add new user picker to history page * Fix copy-paste error * Again * Add CSS for bootstrap-select --------- Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>
This commit is contained in:
parent
b144e6527f
commit
343a3e9281
7 changed files with 125 additions and 82 deletions
6
data/interfaces/default/css/bootstrap-select.min.css
vendored
Normal file
6
data/interfaces/default/css/bootstrap-select.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -2914,7 +2914,7 @@ a .home-platforms-list-cover-face:hover
|
|||
margin-bottom: -20px;
|
||||
width: 100%;
|
||||
max-width: 1750px;
|
||||
overflow: hidden;
|
||||
display: flow-root;
|
||||
}
|
||||
.table-card-back td {
|
||||
font-size: 12px;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<%inherit file="base.html"/>
|
||||
|
||||
<%def name="headIncludes()">
|
||||
<link rel="stylesheet" href="${http_root}css/bootstrap-select.min.css">
|
||||
<link rel="stylesheet" href="${http_root}css/dataTables.bootstrap.min.css">
|
||||
<link rel="stylesheet" href="${http_root}css/tautulli-dataTables.css">
|
||||
</%def>
|
||||
|
@ -14,9 +15,7 @@
|
|||
<div class="button-bar">
|
||||
<div class="btn-group" id="user-selection">
|
||||
<label>
|
||||
<select name="graph-user" id="graph-user" class="btn" style="color: inherit;">
|
||||
<option value="">All Users</option>
|
||||
<option disabled>────────────</option>
|
||||
<select name="graph-user" id="graph-user" multiple>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -225,6 +224,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script src="${http_root}js/bootstrap-select.min.js"></script>
|
||||
<script src="${http_root}js/highcharts.min.js"></script>
|
||||
<script src="${http_root}js/jquery.dataTables.min.js"></script>
|
||||
<script src="${http_root}js/dataTables.bootstrap.min.js"></script>
|
||||
|
@ -373,14 +373,35 @@
|
|||
type: 'get',
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
var select = $('#graph-user');
|
||||
let select = $('#graph-user');
|
||||
let by_id = {};
|
||||
data.sort(function(a, b) {
|
||||
return a.friendly_name.localeCompare(b.friendly_name);
|
||||
});
|
||||
data.forEach(function(item) {
|
||||
select.append('<option value="' + item.user_id + '">' +
|
||||
item.friendly_name + '</option>');
|
||||
by_id[item.user_id] = item.friendly_name;
|
||||
});
|
||||
select.selectpicker({
|
||||
countSelectedText: function(sel, total) {
|
||||
if (sel === 0 || sel === total) {
|
||||
return 'All users';
|
||||
} else if (sel > 1) {
|
||||
return sel + ' users';
|
||||
} else {
|
||||
return select.val().map(function(id) {
|
||||
return by_id[id];
|
||||
}).join(', ');
|
||||
}
|
||||
},
|
||||
style: 'btn-dark',
|
||||
actionsBox: true,
|
||||
selectedTextFormat: 'count',
|
||||
noneSelectedText: 'All users'
|
||||
});
|
||||
select.selectpicker('render');
|
||||
select.selectpicker('selectAll');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -602,11 +623,6 @@
|
|||
$('#nav-tabs-total').tab('show');
|
||||
}
|
||||
|
||||
// Set initial state
|
||||
if (current_tab === '#tabs-plays') { loadGraphsTab1(current_day_range, yaxis); }
|
||||
if (current_tab === '#tabs-stream') { loadGraphsTab2(current_day_range, yaxis); }
|
||||
if (current_tab === '#tabs-total') { loadGraphsTab3(current_month_range, yaxis); }
|
||||
|
||||
// Tab1 opened
|
||||
$('#nav-tabs-plays').on('shown.bs.tab', function (e) {
|
||||
e.preventDefault();
|
||||
|
@ -652,9 +668,20 @@
|
|||
$('.months').text(current_month_range);
|
||||
});
|
||||
|
||||
let graph_user_last_id = undefined;
|
||||
|
||||
// User changed
|
||||
$('#graph-user').on('change', function() {
|
||||
selected_user_id = $(this).val() || null;
|
||||
let val = $(this).val();
|
||||
if (val.length === 0 || val.length === $(this).children().length) {
|
||||
selected_user_id = null; // if all users are selected, just send an empty list
|
||||
} else {
|
||||
selected_user_id = val.join(",");
|
||||
}
|
||||
if (selected_user_id === graph_user_last_id) {
|
||||
return;
|
||||
}
|
||||
graph_user_last_id = selected_user_id;
|
||||
if (current_tab === '#tabs-plays') { loadGraphsTab1(current_day_range, yaxis); }
|
||||
if (current_tab === '#tabs-stream') { loadGraphsTab2(current_day_range, yaxis); }
|
||||
if (current_tab === '#tabs-total') { loadGraphsTab3(current_month_range, yaxis); }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<%inherit file="base.html"/>
|
||||
|
||||
<%def name="headIncludes()">
|
||||
<link rel="stylesheet" href="${http_root}css/bootstrap-select.min.css">
|
||||
<link rel="stylesheet" href="${http_root}css/dataTables.bootstrap.min.css">
|
||||
<link rel="stylesheet" href="${http_root}css/dataTables.colVis.css">
|
||||
<link rel="stylesheet" href="${http_root}css/tautulli-dataTables.css">
|
||||
|
@ -31,9 +32,7 @@
|
|||
% if _session['user_group'] == 'admin':
|
||||
<div class="btn-group" id="user-selection">
|
||||
<label>
|
||||
<select name="history-user" id="history-user" class="btn" style="color: inherit;">
|
||||
<option value="">All Users</option>
|
||||
<option disabled>────────────</option>
|
||||
<select name="history-user" id="history-user" multiple>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -121,6 +120,7 @@
|
|||
</%def>
|
||||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script src="${http_root}js/bootstrap-select.min.js"></script>
|
||||
<script src="${http_root}js/jquery.dataTables.min.js"></script>
|
||||
<script src="${http_root}js/dataTables.colVis.js"></script>
|
||||
<script src="${http_root}js/dataTables.bootstrap.min.js"></script>
|
||||
|
@ -134,17 +134,40 @@
|
|||
type: 'GET',
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
var select = $('#history-user');
|
||||
let select = $('#history-user');
|
||||
let by_id = {};
|
||||
data.sort(function (a, b) {
|
||||
return a.friendly_name.localeCompare(b.friendly_name);
|
||||
});
|
||||
data.forEach(function (item) {
|
||||
select.append('<option value="' + item.user_id + '">' +
|
||||
item.friendly_name + '</option>');
|
||||
by_id[item.user_id] = item.friendly_name;
|
||||
});
|
||||
select.selectpicker({
|
||||
countSelectedText: function(sel, total) {
|
||||
if (sel === 0 || sel === total) {
|
||||
return 'All users';
|
||||
} else if (sel > 1) {
|
||||
return sel + ' users';
|
||||
} else {
|
||||
return select.val().map(function(id) {
|
||||
return by_id[id];
|
||||
}).join(', ');
|
||||
}
|
||||
},
|
||||
style: 'btn-dark',
|
||||
actionsBox: true,
|
||||
selectedTextFormat: 'count',
|
||||
noneSelectedText: 'All users'
|
||||
});
|
||||
select.selectpicker('render');
|
||||
select.selectpicker('selectAll');
|
||||
}
|
||||
});
|
||||
|
||||
let history_user_last_id = undefined;
|
||||
|
||||
function loadHistoryTable(media_type, transcode_decision, selected_user_id) {
|
||||
history_table_options.ajax = {
|
||||
url: 'get_history',
|
||||
|
@ -187,7 +210,16 @@
|
|||
});
|
||||
|
||||
$('#history-user').on('change', function () {
|
||||
selected_user_id = $(this).val() || null;
|
||||
let val = $(this).val();
|
||||
if (val.length === 0 || val.length === $(this).children().length) {
|
||||
selected_user_id = null; // if all users are selected, just send an empty list
|
||||
} else {
|
||||
selected_user_id = val.join(",");
|
||||
}
|
||||
if (selected_user_id === history_user_last_id) {
|
||||
return;
|
||||
}
|
||||
history_user_last_id = selected_user_id;
|
||||
history_table.draw();
|
||||
});
|
||||
}
|
||||
|
|
9
data/interfaces/default/js/bootstrap-select.min.js
vendored
Normal file
9
data/interfaces/default/js/bootstrap-select.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue