Reformat and don't pass back default parameters to URL
This commit is contained in:
@@ -2,141 +2,141 @@
|
||||
{% load static %}
|
||||
{% load joinsep %}
|
||||
{% block outer_content %}
|
||||
{% if params.modal == 'context' %}
|
||||
<div
|
||||
style="display: none;"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_context' %}"
|
||||
hx-vals='{"net": "{{ params.net|escapejs }}",
|
||||
"num": "{{ params.num|escapejs }}",
|
||||
"source": "{{ params.source|escapejs }}",
|
||||
"channel": "{{ params.channel|escapejs }}",
|
||||
"time": "{{ params.time|escapejs }}",
|
||||
"date": "{{ params.date|escapejs }}",
|
||||
"index": "{{ params.index }}",
|
||||
"type": "{{ params.type|escapejs }}",
|
||||
"mtype": "{{ params.mtype|escapejs }}",
|
||||
"nick": "{{ params.nick|escapejs }}"}'
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="load">
|
||||
</div>
|
||||
{% endif %}
|
||||
<script src="{% static 'js/chart.js' %}"></script>
|
||||
<script src="{% static 'tabs.js' %}"></script>
|
||||
<script>
|
||||
function setupTags() {
|
||||
var inputTags = document.getElementById('tags');
|
||||
new BulmaTagsInput(inputTags);
|
||||
|
||||
inputTags.BulmaTagsInput().on('before.add', function(item) {
|
||||
if (item.includes(": ")) {
|
||||
var spl = item.split(": ");
|
||||
} else {
|
||||
var spl = item.split(":");
|
||||
}
|
||||
var field = spl[0];
|
||||
try {
|
||||
var value = JSON.parse(spl[1]);
|
||||
} catch {
|
||||
var value = spl[1];
|
||||
}
|
||||
return `${field}: ${value}`;
|
||||
});
|
||||
inputTags.BulmaTagsInput().on('after.remove', function(item) {
|
||||
var spl = item.split(": ");
|
||||
var field = spl[0];
|
||||
var value = spl[1].trim();
|
||||
});
|
||||
}
|
||||
function populateSearch(field, value) {
|
||||
var inputTags = document.getElementById('tags');
|
||||
inputTags.BulmaTagsInput().add(field+": "+value);
|
||||
//htmx.trigger("#search", "click");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="grid-stack" id="grid-stack-main">
|
||||
<div class="grid-stack-item" gs-w="7" gs-h="10" gs-y="0" gs-x="1">
|
||||
<div class="grid-stack-item-content">
|
||||
<nav class="panel">
|
||||
<p class="panel-heading" style="padding: .2em; line-height: .5em;">
|
||||
<i class="fa-solid fa-arrows-up-down-left-right has-text-grey-light"></i>
|
||||
Search
|
||||
</p>
|
||||
<article class="panel-block is-active">
|
||||
{% include 'ui/drilldown/search_partial.html' %}
|
||||
</article>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var grid = GridStack.init({
|
||||
cellHeight: 20,
|
||||
cellWidth: 50,
|
||||
auto: true,
|
||||
float: true,
|
||||
draggable: {handle: '.panel-heading', scroll: false, appendTo: 'body'},
|
||||
removable: false,
|
||||
});
|
||||
// GridStack.init();
|
||||
setupTags();
|
||||
|
||||
// a widget is ready to be loaded
|
||||
document.addEventListener('load-widget', function(event) {
|
||||
let container = htmx.find('#drilldown-widget');
|
||||
// get the scripts, they won't be run on the new element so we need to eval them
|
||||
var scripts = htmx.findAll(container, "script");
|
||||
let widgetelement = container.firstElementChild.cloneNode(true);
|
||||
|
||||
// check if there's an existing element like the one we want to swap
|
||||
let grid_element = htmx.find('#grid-stack-main');
|
||||
let existing_widget = htmx.find(grid_element, '#drilldown-widget-results');
|
||||
|
||||
// get the size and position attributes
|
||||
if (existing_widget) {
|
||||
let attrs = existing_widget.getAttributeNames();
|
||||
for (let i = 0, len = attrs.length; i < len; i++) {
|
||||
if (attrs[i].startsWith('gs-')) { // only target gridstack attributes
|
||||
widgetelement.setAttribute(attrs[i], existing_widget.getAttribute(attrs[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear the queue element
|
||||
container.outerHTML = "";
|
||||
|
||||
// temporary workaround, other widgets can be duplicated, but not results
|
||||
if (widgetelement.id == 'drilldown-widget-results') {
|
||||
grid.removeWidget("drilldown-widget-{{ unique }}");
|
||||
}
|
||||
|
||||
grid.addWidget(widgetelement);
|
||||
// re-create the HTMX JS listeners, otherwise HTMX won't work inside the grid
|
||||
htmx.process(widgetelement);
|
||||
|
||||
// run the JS scripts inside the added element again
|
||||
// for instance, this will fix the dropdown
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
eval(scripts[i].innerHTML);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="modals-here">
|
||||
</div>
|
||||
<div id="items-here">
|
||||
</div>
|
||||
<div id="widgets-here" style="display: none;">
|
||||
</div>
|
||||
<div id="results" style="display: none;">
|
||||
{% if table %}
|
||||
{% include 'widgets/table_results.html' %}
|
||||
{% if params.modal == 'context' %}
|
||||
<div
|
||||
style="display: none;"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_context' %}"
|
||||
hx-vals='{"net": "{{ params.net|escapejs }}",
|
||||
"num": "{{ params.num|escapejs }}",
|
||||
"source": "{{ params.source|escapejs }}",
|
||||
"channel": "{{ params.channel|escapejs }}",
|
||||
"time": "{{ params.time|escapejs }}",
|
||||
"date": "{{ params.date|escapejs }}",
|
||||
"index": "{{ params.index }}",
|
||||
"type": "{{ params.type|escapejs }}",
|
||||
"mtype": "{{ params.mtype|escapejs }}",
|
||||
"nick": "{{ params.nick|escapejs }}"}'
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="load">
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<script>
|
||||
<script src="{% static 'js/chart.js' %}"></script>
|
||||
<script src="{% static 'tabs.js' %}"></script>
|
||||
<script>
|
||||
function setupTags() {
|
||||
var inputTags = document.getElementById('tags');
|
||||
new BulmaTagsInput(inputTags);
|
||||
|
||||
inputTags.BulmaTagsInput().on('before.add', function(item) {
|
||||
if (item.includes(": ")) {
|
||||
var spl = item.split(": ");
|
||||
} else {
|
||||
var spl = item.split(":");
|
||||
}
|
||||
var field = spl[0];
|
||||
try {
|
||||
var value = JSON.parse(spl[1]);
|
||||
} catch {
|
||||
var value = spl[1];
|
||||
}
|
||||
return `${field}: ${value}`;
|
||||
});
|
||||
inputTags.BulmaTagsInput().on('after.remove', function(item) {
|
||||
var spl = item.split(": ");
|
||||
var field = spl[0];
|
||||
var value = spl[1].trim();
|
||||
});
|
||||
}
|
||||
function populateSearch(field, value) {
|
||||
var inputTags = document.getElementById('tags');
|
||||
inputTags.BulmaTagsInput().add(field+": "+value);
|
||||
//htmx.trigger("#search", "click");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="grid-stack" id="grid-stack-main">
|
||||
<div class="grid-stack-item" gs-w="7" gs-h="10" gs-y="0" gs-x="1">
|
||||
<div class="grid-stack-item-content">
|
||||
<nav class="panel">
|
||||
<p class="panel-heading" style="padding: .2em; line-height: .5em;">
|
||||
<i class="fa-solid fa-arrows-up-down-left-right has-text-grey-light"></i>
|
||||
Search
|
||||
</p>
|
||||
<article class="panel-block is-active">
|
||||
{% include 'ui/drilldown/search_partial.html' %}
|
||||
</article>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var grid = GridStack.init({
|
||||
cellHeight: 20,
|
||||
cellWidth: 50,
|
||||
auto: true,
|
||||
float: true,
|
||||
draggable: {handle: '.panel-heading', scroll: false, appendTo: 'body'},
|
||||
removable: false,
|
||||
});
|
||||
// GridStack.init();
|
||||
setupTags();
|
||||
|
||||
// a widget is ready to be loaded
|
||||
document.addEventListener('load-widget', function(event) {
|
||||
let container = htmx.find('#drilldown-widget');
|
||||
// get the scripts, they won't be run on the new element so we need to eval them
|
||||
var scripts = htmx.findAll(container, "script");
|
||||
let widgetelement = container.firstElementChild.cloneNode(true);
|
||||
|
||||
// check if there's an existing element like the one we want to swap
|
||||
let grid_element = htmx.find('#grid-stack-main');
|
||||
let existing_widget = htmx.find(grid_element, '#drilldown-widget-results');
|
||||
|
||||
// get the size and position attributes
|
||||
if (existing_widget) {
|
||||
let attrs = existing_widget.getAttributeNames();
|
||||
for (let i = 0, len = attrs.length; i < len; i++) {
|
||||
if (attrs[i].startsWith('gs-')) { // only target gridstack attributes
|
||||
widgetelement.setAttribute(attrs[i], existing_widget.getAttribute(attrs[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clear the queue element
|
||||
container.outerHTML = "";
|
||||
|
||||
// temporary workaround, other widgets can be duplicated, but not results
|
||||
if (widgetelement.id == 'drilldown-widget-results') {
|
||||
grid.removeWidget("drilldown-widget-{{ unique }}");
|
||||
}
|
||||
|
||||
grid.addWidget(widgetelement);
|
||||
// re-create the HTMX JS listeners, otherwise HTMX won't work inside the grid
|
||||
htmx.process(widgetelement);
|
||||
|
||||
// run the JS scripts inside the added element again
|
||||
// for instance, this will fix the dropdown
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
eval(scripts[i].innerHTML);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="modals-here">
|
||||
</div>
|
||||
<div id="items-here">
|
||||
</div>
|
||||
<div id="widgets-here" style="display: none;">
|
||||
</div>
|
||||
<div id="results" style="display: none;">
|
||||
{% if table %}
|
||||
{% include 'widgets/table_results.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<script>
|
||||
|
||||
</script>
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,401 +1,401 @@
|
||||
<form class="skipEmptyFields" method="POST" hx-post="{% url 'search' %}"
|
||||
hx-trigger="change"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner">
|
||||
{% csrf_token %}
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="field has-addons">
|
||||
<div id="query" class="control is-expanded has-icons-left">
|
||||
<input
|
||||
hx-trigger="change"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner">
|
||||
{% csrf_token %}
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="field has-addons">
|
||||
<div id="query" class="control is-expanded has-icons-left">
|
||||
<input
|
||||
hx-post="{% url 'search' %}"
|
||||
hx-trigger="keyup changed delay:200ms"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
name="query"
|
||||
value="{{ params.query }}"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Search something">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<button
|
||||
id="search"
|
||||
class="button is-info is-fullwidth"
|
||||
hx-post="{% url 'search' %}"
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<div class="nowrap-parent">
|
||||
<div
|
||||
data-script="on click toggle .is-hidden on #options"
|
||||
class="button is-light has-text-link is-right nowrap-child">
|
||||
Options
|
||||
</div>
|
||||
<div class="nowrap-child">
|
||||
<span id="spinner" class="button is-light has-text-link is-loading htmx-indicator">Static</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="options" class="block is-hidden">
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-narrow">
|
||||
<div class="field has-addons">
|
||||
<div class="control has-icons-left">
|
||||
<span class="select">
|
||||
<select name="size">
|
||||
{% for size in sizes %}
|
||||
{% if size == params.size %}
|
||||
<option selected value="{{ size }}">{{ size }}</option>
|
||||
{% else %}
|
||||
<option value="{{ size }}">{{ size }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
results
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div class="field has-addons block">
|
||||
<div class="control has-icons-left">
|
||||
<span class="select">
|
||||
<select id="source" name="source">
|
||||
{% if params.source == 'irc' %}
|
||||
<option selected value="irc">IRC</option>
|
||||
{% else %}
|
||||
<option value="irc">IRC</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.source == 'dis' %}
|
||||
<option selected value="dis">Discord</option>
|
||||
{% else %}
|
||||
<option value="dis">Discord</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.source == None %}
|
||||
<option selected value="4ch">4chan</option>
|
||||
{% elif params.source == '4ch' %}
|
||||
<option selected value="4ch">4chan</option>
|
||||
{% else %}
|
||||
<option value="4ch">4chan</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.source == 'all' %}
|
||||
<option selected value="all">All</option>
|
||||
{% else %}
|
||||
<option value="all">All</option>
|
||||
{% endif %}
|
||||
|
||||
</select>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
source
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<input
|
||||
id="dedup_switch"
|
||||
type="checkbox"
|
||||
class="switch is-rounded is-info"
|
||||
name="dedup"
|
||||
{% if params.dedup == "on" %}
|
||||
checked="checked"
|
||||
{% endif %}>
|
||||
<label
|
||||
for="dedup_switch">
|
||||
Deduplicate results
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div id="sentiment">
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
<input
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled="undefined"
|
||||
{% endif %}
|
||||
name="sentiment" id="sliderWithValue" class="slider has-output-tooltip is-fullwidth" min="-1" max="1"
|
||||
{% if params.sentiment == None %}
|
||||
value="0"
|
||||
{% else %}
|
||||
value="{{ params.sentiment }}"
|
||||
{% endif %}
|
||||
step="0.05" type="range">
|
||||
<output for="sliderWithValue" class="slider-output">
|
||||
{% if params.sentiment == None %}
|
||||
0
|
||||
{% else %}
|
||||
{{ params.sentiment }}
|
||||
{% endif %}
|
||||
</output>
|
||||
<script>bulmaSlider.attach();</script>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
sentiment
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="below"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'below' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Below">
|
||||
<i class="fa-solid fa-face-frown"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button has-text-link is-hidden">
|
||||
<input
|
||||
type="radio"
|
||||
value="exact"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'exact' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Exact">
|
||||
<i class="fa-solid fa-face-smile"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="above"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'above' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Above">
|
||||
<i class="fa-solid fa-face-smile"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="nonzero"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'nonzero' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Nonzero">
|
||||
<i class="fa-solid fa-face-meh-blank"></i>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<input
|
||||
id="sentiment_switch"
|
||||
type="checkbox"
|
||||
class="switch is-rounded is-info"
|
||||
name="check_sentiment"
|
||||
data-script="on click toggle @disabled on #sliderWithValue then toggle @disabled on #sentiment then toggle @disabled on .sentiment-radio"
|
||||
{% if params.check_sentiment == "on" %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<label
|
||||
for="sentiment_switch">
|
||||
Check sentiment
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<input
|
||||
id="sentiment_graph_switch"
|
||||
type="checkbox"
|
||||
class="switch is-rounded is-info"
|
||||
name="show_sentiment"
|
||||
data-script="on click toggle .is-hidden on #sentiment-container">
|
||||
|
||||
<label
|
||||
for="sentiment_graph_switch">
|
||||
Show graph
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div id="date">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input type="date" name="dates" value="{{ params.date }}">
|
||||
<script>
|
||||
var options = {
|
||||
"type": "datetime",
|
||||
"isRange": true,
|
||||
"color": "info",
|
||||
"validateLabel": "Save",
|
||||
"dateFormat": "yyyy-MM-dd",
|
||||
"startDate": "{{ params.from_date|escapejs }}",
|
||||
"startTime": "{{ params.from_time|escapejs }}",
|
||||
"endDate": "{{ params.to_date|escapejs }}",
|
||||
"endTime": "{{ params.to_time|escapejs }}",
|
||||
"displayMode": "dialog"
|
||||
};
|
||||
// Initialize all input of type date
|
||||
var calendars = bulmaCalendar.attach('[type="date"]', options);
|
||||
|
||||
// Loop on each calendar initialized
|
||||
for(var i = 0; i < calendars.length; i++) {
|
||||
// Add listener to select event
|
||||
calendars[i].on('save', date => {
|
||||
htmx.trigger("#search", "click");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="desc"
|
||||
name="sorting"
|
||||
{% if params.sorting == None %}
|
||||
checked
|
||||
{% elif params.sorting == 'desc' %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Sort descending">
|
||||
<i class="fa-solid fa-sort-down"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button">
|
||||
<input
|
||||
type="radio"
|
||||
value="asc"
|
||||
name="sorting"
|
||||
{% if params.sorting == 'asc' %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Sort ascending">
|
||||
<i class="fa-solid fa-sort-up"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button">
|
||||
<input
|
||||
type="radio"
|
||||
value="none"
|
||||
name="sorting"
|
||||
{% if params.sorting == 'none' %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="No sort">
|
||||
<i class="fa-solid fa-sort"></i>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow rounded-tooltip">
|
||||
<div class="field has-addons">
|
||||
<div class="control has-icons-left">
|
||||
<span class="select is-warning">
|
||||
<select {% if not user.is_superuser %}disabled{% endif %} id="index" name="index">
|
||||
{% if params.index == 'main' %}
|
||||
<option selected value="main">Main</option>
|
||||
{% elif params.index == None %}
|
||||
<option selected value="main">Main</option>
|
||||
{% else %}
|
||||
<option value="main">Main</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.index == 'int' %}
|
||||
<option selected value="int">Internal</option>
|
||||
{% else %}
|
||||
<option value="int">Internal</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.index == 'meta' %}
|
||||
<option selected value="meta">Meta</option>
|
||||
{% else %}
|
||||
<option value="meta">Meta</option>
|
||||
{% endif %}
|
||||
|
||||
</select>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
index
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
{% if not user.is_superuser %}
|
||||
<span class="tooltiptext tag is-danger is-light">No access</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block">
|
||||
<input
|
||||
hx-trigger="change"
|
||||
hx-post="{% url 'search' %}"
|
||||
hx-trigger="keyup changed delay:200ms"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
name="query"
|
||||
value="{{ params.query }}"
|
||||
id="tags"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Search something">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<button
|
||||
id="search"
|
||||
class="button is-info is-fullwidth"
|
||||
hx-post="{% url 'search' %}"
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
type="tags"
|
||||
name="tags"
|
||||
placeholder="Tag search: nick: john"
|
||||
value="{{ params.tags }}">
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<div class="nowrap-parent">
|
||||
<div
|
||||
data-script="on click toggle .is-hidden on #options"
|
||||
class="button is-light has-text-link is-right nowrap-child">
|
||||
Options
|
||||
</div>
|
||||
<div class="nowrap-child">
|
||||
<span id="spinner" class="button is-light has-text-link is-loading htmx-indicator">Static</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="options" class="block is-hidden">
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-narrow">
|
||||
<div class="field has-addons">
|
||||
<div class="control has-icons-left">
|
||||
<span class="select">
|
||||
<select name="size">
|
||||
{% for size in sizes %}
|
||||
{% if size == params.size %}
|
||||
<option selected value="{{ size }}">{{ size }}</option>
|
||||
{% else %}
|
||||
<option value="{{ size }}">{{ size }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
results
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div class="field has-addons block">
|
||||
<div class="control has-icons-left">
|
||||
<span class="select">
|
||||
<select id="source" name="source">
|
||||
{% if params.source == 'irc' %}
|
||||
<option selected value="irc">IRC</option>
|
||||
{% else %}
|
||||
<option value="irc">IRC</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.source == 'dis' %}
|
||||
<option selected value="dis">Discord</option>
|
||||
{% else %}
|
||||
<option value="dis">Discord</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.source == None %}
|
||||
<option selected value="4ch">4chan</option>
|
||||
{% elif params.source == '4ch' %}
|
||||
<option selected value="4ch">4chan</option>
|
||||
{% else %}
|
||||
<option value="4ch">4chan</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.source == 'all' %}
|
||||
<option selected value="all">All</option>
|
||||
{% else %}
|
||||
<option value="all">All</option>
|
||||
{% endif %}
|
||||
|
||||
</select>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
source
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<input
|
||||
id="dedup_switch"
|
||||
type="checkbox"
|
||||
class="switch is-rounded is-info"
|
||||
name="dedup"
|
||||
{% if params.dedup == "on" %}
|
||||
checked="checked"
|
||||
{% endif %}>
|
||||
<label
|
||||
for="dedup_switch">
|
||||
Deduplicate results
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div id="sentiment">
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
<input
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled="undefined"
|
||||
{% endif %}
|
||||
name="sentiment" id="sliderWithValue" class="slider has-output-tooltip is-fullwidth" min="-1" max="1"
|
||||
{% if params.sentiment == None %}
|
||||
value="0"
|
||||
{% else %}
|
||||
value="{{ params.sentiment }}"
|
||||
{% endif %}
|
||||
step="0.05" type="range">
|
||||
<output for="sliderWithValue" class="slider-output">
|
||||
{% if params.sentiment == None %}
|
||||
0
|
||||
{% else %}
|
||||
{{ params.sentiment }}
|
||||
{% endif %}
|
||||
</output>
|
||||
<script>bulmaSlider.attach();</script>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
sentiment
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="below"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'below' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Below">
|
||||
<i class="fa-solid fa-face-frown"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button has-text-link is-hidden">
|
||||
<input
|
||||
type="radio"
|
||||
value="exact"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'exact' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Exact">
|
||||
<i class="fa-solid fa-face-smile"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="above"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'above' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Above">
|
||||
<i class="fa-solid fa-face-smile"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="nonzero"
|
||||
class="sentiment-radio"
|
||||
{% if params.sentiment_method == 'nonzero' %}
|
||||
checked
|
||||
{% endif %}
|
||||
name="sentiment_method"
|
||||
{% if params.check_sentiment != "on" %}
|
||||
disabled
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Nonzero">
|
||||
<i class="fa-solid fa-face-meh-blank"></i>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<input
|
||||
id="sentiment_switch"
|
||||
type="checkbox"
|
||||
class="switch is-rounded is-info"
|
||||
name="check_sentiment"
|
||||
data-script="on click toggle @disabled on #sliderWithValue then toggle @disabled on #sentiment then toggle @disabled on .sentiment-radio"
|
||||
{% if params.check_sentiment == "on" %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<label
|
||||
for="sentiment_switch">
|
||||
Check sentiment
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="field">
|
||||
<input
|
||||
id="sentiment_graph_switch"
|
||||
type="checkbox"
|
||||
class="switch is-rounded is-info"
|
||||
name="show_sentiment"
|
||||
data-script="on click toggle .is-hidden on #sentiment-container">
|
||||
|
||||
<label
|
||||
for="sentiment_graph_switch">
|
||||
Show graph
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div id="date">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input type="date" name="dates" value="{{ params.date }}">
|
||||
<script>
|
||||
var options = {
|
||||
"type": "datetime",
|
||||
"isRange": true,
|
||||
"color": "info",
|
||||
"validateLabel": "Save",
|
||||
"dateFormat": "yyyy-MM-dd",
|
||||
"startDate": "{{ params.from_date|escapejs }}",
|
||||
"startTime": "{{ params.from_time|escapejs }}",
|
||||
"endDate": "{{ params.to_date|escapejs }}",
|
||||
"endTime": "{{ params.to_time|escapejs }}",
|
||||
"displayMode": "dialog"
|
||||
};
|
||||
// Initialize all input of type date
|
||||
var calendars = bulmaCalendar.attach('[type="date"]', options);
|
||||
|
||||
// Loop on each calendar initialized
|
||||
for(var i = 0; i < calendars.length; i++) {
|
||||
// Add listener to select event
|
||||
calendars[i].on('save', date => {
|
||||
htmx.trigger("#search", "click");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="radio button has-text-link">
|
||||
<input
|
||||
type="radio"
|
||||
value="desc"
|
||||
name="sorting"
|
||||
{% if params.sorting == None %}
|
||||
checked
|
||||
{% elif params.sorting == 'desc' %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Sort descending">
|
||||
<i class="fa-solid fa-sort-down"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button">
|
||||
<input
|
||||
type="radio"
|
||||
value="asc"
|
||||
name="sorting"
|
||||
{% if params.sorting == 'asc' %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="Sort ascending">
|
||||
<i class="fa-solid fa-sort-up"></i>
|
||||
</span>
|
||||
</label>
|
||||
<label class="radio button">
|
||||
<input
|
||||
type="radio"
|
||||
value="none"
|
||||
name="sorting"
|
||||
{% if params.sorting == 'none' %}
|
||||
checked
|
||||
{% endif %}>
|
||||
<span class="icon" data-tooltip="No sort">
|
||||
<i class="fa-solid fa-sort"></i>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow rounded-tooltip">
|
||||
<div class="field has-addons">
|
||||
<div class="control has-icons-left">
|
||||
<span class="select is-warning">
|
||||
<select {% if not user.is_superuser %}disabled{% endif %} id="index" name="index">
|
||||
{% if params.index == 'main' %}
|
||||
<option selected value="main">Main</option>
|
||||
{% elif params.index == None %}
|
||||
<option selected value="main">Main</option>
|
||||
{% else %}
|
||||
<option value="main">Main</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.index == 'int' %}
|
||||
<option selected value="int">Internal</option>
|
||||
{% else %}
|
||||
<option value="int">Internal</option>
|
||||
{% endif %}
|
||||
|
||||
{% if params.index == 'meta' %}
|
||||
<option selected value="meta">Meta</option>
|
||||
{% else %}
|
||||
<option value="meta">Meta</option>
|
||||
{% endif %}
|
||||
|
||||
</select>
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-magnifying-glass"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<p class="control">
|
||||
<a class="button is-static">
|
||||
index
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
{% if not user.is_superuser %}
|
||||
<span class="tooltiptext tag is-danger is-light">No access</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block">
|
||||
<input
|
||||
hx-trigger="change"
|
||||
hx-post="{% url 'search' %}"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
id="tags"
|
||||
class="input"
|
||||
type="tags"
|
||||
name="tags"
|
||||
placeholder="Tag search: nick: john"
|
||||
value="{{ params.tags }}">
|
||||
</div>
|
||||
<div class="is-hidden"></div>
|
||||
<div class="is-hidden"></div>
|
||||
</form>
|
||||
@@ -3,8 +3,8 @@
|
||||
</div>
|
||||
|
||||
{% if params.index != 'int' and params.index != 'meta' %}
|
||||
<div id="sentiment-container" {% if params.show_sentiment is None %} class="is-hidden" {% endif %}>
|
||||
<canvas id="sentiment-chart"></canvas>
|
||||
</div>
|
||||
<script src="{% static 'chart.js' %}"></script>
|
||||
<div id="sentiment-container" {% if params.show_sentiment is None %} class="is-hidden" {% endif %}>
|
||||
<canvas id="sentiment-chart"></canvas>
|
||||
</div>
|
||||
<script src="{% static 'chart.js' %}"></script>
|
||||
{% endif %}
|
||||
|
||||
@@ -4,485 +4,485 @@
|
||||
{% load joinsep %}
|
||||
{% load urlsafe %}
|
||||
{% block table-wrapper %}
|
||||
<div id="drilldown-table" class="column-shifter-container" style="position:relative; z-index:1;">
|
||||
{% block table %}
|
||||
<div class="nowrap-parent">
|
||||
<div class="nowrap-child">
|
||||
<div class="dropdown" id="dropdown">
|
||||
<div class="dropdown-trigger">
|
||||
<button id="dropdown-trigger" class="button dropdown-toggle" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||
<span>Show/hide fields</span>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-angle-down" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content" style="position:absolute; z-index:2;">
|
||||
{% for column in table.columns %}
|
||||
{% if column.name in show %}
|
||||
<a class="btn-shift-column dropdown-item"
|
||||
data-td-class="{{ column.name }}"
|
||||
data-state="on"
|
||||
{% if not forloop.last %} style="border-bottom:1px solid #ccc;" {%endif %}
|
||||
data-table-class-container="drilldown-table">
|
||||
<span class="check icon" data-tooltip="Visible" style="display:none;">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</span>
|
||||
<span class="uncheck icon" data-tooltip="Hidden" style="display:none;">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</span>
|
||||
{{ column.header }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nowrap-child">
|
||||
<span id="loader" class="button is-light has-text-link is-loading">Static</span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var dropdown_button = document.getElementById("dropdown-trigger");
|
||||
var dropdown = document.getElementById("dropdown");
|
||||
dropdown_button.addEventListener('click', function(e) {
|
||||
// elements[i].preventDefault();
|
||||
dropdown.classList.toggle('is-active');
|
||||
});
|
||||
|
||||
</script>
|
||||
<div id="table-container" style="display:none;">
|
||||
<table {% render_attrs table.attrs class="table drilldown-results-table is-fullwidth" %}>
|
||||
{% block table.thead %}
|
||||
{% if table.show_header %}
|
||||
<thead {% render_attrs table.attrs.thead class="" %}>
|
||||
{% block table.thead.row %}
|
||||
<tr>
|
||||
{% for column in table.columns %}
|
||||
{% if column.name in show %}
|
||||
{% block table.thead.th %}
|
||||
<th class="orderable {{ column.name }}">
|
||||
<div class="nowrap-parent">
|
||||
{% if column.orderable %}
|
||||
<div class="nowrap-child">
|
||||
{% if column.is_ordered %}
|
||||
{% is_descending column.order_by as descending %}
|
||||
{% if descending %}
|
||||
<span class="icon" aria-hidden="true">{% block table.desc_icon %}<i class="fa-solid fa-sort-down"></i>{% endblock table.desc_icon %}</span>
|
||||
{% else %}
|
||||
<span class="icon" aria-hidden="true">{% block table.asc_icon %}<i class="fa-solid fa-sort-up"></i>{% endblock table.asc_icon %}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="icon" aria-hidden="true">{% block table.orderable_icon %}<i class="fa-solid fa-sort"></i>{% endblock table.orderable_icon %}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="nowrap-child">
|
||||
<a
|
||||
hx-get="search/{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
style="cursor: pointer;">
|
||||
{{ column.header }}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="nowrap-child">
|
||||
{{ column.header }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</th>
|
||||
{% endblock table.thead.th %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endblock table.thead.row %}
|
||||
</thead>
|
||||
{% endif %}
|
||||
{% endblock table.thead %}
|
||||
{% block table.tbody %}
|
||||
<tbody {{ table.attrs.tbody.as_html }}>
|
||||
{% for row in table.paginated_rows %}
|
||||
{% block table.tbody.row %}
|
||||
{% if row.cells.type == 'control' %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<span class="icon has-text-grey" data-tooltip="Hidden">
|
||||
<i class="fa-solid fa-file-slash"></i>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<p class="has-text-grey">Hidden {{ row.cells.hidden }} similar result{% if row.cells.hidden > 1%}s{% endif %}</p>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr class="
|
||||
{% if row.cells.exemption == True %}has-background-grey-lighter
|
||||
{% elif cell == 'join' %}has-background-success-light
|
||||
{% elif cell == 'quit' %}has-background-danger-light
|
||||
{% elif cell == 'kick' %}has-background-danger-light
|
||||
{% elif cell == 'part' %}has-background-warning-light
|
||||
{% elif cell == 'mode' %}has-background-info-light
|
||||
{% endif %}">
|
||||
{% for column, cell in row.items %}
|
||||
{% if column.name in show %}
|
||||
{% block table.tbody.td %}
|
||||
{% if cell == '—' %}
|
||||
<td class="{{ column.name }}">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-file-slash"></i>
|
||||
<div id="drilldown-table" class="column-shifter-container" style="position:relative; z-index:1;">
|
||||
{% block table %}
|
||||
<div class="nowrap-parent">
|
||||
<div class="nowrap-child">
|
||||
<div class="dropdown" id="dropdown">
|
||||
<div class="dropdown-trigger">
|
||||
<button id="dropdown-trigger" class="button dropdown-toggle" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||
<span>Show/hide fields</span>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-angle-down" aria-hidden="true"></i>
|
||||
</span>
|
||||
</td>
|
||||
{% elif column.name == 'tokens' %}
|
||||
<td class="{{ column.name }} wrap" style="max-width: 10em">
|
||||
{{ cell|joinsep:',' }}
|
||||
</td>
|
||||
{% elif column.name == 'src' %}
|
||||
<td class="{{ column.name }}">
|
||||
<a
|
||||
class="has-text-link is-underlined"
|
||||
onclick="populateSearch('src', '{{ cell|escapejs }}')">
|
||||
{% if row.cells.src == 'irc' %}
|
||||
<span class="icon" data-tooltip="IRC">
|
||||
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||
</span>
|
||||
{% elif row.cells.src == 'dis' %}
|
||||
<span class="icon" data-tooltip="Discord">
|
||||
<i class="fa-brands fa-discord" aria-hidden="true"></i>
|
||||
</span>
|
||||
{% elif row.cells.src == '4ch' %}
|
||||
<span class="icon" data-tooltip="4chan">
|
||||
<i class="fa-solid fa-leaf" aria-hidden="true"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
{% elif column.name == 'ts' %}
|
||||
<td class="{{ column.name }}">
|
||||
<p>{{ row.cells.date }}</p>
|
||||
<p>{{ row.cells.time }}</p>
|
||||
</td>
|
||||
{% elif column.name == 'type' or column.name == 'mtype' %}
|
||||
<td class="{{ column.name }}">
|
||||
<a
|
||||
class="has-text-link is-underlined"
|
||||
onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')">
|
||||
{% if cell == 'msg' %}
|
||||
<span class="icon" data-tooltip="Message">
|
||||
<i class="fa-solid fa-message"></i>
|
||||
</span>
|
||||
{% elif cell == 'join' %}
|
||||
<span class="icon" data-tooltip="Join">
|
||||
<i class="fa-solid fa-person-to-portal"></i>
|
||||
</span>
|
||||
{% elif cell == 'part' %}
|
||||
<span class="icon" data-tooltip="Part">
|
||||
<i class="fa-solid fa-person-from-portal"></i>
|
||||
</span>
|
||||
{% elif cell == 'quit' %}
|
||||
<span class="icon" data-tooltip="Quit">
|
||||
<i class="fa-solid fa-circle-xmark"></i>
|
||||
</span>
|
||||
{% elif cell == 'kick' %}
|
||||
<span class="icon" data-tooltip="Kick">
|
||||
<i class="fa-solid fa-user-slash"></i>
|
||||
</span>
|
||||
{% elif cell == 'nick' %}
|
||||
<span class="icon" data-tooltip="Nick">
|
||||
<i class="fa-solid fa-signature"></i>
|
||||
</span>
|
||||
{% elif cell == 'mode' %}
|
||||
<span class="icon" data-tooltip="Mode">
|
||||
<i class="fa-solid fa-gear"></i>
|
||||
</span>
|
||||
{% elif cell == 'action' %}
|
||||
<span class="icon" data-tooltip="Action">
|
||||
<i class="fa-solid fa-exclamation"></i>
|
||||
</span>
|
||||
{% elif cell == 'notice' %}
|
||||
<span class="icon" data-tooltip="Notice">
|
||||
<i class="fa-solid fa-message-code"></i>
|
||||
</span>
|
||||
{% elif cell == 'conn' %}
|
||||
<span class="icon" data-tooltip="Connection">
|
||||
<i class="fa-solid fa-cloud-exclamation"></i>
|
||||
</span>
|
||||
{% elif cell == 'znc' %}
|
||||
<span class="icon" data-tooltip="ZNC">
|
||||
<i class="fa-brands fa-unity"></i>
|
||||
</span>
|
||||
{% elif cell == 'query' %}
|
||||
<span class="icon" data-tooltip="Query">
|
||||
<i class="fa-solid fa-message"></i>
|
||||
</span>
|
||||
{% elif cell == 'highlight' %}
|
||||
<span class="icon" data-tooltip="Highlight">
|
||||
<i class="fa-solid fa-exclamation"></i>
|
||||
</span>
|
||||
{% elif cell == 'who' %}
|
||||
<span class="icon" data-tooltip="Who">
|
||||
<i class="fa-solid fa-passport"></i>
|
||||
</span>
|
||||
{% elif cell == 'topic' %}
|
||||
<span class="icon" data-tooltip="Topic">
|
||||
<i class="fa-solid fa-sign"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
{{ cell }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
{% elif column.name == 'msg' %}
|
||||
<td class="{{ column.name }} wrap">
|
||||
<a
|
||||
class="has-text-grey is-underlined"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_context' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net|escapejs }}",
|
||||
"num": "{{ row.cells.num|escapejs }}",
|
||||
"source": "{{ row.cells.src|escapejs }}",
|
||||
"channel": "{{ row.cells.channel|escapejs }}",
|
||||
"time": "{{ row.cells.time|escapejs }}",
|
||||
"date": "{{ row.cells.date|escapejs }}",
|
||||
"index": "{{ params.index }}",
|
||||
"type": "{{ row.cells.type }}",
|
||||
"mtype": "{{ row.cells.mtype }}",
|
||||
"nick": "{{ row.cells.nick|escapejs }}",
|
||||
"dedup": "{{ params.dedup }}"}'
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
href="/?modal=context&net={{row.cells.net|escapejs}}&num={{row.cells.num|escapejs}}&source={{row.cells.src|escapejs}}&channel={{row.cells.channel|urlsafe}}&time={{row.cells.time|escapejs}}&date={{row.cells.date|escapejs}}&index={{params.index}}&type={{row.cells.type}}&mtype={{row.cells.mtype}}&nick={{row.cells.mtype|escapejs}}">
|
||||
{{ row.cells.msg }}
|
||||
</a>
|
||||
</td>
|
||||
{% elif column.name == 'nick' %}
|
||||
<td class="{{ column.name }}">
|
||||
<div class="nowrap-parent">
|
||||
<div class="nowrap-child">
|
||||
{% if row.cells.online is True %}
|
||||
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
|
||||
<i class="fa-solid fa-circle"></i>
|
||||
</span>
|
||||
{% elif row.cells.online is False %}
|
||||
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
|
||||
<i class="fa-solid fa-circle"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
|
||||
<i class="fa-solid fa-circle"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content" style="position:absolute; z-index:2;">
|
||||
{% for column in table.columns %}
|
||||
{% if column.name in show %}
|
||||
<a class="btn-shift-column dropdown-item"
|
||||
data-td-class="{{ column.name }}"
|
||||
data-state="on"
|
||||
{% if not forloop.last %} style="border-bottom:1px solid #ccc;" {%endif %}
|
||||
data-table-class-container="drilldown-table">
|
||||
<span class="check icon" data-tooltip="Visible" style="display:none;">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</span>
|
||||
<span class="uncheck icon" data-tooltip="Hidden" style="display:none;">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</span>
|
||||
{{ column.header }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a class="nowrap-child has-text-link is-underlined" onclick="populateSearch('nick', '{{ cell|escapejs }}')">
|
||||
{{ cell }}
|
||||
</a>
|
||||
<div class="nowrap-child">
|
||||
{% if row.cells.src == 'irc' %}
|
||||
<a
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_drilldown' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
class="has-text-black">
|
||||
<span class="icon" data-tooltip="Open drilldown modal">
|
||||
<i class="fa-solid fa-album"></i>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_drilldown' type='window' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
|
||||
hx-target="#items-here"
|
||||
hx-swap="afterend"
|
||||
hx-trigger="click"
|
||||
class="has-text-black">
|
||||
<span class="icon" data-tooltip="Open drilldown window">
|
||||
<i class="fa-solid fa-album"></i>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_drilldown' type='widget' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
|
||||
hx-target="#widgets-here"
|
||||
hx-trigger="click"
|
||||
class="has-text-black">
|
||||
<span class="icon" data-tooltip="Open drilldown widget">
|
||||
<i class="fa-solid fa-album"></i>
|
||||
</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if row.cells.num_chans != '—' %}
|
||||
<div class="nowrap-child">
|
||||
<span class="tag">
|
||||
{{ row.cells.num_chans }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
{% elif column.name == 'channel' %}
|
||||
<td class="{{ column.name }}">
|
||||
{% if cell != '—' %}
|
||||
<div class="nowrap-parent">
|
||||
<a
|
||||
class="nowrap-child has-text-link is-underlined"
|
||||
onclick="populateSearch('channel', '{{ cell|escapejs }}')">
|
||||
{{ cell }}
|
||||
</a>
|
||||
{% if row.cells.num_users != '—' %}
|
||||
<div class="nowrap-child">
|
||||
<span class="tag">
|
||||
{{ row.cells.num_users }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ cell }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% elif cell is True or cell is False %}
|
||||
<td class="{{ column.name }}">
|
||||
{% if cell is True %}
|
||||
<span class="icon has-text-success">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="{{ column.name }}">
|
||||
<a
|
||||
class="has-text-link is-underlined"
|
||||
onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')">
|
||||
{{ cell }}
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endblock table.tbody.td %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nowrap-child">
|
||||
<span id="loader" class="button is-light has-text-link is-loading">Static</span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var dropdown_button = document.getElementById("dropdown-trigger");
|
||||
var dropdown = document.getElementById("dropdown");
|
||||
dropdown_button.addEventListener('click', function(e) {
|
||||
// elements[i].preventDefault();
|
||||
dropdown.classList.toggle('is-active');
|
||||
});
|
||||
|
||||
</script>
|
||||
<div id="table-container" style="display:none;">
|
||||
<table {% render_attrs table.attrs class="table drilldown-results-table is-fullwidth" %}>
|
||||
{% block table.thead %}
|
||||
{% if table.show_header %}
|
||||
<thead {% render_attrs table.attrs.thead class="" %}>
|
||||
{% block table.thead.row %}
|
||||
<tr>
|
||||
{% for column in table.columns %}
|
||||
{% if column.name in show %}
|
||||
{% block table.thead.th %}
|
||||
<th class="orderable {{ column.name }}">
|
||||
<div class="nowrap-parent">
|
||||
{% if column.orderable %}
|
||||
<div class="nowrap-child">
|
||||
{% if column.is_ordered %}
|
||||
{% is_descending column.order_by as descending %}
|
||||
{% if descending %}
|
||||
<span class="icon" aria-hidden="true">{% block table.desc_icon %}<i class="fa-solid fa-sort-down"></i>{% endblock table.desc_icon %}</span>
|
||||
{% else %}
|
||||
<span class="icon" aria-hidden="true">{% block table.asc_icon %}<i class="fa-solid fa-sort-up"></i>{% endblock table.asc_icon %}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="icon" aria-hidden="true">{% block table.orderable_icon %}<i class="fa-solid fa-sort"></i>{% endblock table.orderable_icon %}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="nowrap-child">
|
||||
<a
|
||||
hx-get="search/{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
style="cursor: pointer;">
|
||||
{{ column.header }}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="nowrap-child">
|
||||
{{ column.header }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</th>
|
||||
{% endblock table.thead.th %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endblock table.thead.row %}
|
||||
</thead>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endblock table.tbody.row %}
|
||||
{% empty %}
|
||||
{% if table.empty_text %}
|
||||
{% block table.tbody.empty_text %}
|
||||
<tr><td class="{{ column.name }}" colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
|
||||
{% endblock table.tbody.empty_text %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endblock table.tbody %}
|
||||
{% block table.tfoot %}
|
||||
{% if table.has_footer %}
|
||||
<tfoot {{ table.attrs.tfoot.as_html }}>
|
||||
{% block table.tfoot.row %}
|
||||
<tr>
|
||||
{% for column in table.columns %}
|
||||
{% block table.tfoot.td %}
|
||||
<td class="{{ column.name }}" {{ column.attrs.tf.as_html }}>{{ column.footer }}</td>
|
||||
{% endblock table.tfoot.td %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endblock table.tfoot.row %}
|
||||
</tfoot>
|
||||
{% endblock table.thead %}
|
||||
{% block table.tbody %}
|
||||
<tbody {{ table.attrs.tbody.as_html }}>
|
||||
{% for row in table.paginated_rows %}
|
||||
{% block table.tbody.row %}
|
||||
{% if row.cells.type == 'control' %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<span class="icon has-text-grey" data-tooltip="Hidden">
|
||||
<i class="fa-solid fa-file-slash"></i>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<p class="has-text-grey">Hidden {{ row.cells.hidden }} similar result{% if row.cells.hidden > 1%}s{% endif %}</p>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr class="
|
||||
{% if row.cells.exemption == True %}has-background-grey-lighter
|
||||
{% elif cell == 'join' %}has-background-success-light
|
||||
{% elif cell == 'quit' %}has-background-danger-light
|
||||
{% elif cell == 'kick' %}has-background-danger-light
|
||||
{% elif cell == 'part' %}has-background-warning-light
|
||||
{% elif cell == 'mode' %}has-background-info-light
|
||||
{% endif %}">
|
||||
{% for column, cell in row.items %}
|
||||
{% if column.name in show %}
|
||||
{% block table.tbody.td %}
|
||||
{% if cell == '—' %}
|
||||
<td class="{{ column.name }}">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-file-slash"></i>
|
||||
</span>
|
||||
</td>
|
||||
{% elif column.name == 'tokens' %}
|
||||
<td class="{{ column.name }} wrap" style="max-width: 10em">
|
||||
{{ cell|joinsep:',' }}
|
||||
</td>
|
||||
{% elif column.name == 'src' %}
|
||||
<td class="{{ column.name }}">
|
||||
<a
|
||||
class="has-text-link is-underlined"
|
||||
onclick="populateSearch('src', '{{ cell|escapejs }}')">
|
||||
{% if row.cells.src == 'irc' %}
|
||||
<span class="icon" data-tooltip="IRC">
|
||||
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||
</span>
|
||||
{% elif row.cells.src == 'dis' %}
|
||||
<span class="icon" data-tooltip="Discord">
|
||||
<i class="fa-brands fa-discord" aria-hidden="true"></i>
|
||||
</span>
|
||||
{% elif row.cells.src == '4ch' %}
|
||||
<span class="icon" data-tooltip="4chan">
|
||||
<i class="fa-solid fa-leaf" aria-hidden="true"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
{% elif column.name == 'ts' %}
|
||||
<td class="{{ column.name }}">
|
||||
<p>{{ row.cells.date }}</p>
|
||||
<p>{{ row.cells.time }}</p>
|
||||
</td>
|
||||
{% elif column.name == 'type' or column.name == 'mtype' %}
|
||||
<td class="{{ column.name }}">
|
||||
<a
|
||||
class="has-text-link is-underlined"
|
||||
onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')">
|
||||
{% if cell == 'msg' %}
|
||||
<span class="icon" data-tooltip="Message">
|
||||
<i class="fa-solid fa-message"></i>
|
||||
</span>
|
||||
{% elif cell == 'join' %}
|
||||
<span class="icon" data-tooltip="Join">
|
||||
<i class="fa-solid fa-person-to-portal"></i>
|
||||
</span>
|
||||
{% elif cell == 'part' %}
|
||||
<span class="icon" data-tooltip="Part">
|
||||
<i class="fa-solid fa-person-from-portal"></i>
|
||||
</span>
|
||||
{% elif cell == 'quit' %}
|
||||
<span class="icon" data-tooltip="Quit">
|
||||
<i class="fa-solid fa-circle-xmark"></i>
|
||||
</span>
|
||||
{% elif cell == 'kick' %}
|
||||
<span class="icon" data-tooltip="Kick">
|
||||
<i class="fa-solid fa-user-slash"></i>
|
||||
</span>
|
||||
{% elif cell == 'nick' %}
|
||||
<span class="icon" data-tooltip="Nick">
|
||||
<i class="fa-solid fa-signature"></i>
|
||||
</span>
|
||||
{% elif cell == 'mode' %}
|
||||
<span class="icon" data-tooltip="Mode">
|
||||
<i class="fa-solid fa-gear"></i>
|
||||
</span>
|
||||
{% elif cell == 'action' %}
|
||||
<span class="icon" data-tooltip="Action">
|
||||
<i class="fa-solid fa-exclamation"></i>
|
||||
</span>
|
||||
{% elif cell == 'notice' %}
|
||||
<span class="icon" data-tooltip="Notice">
|
||||
<i class="fa-solid fa-message-code"></i>
|
||||
</span>
|
||||
{% elif cell == 'conn' %}
|
||||
<span class="icon" data-tooltip="Connection">
|
||||
<i class="fa-solid fa-cloud-exclamation"></i>
|
||||
</span>
|
||||
{% elif cell == 'znc' %}
|
||||
<span class="icon" data-tooltip="ZNC">
|
||||
<i class="fa-brands fa-unity"></i>
|
||||
</span>
|
||||
{% elif cell == 'query' %}
|
||||
<span class="icon" data-tooltip="Query">
|
||||
<i class="fa-solid fa-message"></i>
|
||||
</span>
|
||||
{% elif cell == 'highlight' %}
|
||||
<span class="icon" data-tooltip="Highlight">
|
||||
<i class="fa-solid fa-exclamation"></i>
|
||||
</span>
|
||||
{% elif cell == 'who' %}
|
||||
<span class="icon" data-tooltip="Who">
|
||||
<i class="fa-solid fa-passport"></i>
|
||||
</span>
|
||||
{% elif cell == 'topic' %}
|
||||
<span class="icon" data-tooltip="Topic">
|
||||
<i class="fa-solid fa-sign"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
{{ cell }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
{% elif column.name == 'msg' %}
|
||||
<td class="{{ column.name }} wrap">
|
||||
<a
|
||||
class="has-text-grey is-underlined"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_context' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net|escapejs }}",
|
||||
"num": "{{ row.cells.num|escapejs }}",
|
||||
"source": "{{ row.cells.src|escapejs }}",
|
||||
"channel": "{{ row.cells.channel|escapejs }}",
|
||||
"time": "{{ row.cells.time|escapejs }}",
|
||||
"date": "{{ row.cells.date|escapejs }}",
|
||||
"index": "{{ params.index }}",
|
||||
"type": "{{ row.cells.type }}",
|
||||
"mtype": "{{ row.cells.mtype }}",
|
||||
"nick": "{{ row.cells.nick|escapejs }}",
|
||||
"dedup": "{{ params.dedup }}"}'
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
href="/?modal=context&net={{row.cells.net|escapejs}}&num={{row.cells.num|escapejs}}&source={{row.cells.src|escapejs}}&channel={{row.cells.channel|urlsafe}}&time={{row.cells.time|escapejs}}&date={{row.cells.date|escapejs}}&index={{params.index}}&type={{row.cells.type}}&mtype={{row.cells.mtype}}&nick={{row.cells.mtype|escapejs}}">
|
||||
{{ row.cells.msg }}
|
||||
</a>
|
||||
</td>
|
||||
{% elif column.name == 'nick' %}
|
||||
<td class="{{ column.name }}">
|
||||
<div class="nowrap-parent">
|
||||
<div class="nowrap-child">
|
||||
{% if row.cells.online is True %}
|
||||
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
|
||||
<i class="fa-solid fa-circle"></i>
|
||||
</span>
|
||||
{% elif row.cells.online is False %}
|
||||
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
|
||||
<i class="fa-solid fa-circle"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
|
||||
<i class="fa-solid fa-circle"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<a class="nowrap-child has-text-link is-underlined" onclick="populateSearch('nick', '{{ cell|escapejs }}')">
|
||||
{{ cell }}
|
||||
</a>
|
||||
<div class="nowrap-child">
|
||||
{% if row.cells.src == 'irc' %}
|
||||
<a
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_drilldown' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
|
||||
hx-target="#modals-here"
|
||||
hx-trigger="click"
|
||||
class="has-text-black">
|
||||
<span class="icon" data-tooltip="Open drilldown modal">
|
||||
<i class="fa-solid fa-album"></i>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_drilldown' type='window' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
|
||||
hx-target="#items-here"
|
||||
hx-swap="afterend"
|
||||
hx-trigger="click"
|
||||
class="has-text-black">
|
||||
<span class="icon" data-tooltip="Open drilldown window">
|
||||
<i class="fa-solid fa-album"></i>
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-post="{% url 'modal_drilldown' type='widget' %}"
|
||||
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
|
||||
hx-target="#widgets-here"
|
||||
hx-trigger="click"
|
||||
class="has-text-black">
|
||||
<span class="icon" data-tooltip="Open drilldown widget">
|
||||
<i class="fa-solid fa-album"></i>
|
||||
</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if row.cells.num_chans != '—' %}
|
||||
<div class="nowrap-child">
|
||||
<span class="tag">
|
||||
{{ row.cells.num_chans }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
{% elif column.name == 'channel' %}
|
||||
<td class="{{ column.name }}">
|
||||
{% if cell != '—' %}
|
||||
<div class="nowrap-parent">
|
||||
<a
|
||||
class="nowrap-child has-text-link is-underlined"
|
||||
onclick="populateSearch('channel', '{{ cell|escapejs }}')">
|
||||
{{ cell }}
|
||||
</a>
|
||||
{% if row.cells.num_users != '—' %}
|
||||
<div class="nowrap-child">
|
||||
<span class="tag">
|
||||
{{ row.cells.num_users }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ cell }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% elif cell is True or cell is False %}
|
||||
<td class="{{ column.name }}">
|
||||
{% if cell is True %}
|
||||
<span class="icon has-text-success">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="{{ column.name }}">
|
||||
<a
|
||||
class="has-text-link is-underlined"
|
||||
onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')">
|
||||
{{ cell }}
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endblock table.tbody.td %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endblock table.tbody.row %}
|
||||
{% empty %}
|
||||
{% if table.empty_text %}
|
||||
{% block table.tbody.empty_text %}
|
||||
<tr><td class="{{ column.name }}" colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
|
||||
{% endblock table.tbody.empty_text %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endblock table.tbody %}
|
||||
{% block table.tfoot %}
|
||||
{% if table.has_footer %}
|
||||
<tfoot {{ table.attrs.tfoot.as_html }}>
|
||||
{% block table.tfoot.row %}
|
||||
<tr>
|
||||
{% for column in table.columns %}
|
||||
{% block table.tfoot.td %}
|
||||
<td class="{{ column.name }}" {{ column.attrs.tf.as_html }}>{{ column.footer }}</td>
|
||||
{% endblock table.tfoot.td %}
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endblock table.tfoot.row %}
|
||||
</tfoot>
|
||||
{% endif %}
|
||||
{% endblock table.tfoot %}
|
||||
</table>
|
||||
</div>
|
||||
{% endblock table %}
|
||||
{% block pagination %}
|
||||
{% if table.page and table.paginator.num_pages > 1 %}
|
||||
<nav class="pagination is-justify-content-flex-end" role="navigation" aria-label="pagination">
|
||||
{% block pagination.previous %}
|
||||
<a
|
||||
class="pagination-previous is-flex-grow-0 {% if not table.page.has_previous %}is-hidden-mobile{% endif %}"
|
||||
{% if table.page.has_previous %}
|
||||
hx-get="search/{% querystring table.prefixed_page_field=table.page.previous_page_number %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
{% else %}
|
||||
href="#"
|
||||
disabled
|
||||
{% endif %}
|
||||
style="order:1;">
|
||||
{% block pagination.previous.text %}
|
||||
<span aria-hidden="true">«</span>
|
||||
{% endblock pagination.previous.text %}
|
||||
</a>
|
||||
{% endblock pagination.previous %}
|
||||
{% block pagination.next %}
|
||||
<a
|
||||
class="pagination-next is-flex-grow-0 {% if not table.page.has_next %}is-hidden-mobile{% endif %}"
|
||||
{% if table.page.has_next %}
|
||||
hx-get="search/{% querystring table.prefixed_page_field=table.page.next_page_number %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
{% else %}
|
||||
href="#"
|
||||
disabled
|
||||
{% endif %}
|
||||
style="order:3;"
|
||||
>
|
||||
{% block pagination.next.text %}
|
||||
<span aria-hidden="true">»</span>
|
||||
{% endblock pagination.next.text %}
|
||||
</a>
|
||||
{% endblock pagination.next %}
|
||||
{% if table.page.has_previous or table.page.has_next %}
|
||||
{% block pagination.range %}
|
||||
<ul class="pagination-list is-flex-grow-0" style="order:2;">
|
||||
{% for p in table.page|table_page_range:table.paginator %}
|
||||
<li>
|
||||
<a
|
||||
class="pagination-link {% if p == table.page.number %}is-current{% endif %}"
|
||||
aria-label="Page {{ p }}" block
|
||||
{% if p == table.page.number %}aria-current="page"{% endif %}
|
||||
{% if p == table.page.number %}
|
||||
href="#"
|
||||
{% else %}
|
||||
hx-get="search/{% querystring table.prefixed_page_field=p %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
{% endif %}
|
||||
>
|
||||
{% if p == '...' %}
|
||||
<span class="pagination-ellipsis">…</span>
|
||||
{% else %}
|
||||
{{ p }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock pagination.range %}
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% endblock table.tfoot %}
|
||||
</table>
|
||||
</div>
|
||||
{% endblock table %}
|
||||
{% block pagination %}
|
||||
{% if table.page and table.paginator.num_pages > 1 %}
|
||||
<nav class="pagination is-justify-content-flex-end" role="navigation" aria-label="pagination">
|
||||
{% block pagination.previous %}
|
||||
<a
|
||||
class="pagination-previous is-flex-grow-0 {% if not table.page.has_previous %}is-hidden-mobile{% endif %}"
|
||||
{% if table.page.has_previous %}
|
||||
hx-get="search/{% querystring table.prefixed_page_field=table.page.previous_page_number %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
{% else %}
|
||||
href="#"
|
||||
disabled
|
||||
{% endif %}
|
||||
style="order:1;">
|
||||
{% block pagination.previous.text %}
|
||||
<span aria-hidden="true">«</span>
|
||||
{% endblock pagination.previous.text %}
|
||||
</a>
|
||||
{% endblock pagination.previous %}
|
||||
{% block pagination.next %}
|
||||
<a
|
||||
class="pagination-next is-flex-grow-0 {% if not table.page.has_next %}is-hidden-mobile{% endif %}"
|
||||
{% if table.page.has_next %}
|
||||
hx-get="search/{% querystring table.prefixed_page_field=table.page.next_page_number %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
{% else %}
|
||||
href="#"
|
||||
disabled
|
||||
{% endif %}
|
||||
style="order:3;"
|
||||
>
|
||||
{% block pagination.next.text %}
|
||||
<span aria-hidden="true">»</span>
|
||||
{% endblock pagination.next.text %}
|
||||
</a>
|
||||
{% endblock pagination.next %}
|
||||
{% if table.page.has_previous or table.page.has_next %}
|
||||
{% block pagination.range %}
|
||||
<ul class="pagination-list is-flex-grow-0" style="order:2;">
|
||||
{% for p in table.page|table_page_range:table.paginator %}
|
||||
<li>
|
||||
<a
|
||||
class="pagination-link {% if p == table.page.number %}is-current{% endif %}"
|
||||
aria-label="Page {{ p }}" block
|
||||
{% if p == table.page.number %}aria-current="page"{% endif %}
|
||||
{% if p == table.page.number %}
|
||||
href="#"
|
||||
{% else %}
|
||||
hx-get="search/{% querystring table.prefixed_page_field=p %}&{{ uri }}"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-trigger="click"
|
||||
hx-target="#results"
|
||||
hx-swap="innerHTML"
|
||||
hx-indicator="#spinner"
|
||||
{% endif %}
|
||||
>
|
||||
{% if p == '...' %}
|
||||
<span class="pagination-ellipsis">…</span>
|
||||
{% else %}
|
||||
{{ p }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock pagination.range %}
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% endblock pagination %}
|
||||
</div>
|
||||
{% endblock pagination %}
|
||||
</div>
|
||||
{% endblock table-wrapper %}
|
||||
Reference in New Issue
Block a user