Make tag handling much more flexible
This commit is contained in:
parent
16c03bc19a
commit
ae489b1045
|
@ -1,67 +1,89 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load joinsep %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<script src="{% static 'js/chart.js' %}"></script>
|
<script src="{% static 'js/chart.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
function addTag(value) {
|
function setupTags() {
|
||||||
var inputTags = document.getElementById('tags');
|
var inputTags = document.getElementById('tags');
|
||||||
var btiInstance = inputTags.BulmaTagsInput();
|
new BulmaTagsInput(inputTags);
|
||||||
btiInstance.add(value);
|
|
||||||
}
|
|
||||||
function delTag(value) {
|
|
||||||
var inputTags = document.getElementById('tags');
|
|
||||||
var btiInstance = inputTags.BulmaTagsInput();
|
|
||||||
btiInstance.remove(value);
|
|
||||||
}
|
|
||||||
function toggleTag(field, value) {
|
|
||||||
var queryElement = document.getElementById('query');
|
|
||||||
var tagText = `${field}: ${value}`;
|
|
||||||
var present = true;
|
|
||||||
if (present == true) {
|
|
||||||
var toAppend = ` AND ${field}: "${value}"`;
|
|
||||||
var toRemove = `${field}: "${value}"`;
|
|
||||||
var tagText = `${field}: ${value}`;
|
|
||||||
} else {
|
|
||||||
var toAppend = ` AND NOT ${field}: "${value}"`;
|
|
||||||
var toRemove = `NOT ${field}: "${value}"`;
|
|
||||||
}
|
|
||||||
if (!queryElement.value.includes(toAppend) && !queryElement.value.includes(toRemove)) {
|
|
||||||
addTag(tagText);
|
|
||||||
} else {
|
|
||||||
delTag(tagText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function populateSearch(field, value, fromTag=false) {
|
|
||||||
var queryElement = document.getElementById('query');
|
|
||||||
var present = true;
|
|
||||||
if (present == true) {
|
|
||||||
var toAppend = ` AND ${field}: "${value}"`;
|
|
||||||
var toRemove = `${field}: "${value}"`;
|
|
||||||
var tagText = `${field}: ${value}`;
|
|
||||||
} else {
|
|
||||||
var toAppend = ` AND NOT ${field}: "${value}"`;
|
|
||||||
var toRemove = `NOT ${field}: "${value}"`;
|
|
||||||
}
|
|
||||||
if (!queryElement.value.includes(toAppend) && !queryElement.value.includes(toRemove)) {
|
|
||||||
|
|
||||||
if (fromTag) {
|
inputTags.BulmaTagsInput().on('before.add', function(item) {
|
||||||
queryElement.value+=toAppend;
|
if (item.includes(": ")) {
|
||||||
|
var spl = item.split(": ");
|
||||||
} else {
|
} else {
|
||||||
queryElement.value+=toAppend;
|
var spl = item.split(":");
|
||||||
}
|
}
|
||||||
|
var field = spl[0];
|
||||||
|
try {
|
||||||
|
var value = JSON.parse(spl[1]);
|
||||||
|
} catch {
|
||||||
|
var value = spl[1];
|
||||||
|
}
|
||||||
|
populateSearch(field, value);
|
||||||
|
return `${field}: ${value}`;
|
||||||
|
});
|
||||||
|
inputTags.BulmaTagsInput().on('after.remove', function(item) {
|
||||||
|
var spl = item.split(": ");
|
||||||
|
var field = spl[0];
|
||||||
|
try {
|
||||||
|
var value = JSON.parse(spl[1]);
|
||||||
|
} catch {
|
||||||
|
var value = spl[1].trim();
|
||||||
|
}
|
||||||
|
populateSearch(field, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function populateSearch(field, value) {
|
||||||
|
var queryElement = document.getElementById('query');
|
||||||
|
var present = true;
|
||||||
|
if (present == true) {
|
||||||
|
var combinations = [`${field}: "${value}"`,
|
||||||
|
`${field}: "${value}"`,
|
||||||
|
`${field}: ${value}`,
|
||||||
|
`${field}:${value}`,
|
||||||
|
`${field}:"${value}"`];
|
||||||
|
var toAppend = ` AND ${field}: "${value}"`;
|
||||||
|
// var toRemove = `${field}: "${value}"`;
|
||||||
|
// var tagText = `${field}: ${value}`;
|
||||||
} else {
|
} else {
|
||||||
if (fromTag) {
|
var combinations = [`NOT ${field}: "${value}"`,
|
||||||
queryElement.value = queryElement.value.replaceAll(toAppend, "");
|
`NOT ${field}: "${value}"`,
|
||||||
queryElement.value = queryElement.value.replaceAll(toRemove, "");
|
`NOT ${field}: ${value}`,
|
||||||
} else {
|
`NOT ${field}:${value}`,
|
||||||
}
|
`NOT ${field}:"${value}"`];
|
||||||
|
// var toAppend = ` AND NOT ${field}: "${value}"`;
|
||||||
|
// var toRemove = `NOT ${field}: "${value}"`;
|
||||||
}
|
}
|
||||||
|
var contains = combinations.some(elem => queryElement.value.includes(elem));
|
||||||
|
if (!contains) {
|
||||||
|
queryElement.value+=toAppend;
|
||||||
|
} else {
|
||||||
|
for (var index in combinations) {
|
||||||
|
combination = combinations[index];
|
||||||
|
queryElement.value = queryElement.value.replaceAll("AND "+combination, "");
|
||||||
|
queryElement.value = queryElement.value.replaceAll(combination, "");
|
||||||
|
}
|
||||||
|
// queryElement.value = queryElement.value.replaceAll(toAppend, "");
|
||||||
|
// queryElement.value = queryElement.value.replaceAll(toRemove, "");
|
||||||
|
|
||||||
|
}
|
||||||
|
// if (!queryElement.value.includes(toAppend) && !queryElement.value.includes(toRemove)) {
|
||||||
|
// queryElement.value+=toAppend;
|
||||||
|
// } else {
|
||||||
|
// queryElement.value = queryElement.value.replaceAll(toAppend, "");
|
||||||
|
// queryElement.value = queryElement.value.replaceAll(toRemove, "");
|
||||||
|
|
||||||
|
// }
|
||||||
if (field == "src") {
|
if (field == "src") {
|
||||||
document.getElementById("source").selectedIndex = 0;
|
document.getElementById("source").selectedIndex = 0;
|
||||||
}
|
}
|
||||||
if (queryElement.value.startsWith(" AND ")) {
|
if (queryElement.value.startsWith(" AND ")) {
|
||||||
queryElement.value = queryElement.value.replace(" AND ", "");
|
queryElement.value = queryElement.value.replace(" AND ", "");
|
||||||
}
|
}
|
||||||
|
if (queryElement.value.startsWith("AND ")) {
|
||||||
|
queryElement.value = queryElement.value.replace("AND ", "");
|
||||||
|
}
|
||||||
htmx.trigger("#search", "click");
|
htmx.trigger("#search", "click");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -339,38 +361,9 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<input id="tags" class="input" type="tags" placeholder="Add query" value="">
|
<input id="tags" class="input" type="tags" placeholder="Add query" value="{{ tags|joinsep:',' }}">
|
||||||
<script>
|
<script>
|
||||||
var inputTags = document.getElementById('tags');
|
setupTags();
|
||||||
new BulmaTagsInput(inputTags);
|
|
||||||
{% for tag in tags %}
|
|
||||||
inputTags.BulmaTagsInput().add("{{ tag|escapejs }}");
|
|
||||||
{% endfor %}
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
populateSearch(field, value, fromTag=true);
|
|
||||||
return `${field}: ${value}`;
|
|
||||||
});
|
|
||||||
inputTags.BulmaTagsInput().on('after.remove', function(item) {
|
|
||||||
var spl = item.split(": ");
|
|
||||||
var field = spl[0];
|
|
||||||
try {
|
|
||||||
var value = JSON.parse(spl[1]);
|
|
||||||
} catch {
|
|
||||||
var value = spl[1];
|
|
||||||
}
|
|
||||||
populateSearch(field, value, fromTag=true);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load index %}
|
{% load index %}
|
||||||
|
{% load joinsep %}
|
||||||
{% include 'partials/notify.html' %}
|
{% include 'partials/notify.html' %}
|
||||||
{% if results %}
|
{% if results %}
|
||||||
<div style="display: none" id="jsonData" data-json="{{ data }}">
|
<div style="display: none" id="jsonData" data-json="{{ data }}">
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
{% endif %}">
|
{% endif %}">
|
||||||
<td>
|
<td>
|
||||||
<a class="has-text-link is-underlined"
|
<a class="has-text-link is-underlined"
|
||||||
onclick="toggleTag('src', '{{ item.src|escapejs }}')">
|
onclick="populateSearch('src', '{{ item.src|escapejs }}')">
|
||||||
{% if item.src == 'irc' %}
|
{% if item.src == 'irc' %}
|
||||||
<span class="icon" data-tooltip="IRC">
|
<span class="icon" data-tooltip="IRC">
|
||||||
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
|
||||||
|
@ -77,7 +78,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="has-text-link is-underlined"
|
<a class="has-text-link is-underlined"
|
||||||
onclick="toggleTag('type', '{{ item.type|escapejs }}')">
|
onclick="populateSearch('type', '{{ item.type|escapejs }}')">
|
||||||
{% if item.type == 'msg' %}
|
{% if item.type == 'msg' %}
|
||||||
<span class="icon" data-tooltip="Message">
|
<span class="icon" data-tooltip="Message">
|
||||||
<i class="fa-solid fa-message"></i>
|
<i class="fa-solid fa-message"></i>
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
<td style="max-width: 10em" class="wrap">{{ item.msg }}</td>
|
<td style="max-width: 10em" class="wrap">{{ item.msg }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="has-text-link is-underlined"
|
<a class="has-text-link is-underlined"
|
||||||
onclick="toggleTag('host', '{{ item.host|escapejs }}')">
|
onclick="populateSearch('host', '{{ item.host|escapejs }}')">
|
||||||
{{ item.host }}
|
{{ item.host }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -143,7 +144,7 @@
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<a class="nowrap-child has-text-link is-underlined" onclick="toggleTag('nick', '{{ item.nick|escapejs }}')">
|
<a class="nowrap-child has-text-link is-underlined" onclick="populateSearch('nick', '{{ item.nick|escapejs }}')">
|
||||||
{{ item.nick }}
|
{{ item.nick }}
|
||||||
</a>
|
</a>
|
||||||
{% if item.num_chans is not None %}
|
{% if item.num_chans is not None %}
|
||||||
|
@ -171,7 +172,7 @@
|
||||||
<td>
|
<td>
|
||||||
<div class="nowrap-parent">
|
<div class="nowrap-parent">
|
||||||
<a class="nowrap-child has-text-link is-underlined"
|
<a class="nowrap-child has-text-link is-underlined"
|
||||||
onclick="toggleTag('channel', '{{ item.channel|escapejs }}')">
|
onclick="populateSearch('channel', '{{ item.channel|escapejs }}')">
|
||||||
{{ item.channel }}
|
{{ item.channel }}
|
||||||
</a>
|
</a>
|
||||||
{% if item.num_users is not None %}
|
{% if item.num_users is not None %}
|
||||||
|
@ -185,7 +186,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="has-text-link is-underlined"
|
<a class="has-text-link is-underlined"
|
||||||
onclick="toggleTag('net', '{{ item.net|escapejs }}')">
|
onclick="populateSearch('net', '{{ item.net|escapejs }}')">
|
||||||
{{ item.net }}
|
{{ item.net }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -196,3 +197,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{# Update the tags in case the user changed the query #}
|
||||||
|
{# Check for focus and refocus #}
|
||||||
|
<script>
|
||||||
|
var inputTags = document.getElementsByClassName('tags-input');
|
||||||
|
var inputBox = document.querySelector("[placeholder='Add query']");
|
||||||
|
var isFocused = (document.activeElement === inputBox);
|
||||||
|
inputTags[0].outerHTML = '<input id="tags" class="input" type="tags" placeholder="Add query" value="{{ tags|joinsep:',' }}">';
|
||||||
|
setupTags();
|
||||||
|
var inputBox = document.querySelector("[placeholder='Add query']");
|
||||||
|
if (isFocused) {
|
||||||
|
inputBox.focus();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
|
@ -72,7 +72,8 @@ def create_tags(query):
|
||||||
spl = query.split("AND")
|
spl = query.split("AND")
|
||||||
spl = [x.strip() for x in spl if ":" in x]
|
spl = [x.strip() for x in spl if ":" in x]
|
||||||
spl = [x.replace('"', "") for x in spl]
|
spl = [x.replace('"', "") for x in spl]
|
||||||
return spl
|
tags = [f"{tag}: {elem}" for tag, elem in [x.split(":") for x in spl]]
|
||||||
|
return tags
|
||||||
|
|
||||||
|
|
||||||
def drilldown_search(request):
|
def drilldown_search(request):
|
||||||
|
|
Loading…
Reference in New Issue