Reformat and add blacklisted directories to DjHTML

master
Mark Veidemanis 2 years ago
parent 5be02807e3
commit 958eb2b549
Signed by: m
GPG Key ID: 5ACFCEED46C0904F

@ -3,323 +3,323 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en-GB"> <html lang="en-GB">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pathogen - {{ request.path_info }}</title> <title>Pathogen - {{ request.path_info }}</title>
<link rel="shortcut icon" href="{% static 'favicon.ico' %}"> <link rel="shortcut icon" href="{% static 'favicon.ico' %}">
<link rel="manifest" href="{% static 'manifest.webmanifest' %}"> <link rel="manifest" href="{% static 'manifest.webmanifest' %}">
<link rel="stylesheet" href="{% static 'css/bulma.min.css' %}"> <link rel="stylesheet" href="{% static 'css/bulma.min.css' %}">
<link rel="stylesheet" href="{% static 'css/bulma-tooltip.min.css' %}"> <link rel="stylesheet" href="{% static 'css/bulma-tooltip.min.css' %}">
<link rel="stylesheet" href="https://site-assets.fontawesome.com/releases/v6.1.1/css/all.css"> <link rel="stylesheet" href="https://site-assets.fontawesome.com/releases/v6.1.1/css/all.css">
<link rel="stylesheet" href="{% static 'css/bulma-slider.min.css' %}"> <link rel="stylesheet" href="{% static 'css/bulma-slider.min.css' %}">
<link rel="stylesheet" href="{% static 'css/bulma-calendar.min.css' %}"> <link rel="stylesheet" href="{% static 'css/bulma-calendar.min.css' %}">
<link rel="stylesheet" href="{% static 'css/bulma-tagsinput.min.css' %}"> <link rel="stylesheet" href="{% static 'css/bulma-tagsinput.min.css' %}">
<link rel="stylesheet" href="{% static 'css/bulma-switch.min.css' %}"> <link rel="stylesheet" href="{% static 'css/bulma-switch.min.css' %}">
<link rel="stylesheet" href="{% static 'css/gridstack.min.css' %}"> <link rel="stylesheet" href="{% static 'css/gridstack.min.css' %}">
<script src="{% static 'js/bulma-calendar.min.js' %}" integrity="sha384-DThNif0xGXbopX7+PE+UabkuClfI/zELNhaVqoGLutaWB76dyMw0vIQBGmUxSfVQ" crossorigin="anonymous"></script> <script src="{% static 'js/bulma-calendar.min.js' %}" integrity="sha384-DThNif0xGXbopX7+PE+UabkuClfI/zELNhaVqoGLutaWB76dyMw0vIQBGmUxSfVQ" crossorigin="anonymous"></script>
<script src="{% static 'js/bulma-slider.min.js' %}" integrity="sha384-wbyps8iLG8QzJE02viYc/27BtT5HSa11+b5V7QPR1/huVuA8f4LRTNGc82qAIeIZ" crossorigin="anonymous"></script> <script src="{% static 'js/bulma-slider.min.js' %}" integrity="sha384-wbyps8iLG8QzJE02viYc/27BtT5HSa11+b5V7QPR1/huVuA8f4LRTNGc82qAIeIZ" crossorigin="anonymous"></script>
<script src="{% static 'js/htmx.min.js' %}" integrity="sha384-cZuAZ+ZbwkNRnrKi05G/fjBX+azI9DNOkNYysZ0I/X5ZFgsmMiBXgDZof30F5ofc" crossorigin="anonymous"></script> <script src="{% static 'js/htmx.min.js' %}" integrity="sha384-cZuAZ+ZbwkNRnrKi05G/fjBX+azI9DNOkNYysZ0I/X5ZFgsmMiBXgDZof30F5ofc" crossorigin="anonymous"></script>
<script defer src="{% static 'js/remove-me.js' %}" integrity="sha384-6fHcFNoQ8QEI3ZDgw9Z/A6Brk64gF7AnFbLgdrumo8/kBbsKQ/wo7wPegj5WkzuG" crossorigin="anonymous"></script> <script defer src="{% static 'js/remove-me.js' %}" integrity="sha384-6fHcFNoQ8QEI3ZDgw9Z/A6Brk64gF7AnFbLgdrumo8/kBbsKQ/wo7wPegj5WkzuG" crossorigin="anonymous"></script>
<script defer src="{% static 'js/hyperscript.min.js' %}" integrity="sha384-6GYN8BDHOJkkru6zcpGOUa//1mn+5iZ/MyT6mq34WFIpuOeLF52kSi721q0SsYF9" crossorigin="anonymous"></script> <script defer src="{% static 'js/hyperscript.min.js' %}" integrity="sha384-6GYN8BDHOJkkru6zcpGOUa//1mn+5iZ/MyT6mq34WFIpuOeLF52kSi721q0SsYF9" crossorigin="anonymous"></script>
<script src="{% static 'js/bulma-tagsinput.min.js' %}"></script> <script src="{% static 'js/bulma-tagsinput.min.js' %}"></script>
<script src="{% static 'js/jquery.min.js' %}"></script> <script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/gridstack-all.js' %}"></script> <script src="{% static 'js/gridstack-all.js' %}"></script>
<script defer src="{% static 'js/magnet.min.js' %}"></script> <script defer src="{% static 'js/magnet.min.js' %}"></script>
<script> <script>
document.addEventListener("restore-scroll", function(event) { document.addEventListener("restore-scroll", function(event) {
var scrollpos = localStorage.getItem('scrollpos'); var scrollpos = localStorage.getItem('scrollpos');
if (scrollpos) { if (scrollpos) {
window.scrollTo(0, scrollpos) window.scrollTo(0, scrollpos)
}; };
}); });
document.addEventListener("htmx:beforeSwap", function(event) { document.addEventListener("htmx:beforeSwap", function(event) {
localStorage.setItem('scrollpos', window.scrollY); localStorage.setItem('scrollpos', window.scrollY);
}); });
</script> </script>
<script> <script>
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements // Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0); const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them // Add a click event on each of them
$navbarBurgers.forEach( el => { $navbarBurgers.forEach( el => {
el.addEventListener('click', () => { el.addEventListener('click', () => {
// Get the target from the "data-target" attribute // Get the target from the "data-target" attribute
const target = el.dataset.target; const target = el.dataset.target;
const $target = document.getElementById(target); const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu" // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active'); el.classList.toggle('is-active');
$target.classList.toggle('is-active'); $target.classList.toggle('is-active');
}); });
}); });
}); });
</script> </script>
<style> <style>
.icon { border-bottom: 0px !important;} .icon { border-bottom: 0px !important;}
.wrap { .wrap {
/* white-space: pre-wrap; /* white-space: pre-wrap;
white-space: -moz-pre-wrap; white-space: -moz-pre-wrap;
white-space: -pre-wrap; white-space: -pre-wrap;
white-space: -o-pre-wrap; */ white-space: -o-pre-wrap; */
word-wrap: break-word; word-wrap: break-word;
} }
.nowrap-parent { .nowrap-parent {
white-space: nowrap; white-space: nowrap;
} }
.nowrap-child { .nowrap-child {
display: inline-block; display: inline-block;
} }
.slider-output { .slider-output {
width: 4rem !important; width: 4rem !important;
} }
.htmx-indicator{ .htmx-indicator{
opacity:0; opacity:0;
transition: opacity 500ms ease-in; transition: opacity 500ms ease-in;
} }
.htmx-request .htmx-indicator{ .htmx-request .htmx-indicator{
opacity:1 opacity:1
} }
.htmx-request.htmx-indicator{ .htmx-request.htmx-indicator{
opacity:1 opacity:1
} }
.dropdown-content { .dropdown-content {
height: 20em; height: 20em;
overflow: auto; overflow: auto;
} }
table.relays-table tr:nth-of-type(2n) td { table.relays-table tr:nth-of-type(2n) td {
border-bottom: 3px solid grey; border-bottom: 3px solid grey;
} }
.tooltiptext { .tooltiptext {
visibility: hidden; visibility: hidden;
background-color: black; background-color: black;
color: #fff; color: #fff;
text-align: center; text-align: center;
padding: 5px 0; padding: 5px 0;
border-radius: 6px; border-radius: 6px;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
} }
.rounded-tooltip:hover .tooltiptext { .rounded-tooltip:hover .tooltiptext {
visibility: visible; visibility: visible;
} }
#sentiment-container { #sentiment-container {
position: fixed; position: fixed;
top: 0; top: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
height: 100vh; height: 100vh;
width: 100vw; width: 100vw;
z-index: -2; z-index: -2;
} }
.table { .table {
background: transparent !important; background: transparent !important;
} }
tr { tr {
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
} }
tr:hover { tr:hover {
cursor:pointer; cursor:pointer;
background-color:rgba(221, 224, 255, 0.3) !important; background-color:rgba(221, 224, 255, 0.3) !important;
} }
a.panel-block { a.panel-block {
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
} }
a.panel-block:hover { a.panel-block:hover {
cursor:pointer; cursor:pointer;
background-color:rgba(221, 224, 255, 0.3) !important; background-color:rgba(221, 224, 255, 0.3) !important;
} }
.panel, .box, .modal { .panel, .box, .modal {
background-color:rgba(250, 250, 250, 0.5) !important; background-color:rgba(250, 250, 250, 0.5) !important;
} }
.modal, .modal.box{ .modal, .modal.box{
background-color:rgba(210, 210, 210, 0.9) !important; background-color:rgba(210, 210, 210, 0.9) !important;
} }
.modal-background{ .modal-background{
background-color:rgba(255, 255, 255, 0.3) !important; background-color:rgba(255, 255, 255, 0.3) !important;
} }
.has-background-grey-lighter{ .has-background-grey-lighter{
background-color:rgba(219, 219, 219, 0.5) !important; background-color:rgba(219, 219, 219, 0.5) !important;
} }
.navbar { .navbar {
background-color:rgba(0, 0, 0, 0.03) !important; background-color:rgba(0, 0, 0, 0.03) !important;
} }
.grid-stack-item-content { .grid-stack-item-content {
display: flex !important; display: flex !important;
flex-direction: column !important; flex-direction: column !important;
overflow-x: hidden !important; overflow-x: hidden !important;
overflow-y: hidden !important; overflow-y: hidden !important;
} }
.panel { .panel {
display: flex !important; display: flex !important;
flex-direction: column !important; flex-direction: column !important;
overflow: hidden; overflow: hidden;
} }
.panel-block { .panel-block {
overflow-y:scroll; overflow-y:scroll;
overflow-x:scroll; overflow-x:scroll;
min-height: 90%; min-height: 90%;
display: block; display: block;
} }
.floating-window { .floating-window {
/* background-color:rgba(210, 210, 210, 0.6) !important; */ /* background-color:rgba(210, 210, 210, 0.6) !important; */
display: flex !important; display: flex !important;
flex-direction: column !important; flex-direction: column !important;
overflow-x: hidden !important; overflow-x: hidden !important;
overflow-y: hidden !important; overflow-y: hidden !important;
max-height: 300px; max-height: 300px;
z-index: 9000; z-index: 9000;
position: absolute; position: absolute;
top: 50px; top: 50px;
left: 50px; left: 50px;
} }
.floating-window .panel { .floating-window .panel {
background-color:rgba(250, 250, 250, 0.8) !important; background-color:rgba(250, 250, 250, 0.8) !important;
} }
.float-right { .float-right {
float: right; float: right;
padding-right: 5px; padding-right: 5px;
padding-left: 5px; padding-left: 5px;
} }
.grid-stack-item:hover .ui-resizable-handle { .grid-stack-item:hover .ui-resizable-handle {
display: block !important; display: block !important;
} }
</style> </style>
</head> </head>
<body> <body>
<nav class="navbar" role="navigation" aria-label="main navigation"> <nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand"> <div class="navbar-brand">
<a class="navbar-item" href="{% url 'home' %}"> <a class="navbar-item" href="{% url 'home' %}">
<img src="{% static 'logo.svg' %}" width="112" height="28" alt="logo"> <img src="{% static 'logo.svg' %}" width="112" height="28" alt="logo">
</a>
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="bar">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="bar" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item" href="{% url 'home' %}">
Search
</a>
{% if user.is_authenticated %}
<a class="navbar-item" href="{% url 'billing' %}">
Billing
</a>
{% endif %}
{% if user.is_superuser %}
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
Threshold
</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="{% url 'threshold_irc_overview' %}">
IRC
</a> </a>
<a class="navbar-item" href="#">
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="bar"> Discord
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a> </a>
</div>
</div> </div>
{% endif %}
{% if perms.core.use_insights %}
<a class="navbar-item" href="{% url 'insights' %}">
Insights
</a>
{% endif %}
<a class="navbar-item add-button">
Install
</a>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
{% if not user.is_authenticated %}
<a class="button is-info" href="{% url 'signup' %}">
<strong>Sign up</strong>
</a>
<a class="button is-light" href="{% url 'login' %}">
Log in
</a>
{% endif %}
{% if user.is_authenticated %}
<a class="button is-dark" href="{% url 'logout' %}">Logout</a>
{% endif %}
<div id="bar" class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item" href="{% url 'home' %}">
Search
</a>
{% if user.is_authenticated %}
<a class="navbar-item" href="{% url 'billing' %}">
Billing
</a>
{% endif %}
{% if user.is_superuser %}
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
Threshold
</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="{% url 'threshold_irc_overview' %}">
IRC
</a>
<a class="navbar-item" href="#">
Discord
</a>
</div>
</div>
{% endif %}
{% if perms.core.use_insights %}
<a class="navbar-item" href="{% url 'insights' %}">
Insights
</a>
{% endif %}
<a class="navbar-item add-button">
Install
</a>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
{% if not user.is_authenticated %}
<a class="button is-info" href="{% url 'signup' %}">
<strong>Sign up</strong>
</a>
<a class="button is-light" href="{% url 'login' %}">
Log in
</a>
{% endif %}
{% if user.is_authenticated %}
<a class="button is-dark" href="{% url 'logout' %}">Logout</a>
{% endif %}
</div>
</div>
</div>
</div> </div>
</nav> </div>
<script> </div>
let deferredPrompt; </div>
const addBtn = document.querySelector('.add-button'); </nav>
addBtn.style.display = 'none'; <script>
window.addEventListener('beforeinstallprompt', (e) => { let deferredPrompt;
// Prevent Chrome 67 and earlier from automatically showing the prompt const addBtn = document.querySelector('.add-button');
e.preventDefault(); addBtn.style.display = 'none';
// Stash the event so it can be triggered later. window.addEventListener('beforeinstallprompt', (e) => {
deferredPrompt = e; // Prevent Chrome 67 and earlier from automatically showing the prompt
// Update UI to notify the user they can add to home screen e.preventDefault();
addBtn.style.display = 'block'; // Stash the event so it can be triggered later.
deferredPrompt = e;
addBtn.addEventListener('click', (e) => { // Update UI to notify the user they can add to home screen
// hide our user interface that shows our A2HS button addBtn.style.display = 'block';
addBtn.style.display = 'none';
// Show the prompt addBtn.addEventListener('click', (e) => {
deferredPrompt.prompt(); // hide our user interface that shows our A2HS button
// Wait for the user to respond to the prompt addBtn.style.display = 'none';
deferredPrompt.userChoice.then((choiceResult) => { // Show the prompt
if (choiceResult.outcome === 'accepted') { deferredPrompt.prompt();
console.log('User accepted the A2HS prompt'); // Wait for the user to respond to the prompt
} else { deferredPrompt.userChoice.then((choiceResult) => {
console.log('User dismissed the A2HS prompt'); if (choiceResult.outcome === 'accepted') {
} console.log('User accepted the A2HS prompt');
deferredPrompt = null; } else {
}); console.log('User dismissed the A2HS prompt');
}); }
}); deferredPrompt = null;
</script> });
{% block outer_content %} });
});
</script>
{% block outer_content %}
{% endblock %}
<section class="section">
<div class="container">
{% block content %}
{% endblock %} {% endblock %}
<section class="section"> </div>
<div class="container"> </section>
{% block content %} </body>
{% endblock %}
</div>
</section>
</body>
</html> </html>

@ -1,46 +1,46 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<article class="panel is-info"> <article class="panel is-info">
<p class="panel-heading"> <p class="panel-heading">
User information User information
</p> </p>
<a class="panel-block is-active"> <a class="panel-block is-active">
<span class="panel-icon"> <span class="panel-icon">
<i class="fas fa-id-card" aria-hidden="true"></i> <i class="fas fa-id-card" aria-hidden="true"></i>
</span> </span>
<span class="tag is-info">{{ user.first_name }} {{ user.last_name }}</span> <span class="tag is-info">{{ user.first_name }} {{ user.last_name }}</span>
</a> </a>
<a class="panel-block"> <a class="panel-block">
<span class="panel-icon"> <span class="panel-icon">
<i class="fas fa-binary" aria-hidden="true"></i> <i class="fas fa-binary" aria-hidden="true"></i>
</span> </span>
{% for plan in user.plans.all %} {% for plan in user.plans.all %}
<span class="tag is-info">{{ plan.name }}</span> <span class="tag is-info">{{ plan.name }}</span>
{% endfor %} {% endfor %}
</a> </a>
<a class="panel-block"> <a class="panel-block">
<span class="panel-icon"> <span class="panel-icon">
<i class="fas fa-credit-card" aria-hidden="true"></i> <i class="fas fa-credit-card" aria-hidden="true"></i>
</span> </span>
<span class="tag">{{ user.last_payment }}</span> <span class="tag">{{ user.last_payment }}</span>
</a> </a>
<a class="panel-block" href="{% url 'portal' %}"> <a class="panel-block" href="{% url 'portal' %}">
<span class="panel-icon"> <span class="panel-icon">
<i class="fa-brands fa-stripe-s" aria-hidden="true"></i> <i class="fa-brands fa-stripe-s" aria-hidden="true"></i>
</span> </span>
Subscription management Subscription management
</a> </a>
</article> </article>
<div class="box"> <div class="box">
<h1 class="subtitle"> <h1 class="subtitle">
This product is currently free. You may cancel any plans above. This product is currently free. You may cancel any plans above.
</h1> </h1>
</div> </div>
<div class="box"> <div class="box">
<h1 class="subtitle"> <h1 class="subtitle">
You cannot pay for access to the raw data. It is hashed to preserve privacy. You cannot pay for access to the raw data. It is hashed to preserve privacy.
</h1> </h1>
</div> </div>
{# {% include "partials/product-list.html" %} #} {# {% include "partials/product-list.html" %} #}
{% endblock %} {% endblock %}

@ -2,8 +2,8 @@
{% block content %} {% block content %}
<section> <section>
<p>Forgot to add something to your cart? Shop around then come back to pay!</p> <p>Forgot to add something to your cart? Shop around then come back to pay!</p>
</section> </section>
{% endblock %} {% endblock %}

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<h1 class="title">Access denied</h1> <h1 class="title">Access denied</h1>
<h2 class="subtitle">Sorry, you do not have the necessary permissions to view this page.</h2> <h2 class="subtitle">Sorry, you do not have the necessary permissions to view this page.</h2>
{% endblock %} {% endblock %}

@ -2,47 +2,47 @@
{% load static %} {% load static %}
{% block content %} {% block content %}
<div class="block"> <div class="block">
{% for block in blocks %} {% for block in blocks %}
{% if block.title is not None %} {% if block.title is not None %}
<h1 class="title">{{ block.title }}</h1> <h1 class="title">{{ block.title }}</h1>
{% endif %} {% endif %}
<div class="box"> <div class="box">
<div class="columns"> <div class="columns">
{% if block.column1 is not None %} {% if block.column1 is not None %}
<div class="column"> <div class="column">
{{ block.column1 }} {{ block.column1 }}
</div>
{% endif %}
{% if block.column2 is not None %}
<div class="column">
{{ block.column2 }}
</div>
{% endif %}
{% if block.column3 is not None %}
<div class="column">
{{ block.column3 }}
</div>
{% endif %}
</div>
<div class="columns">
{% if block.image1 is not None %}
<div class="column">
<img src="{% static block.image1 %}">
</div>
{% endif %}
{% if block.image2 is not None %}
<div class="column">
<img src="{% static block.image2 %}">
</div>
{% endif %}
{% if block.image3 is not None %}
<div class="column">
<img src="{% static block.image3 %}">
</div>
{% endif %}
</div>
</div> </div>
{% endfor %} {% endif %}
</div> {% if block.column2 is not None %}
<div class="column">
{{ block.column2 }}
</div>
{% endif %}
{% if block.column3 is not None %}
<div class="column">
{{ block.column3 }}
</div>
{% endif %}
</div>
<div class="columns">
{% if block.image1 is not None %}
<div class="column">
<img src="{% static block.image1 %}">
</div>
{% endif %}
{% if block.image2 is not None %}
<div class="column">
<img src="{% static block.image2 %}">
</div>
{% endif %}
{% if block.image3 is not None %}
<div class="column">
<img src="{% static block.image3 %}">
</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% endblock %} {% endblock %}

@ -1,81 +1,81 @@
<div id="actions"> <div id="actions">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
<div class="buttons"> <div class="buttons">
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-put="{% url 'threshold_irc_network_actions_add_relay' net %}"
hx-trigger="click"
hx-target="#actions"
hx-swap="outerHTML"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-plus"></i>
</span>
<span>Relay</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_actions_auto' net %}"
hx-trigger="click"
hx-target="#actions"
hx-swap="outerHTML"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-wrench"></i>
</span>
<span>Auto</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_actions_registration_net' net %}"
hx-trigger="click"
hx-target="#modals-here"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-list"></i>
</span>
<span>Registration</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_list' net %}"
hx-trigger="click"
hx-target="#actions"
hx-swap="outerHTML"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-list"></i>
</span>
<span>List</span>
</span>
</button>
</div>
<form method="POST">
<div class="field has-addons">
<div class="control is-expanded has-icons-left">
<input class="input" name="num" type="text" placeholder="Relay number">
<span class="icon is-small is-left">
<i class="fa-brands fa-unity"></i>
</span>
</div>
<div class="control">
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-put="{% url 'threshold_irc_network_actions_add_relay' net %}" class="button is-info is-fullwidth"
hx-trigger="click" hx-put="{% url 'threshold_irc_network_actions_add_relay' net %}"
hx-target="#actions" hx-trigger="click"
hx-swap="outerHTML" hx-target="#actions"
class="button is-info"> hx-swap="outerHTML">
<span class="icon-text"> Add
<span class="icon">
<i class="fa-solid fa-plus"></i>
</span>
<span>Relay</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_actions_auto' net %}"
hx-trigger="click"
hx-target="#actions"
hx-swap="outerHTML"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-wrench"></i>
</span>
<span>Auto</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_actions_registration_net' net %}"
hx-trigger="click"
hx-target="#modals-here"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-list"></i>
</span>
<span>Registration</span>
</span>
</button>
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_list' net %}"
hx-trigger="click"
hx-target="#actions"
hx-swap="outerHTML"
class="button is-info">
<span class="icon-text">
<span class="icon">
<i class="fa-solid fa-list"></i>
</span>
<span>List</span>
</span>
</button> </button>
</div>
</div> </div>
<form method="POST"> </form>
<div class="field has-addons">
<div class="control is-expanded has-icons-left">
<input class="input" name="num" type="text" placeholder="Relay number">
<span class="icon is-small is-left">
<i class="fa-brands fa-unity"></i>
</span>
</div>
<div class="control">
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
class="button is-info is-fullwidth"
hx-put="{% url 'threshold_irc_network_actions_add_relay' net %}"
hx-trigger="click"
hx-target="#actions"
hx-swap="outerHTML">
Add
</button>
</div>
</div>
</form>
</div> </div>

@ -1,44 +1,44 @@
<div id="channels"> <div id="channels">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
{% if channels is not None %} {% if channels is not None %}
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>channel</th> <th>channel</th>
<th>num</th> <th>num</th>
<th>actions</th> <th>actions</th>
</thead> </thead>
<tbody> <tbody>
{% for channel in channels %} {% for channel in channels %}
<tr> <tr>
<td> <td>
{{ channel.name }} {{ channel.name }}
<span class="tag"> <span class="tag">
{{ channel.users }} {{ channel.users }}
</span> </span>
</td> </td>
<td> <td>
{{ channel.num }} {{ channel.num }}
</td> </td>
<td> <td>
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}", "Content-Type": "application/json"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}", "Content-Type": "application/json"}'
hx-delete="{% url 'threshold_irc_network_channel_json' net %}" hx-delete="{% url 'threshold_irc_network_channel_json' net %}"
hx-vals='{"channel": "{{ channel.name }}"}' hx-vals='{"channel": "{{ channel.name }}"}'
hx-target="#channels" hx-target="#channels"
hx-swap="outerHTML" hx-swap="outerHTML"
class="button is-danger is-small"> class="button is-danger is-small">
<span class="icon" data-tooltip="Part"> <span class="icon" data-tooltip="Part">
<i class="fa-solid fa-xmark" aria-hidden="true"></i> <i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span> </span>
</button> </button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>

@ -1,77 +1,77 @@
<form <form
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_edit' net %}" hx-post="{% url 'threshold_irc_network_edit' net %}"
hx-target="this" hx-target="this"
hx-swap="outerHTML"> hx-swap="outerHTML">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>attribute</th> <th>attribute</th>
<th>value</th> <th>value</th>
</thead> </thead>
<tbody> <tbody>
{% for key, item in network.items %} {% for key, item in network.items %}
<tr> <tr>
<th>{{ key }}</th> <th>{{ key }}</th>
<td> <td>
<div class="field"> <div class="field">
{% if key == 'auth' %} {% if key == 'auth' %}
<div class="select"> <div class="select">
<select name="{{ key }}"> <select name="{{ key }}">
{% if item == 'sasl' %} {% if item == 'sasl' %}
<option selected>sasl</option> <option selected>sasl</option>
{% else %} {% else %}
<option>sasl</option> <option>sasl</option>
{% endif %} {% endif %}
{% if item == 'ns' %} {% if item == 'ns' %}
<option selected>ns</option> <option selected>ns</option>
{% else %} {% else %}
<option>ns</option> <option>ns</option>
{% endif %} {% endif %}
{% if item == 'none' %} {% if item == 'none' %}
<option selected>none</option> <option selected>none</option>
{% else %} {% else %}
<option>none</option> <option>none</option>
{% endif %} {% endif %}
</select> </select>
</div> </div>
{% elif key == 'security' %} {% elif key == 'security' %}
<div class="select"> <div class="select">
<select name="{{ key }}"> <select name="{{ key }}">
{% if item == 'ssl' %} {% if item == 'ssl' %}
<option selected>ssl</option> <option selected>ssl</option>
{% else %} {% else %}
<option>ssl</option> <option>ssl</option>
{% endif %} {% endif %}
{% if item == 'plain' %} {% if item == 'plain' %}
<option selected>plain</option> <option selected>plain</option>
{% else %} {% else %}
<option>plain</option> <option>plain</option>
{% endif %} {% endif %}
</select> </select>
</div> </div>
{% else %} {% else %}
<input class="input" type="text" name="{{ key }}" value="{{ item }}"> <input class="input" type="text" name="{{ key }}" value="{{ item }}">
{% endif %} {% endif %}
</div> </div>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<button <button
type="button" type="button"
class="button is-light" class="button is-light"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_info' net %}"> hx-get="{% url 'threshold_irc_network_info' net %}">
Cancel Cancel
</button> </button>
<button type="submit" class="button is-info">Submit</button> <button type="submit" class="button is-info">Submit</button>
<script>activateButtons();</script> <script>activateButtons();</script>
</div> </div>
</form> </form>

@ -1,61 +1,61 @@
<div id="info"> <div id="info">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
{% if network is not None %} {% if network is not None %}
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>attribute</th> <th>attribute</th>
<th>value</th> <th>value</th>
</thead> </thead>
<tbody> <tbody>
{% for key, item in network.items %} {% for key, item in network.items %}
<tr> <tr>
<th>{{ key }}</th> <th>{{ key }}</th>
<td> <td>
{% if key == 'security' %} {% if key == 'security' %}
{% if item == 'none' %} {% if item == 'none' %}
<span class="icon"> <span class="icon">
<i class="fa-solid fa-lock-open" aria-hidden="true"></i> <i class="fa-solid fa-lock-open" aria-hidden="true"></i>
</span> </span>
{% elif item == 'ssl' %} {% elif item == 'ssl' %}
<span class="icon"> <span class="icon">
<i class="fa-solid fa-lock" aria-hidden="true"></i> <i class="fa-solid fa-lock" aria-hidden="true"></i>
</span> </span>
{% endif %} {% endif %}
{% elif key == 'relays' %} {% elif key == 'relays' %}
<span class="icon"> <span class="icon">
<i class="fa-brands fa-unity"></i> <i class="fa-brands fa-unity"></i>
</span> </span>
{% elif key == 'channels' %} {% elif key == 'channels' %}
<span class="icon"> <span class="icon">
<i class="fa-solid fa-hashtag"></i> <i class="fa-solid fa-hashtag"></i>
</span> </span>
{% elif key == 'records' %} {% elif key == 'records' %}
<span class="icon"> <span class="icon">
<i class="fa-solid fa-album"></i> <i class="fa-solid fa-album"></i>
</span> </span>
{% elif key == 'host' %} {% elif key == 'host' %}
<span class="icon"> <span class="icon">
<i class="fa-solid fa-router"></i> <i class="fa-solid fa-router"></i>
</span> </span>
{% endif %} {% endif %}
{% if item is not None %} {% if item is not None %}
{{ item }} {{ item }}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div hx-target="#info" hx-swap="outerHTML"> <div hx-target="#info" hx-swap="outerHTML">
<button hx-get="{% url 'threshold_irc_network_info_edit' network.net %}" class="button is-info is-fullwidth"> <button hx-get="{% url 'threshold_irc_network_info_edit' network.net %}" class="button is-info is-fullwidth">
<span class="icon" data-tooltip="Edit"> <span class="icon" data-tooltip="Edit">
<i class="fa-solid fa-pencil" aria-hidden="true"></i> <i class="fa-solid fa-pencil" aria-hidden="true"></i>
</span> </span>
</button> </button>
</div>
</div>
</div> </div>
{% endif %} </div>
</div>
{% endif %}
</div> </div>

@ -3,91 +3,91 @@
<script src="{% static 'modal.js' %}"></script> <script src="{% static 'modal.js' %}"></script>
<div id="modal" class="modal is-active is-clipped"> <div id="modal" class="modal is-active is-clipped">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content">
<div class="box"> <div class="box">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
<h4 class="subtitle is-4">Registration</h4> <h4 class="subtitle is-4">Registration</h4>
<div class="buttons"> <div class="buttons">
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_actions_registration_auth' %}" hx-post="{% url 'threshold_irc_actions_registration_auth' %}"
hx-vals='{"net": "{{ net }}", "func": "recheckauth"}' hx-vals='{"net": "{{ net }}", "func": "recheckauth"}'
hx-trigger="click" hx-trigger="click"
hx-target="#modals-here" hx-target="#modals-here"
class="button is-info"> class="button is-info">
<span class="icon-text"> <span class="icon-text">
<span class="icon"> <span class="icon">
<i class="fa-solid fa-wrench"></i> <i class="fa-solid fa-wrench"></i>
</span> </span>
<span>Check auth</span> <span>Check auth</span>
</span> </span>
</button> </button>
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_actions_registration_auth' %}" hx-post="{% url 'threshold_irc_actions_registration_auth' %}"
hx-vals='{"net": "{{ net }}", "func": "resetauth"}' hx-vals='{"net": "{{ net }}", "func": "resetauth"}'
hx-trigger="click" hx-trigger="click"
hx-target="#modals-here" hx-target="#modals-here"
class="button is-info"> class="button is-info">
<span class="icon-text"> <span class="icon-text">
<span class="icon"> <span class="icon">
<i class="fa-solid fa-wrench"></i> <i class="fa-solid fa-wrench"></i>
</span> </span>
<span>Reset auth</span> <span>Reset auth</span>
</span> </span>
</button> </button>
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_actions_registration_auth' %}" hx-post="{% url 'threshold_irc_actions_registration_auth' %}"
hx-vals='{"net": "{{ net }}", "func": "register"}' hx-vals='{"net": "{{ net }}", "func": "register"}'
hx-trigger="click" hx-trigger="click"
hx-target="#modals-here" hx-target="#modals-here"
class="button is-info"> class="button is-info">
<span class="icon-text"> <span class="icon-text">
<span class="icon"> <span class="icon">
<i class="fa-solid fa-wrench"></i> <i class="fa-solid fa-wrench"></i>
</span> </span>
<span>Register</span> <span>Register</span>
</span> </span>
</button> </button>
</div> </div>
{% if unreg is not None %} {% if unreg is not None %}
<form <form
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-put="{% url 'threshold_irc_actions_registration_net' net %}" hx-put="{% url 'threshold_irc_actions_registration_net' net %}"
hx-target="#actions" hx-target="#actions"
hx-swap="outerHTML"> hx-swap="outerHTML">
{% for network, items in unreg.items %} {% for network, items in unreg.items %}
<h4 class="title is-4">{{ network }}</h4> <h4 class="title is-4">{{ network }}</h4>
{% if items is not False %} {% if items is not False %}
{% for nick, num in items %} {% for nick, num in items %}
<div class="field"> <div class="field">
<label class="label">{{ nick }}/{{ num }}</label> <label class="label">{{ nick }}/{{ num }}</label>
<div class="control"> <div class="control">
<input class="input" type="text" name="{{ network }}|{{ num }}" placeholder="Enter token"> <input class="input" type="text" name="{{ network }}|{{ num }}" placeholder="Enter token">
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
{% else %}
<p>Error getting information for {{ network }}.</p>
{% endif %}
{% endfor %}
<button
type="button"
class="button is-light modal-close-button">
Cancel
</button>
<button type="submit" class="button is-info modal-close-button">Submit</button>
{# <script>activateButtons();</script> #}
</form>
{% else %} {% else %}
<p>No unregistered relays.</p> <p>Error getting information for {{ network }}.</p>
{% endif %} {% endif %}
{% endfor %}
<button
type="button"
class="button is-light modal-close-button">
Cancel
</button>
<button type="submit" class="button is-info modal-close-button">Submit</button>
{# <script>activateButtons();</script> #}
</form>
{% else %}
<p>No unregistered relays.</p>
{% endif %}
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div> </div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
</div> </div>

@ -1,150 +1,150 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<script> <script>
document.addEventListener("restore-relay-scroll", function(event) { document.addEventListener("restore-relay-scroll", function(event) {
var modalContent = document.getElementsByClassName("relay_table_container")[0]; var modalContent = document.getElementsByClassName("relay_table_container")[0];
var maxScroll = modalContent.scrollHeight - modalContent.offsetHeight; var maxScroll = modalContent.scrollHeight - modalContent.offsetHeight;
var scrollpos = localStorage.getItem('scrollpos_relays_table'); var scrollpos = localStorage.getItem('scrollpos_relays_table');
if (scrollpos == 'BOTTOM') { if (scrollpos == 'BOTTOM') {
modalContent.scrollTop = maxScroll; modalContent.scrollTop = maxScroll;
} else if (scrollpos) { } else if (scrollpos) {
modalContent.scrollTop = scrollpos; modalContent.scrollTop = scrollpos;
}; };
}); });
document.addEventListener("htmx:beforeSwap", function(event) { document.addEventListener("htmx:beforeSwap", function(event) {
var modalContent = document.getElementsByClassName("relay_table_container")[0]; var modalContent = document.getElementsByClassName("relay_table_container")[0];
var scrollpos = modalContent.scrollTop; var scrollpos = modalContent.scrollTop;
if(modalContent.scrollTop === (modalContent.scrollHeight - modalContent.offsetHeight)) { if(modalContent.scrollTop === (modalContent.scrollHeight - modalContent.offsetHeight)) {
localStorage.setItem('scrollpos_relays_table', 'BOTTOM'); localStorage.setItem('scrollpos_relays_table', 'BOTTOM');
} else { } else {
localStorage.setItem('scrollpos_relays_table', scrollpos); localStorage.setItem('scrollpos_relays_table', scrollpos);
} }
}); });
</script> </script>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_info' net %}" hx-get="{% url 'threshold_irc_network_info' net %}"
hx-trigger="load, every 60s" hx-trigger="load, every 60s"
hx-target="#info" hx-target="#info"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_relays' net %}" hx-get="{% url 'threshold_irc_network_relays' net %}"
hx-trigger="load, every 60s" hx-trigger="load, every 60s"
hx-target="#relays" hx-target="#relays"
{# hx-swap="innerHTML" #} {# hx-swap="innerHTML" #}
> >
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_channels' net %}" hx-get="{% url 'threshold_irc_network_channels' net %}"
hx-trigger="load, every 60s" hx-trigger="load, every 60s"
hx-target="#channels" hx-target="#channels"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_actions' net %}" hx-get="{% url 'threshold_irc_network_actions' net %}"
hx-trigger="load" hx-trigger="load"
hx-target="#actions" hx-target="#actions"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_list' net %}" hx-get="{% url 'threshold_irc_network_list' net %}"
hx-trigger="load" hx-trigger="load"
hx-target="#stats" hx-target="#stats"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="box"> <div class="box">
<div id="info"> <div id="info">
</div>
</div>
</div> </div>
<!-- <div class="column"> </div>
</div>
<!-- <div class="column">
<div class="box"> <div class="box">
<div id="relays"> <div id="relays">
</div> </div>
</div> </div>
</div> --> </div> -->
<div class="column"> <div class="column">
<div class="box"> <div class="box">
<div> <div>
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container relay_table_container" id="relays"> <div class="table-container relay_table_container" id="relays">
</div>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
</div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="box"> <div class="box">
<div id="channels"> <div id="channels">
</div>
</div>
</div> </div>
<div class="column"> </div>
<div class="box"> </div>
<div id="stats"> <div class="column">
Stats here <div class="box">
</div> <div id="stats">
</div> Stats here
</div> </div>
</div>
</div> </div>
<div class="columns"> </div>
<div class="column"> <div class="columns">
{# This is the only thing included without HTMX because it isn't interactive #} <div class="column">
{# It needs no dynamic message element because it posts messages to chanels #} {# This is the only thing included without HTMX because it isn't interactive #}
<div class="box"> {# It needs no dynamic message element because it posts messages to chanels #}
<form method="POST"> <div class="box">
<div class="field has-addons"> <form method="POST">
<div class="control is-expanded has-icons-left"> <div class="field has-addons">
<input id="query" name="channel" class="input" type="text" placeholder="channel"> <div class="control is-expanded has-icons-left">
<span class="icon is-small is-left"> <input id="query" name="channel" class="input" type="text" placeholder="channel">
<i class="fa-solid fa-hashtag"></i> <span class="icon is-small is-left">
</span> <i class="fa-solid fa-hashtag"></i>
</div> </span>
<div class="control">
<button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
class="button is-info is-fullwidth"
hx-put="{% url 'threshold_irc_network_channel' net %}"
hx-trigger="click"
hx-target="#channels"
hx-swap="outerHTML">
Join
</button>
</div>
</div>
</form>
</div> </div>
</div> <div class="control">
<div class="column"> <button
<div class="box"> hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
<div id="actions"> class="button is-info is-fullwidth"
</div> hx-put="{% url 'threshold_irc_network_channel' net %}"
hx-trigger="click"
hx-target="#channels"
hx-swap="outerHTML">
Join
</button>
</div> </div>
</div> </div>
</form>
</div>
</div> </div>
<div id="modals-here"> <div class="column">
<div class="box">
<div id="actions">
</div>
</div>
</div> </div>
</div>
<div id="modals-here">
</div>
{% endblock %} {% endblock %}

@ -1,221 +1,221 @@
{% load index %} {% load index %}
<div class="table-container relay_table_container" id="relays"> <div class="table-container relay_table_container" id="relays">
<table class="table is-fullwidth is-hoverable relays-table"> <table class="table is-fullwidth is-hoverable relays-table">
<thead> <thead>
<th>id</th> <th>id</th>
<th> <th>
<span class="icon has-tooltip-bottom" data-tooltip="Registered"> <span class="icon has-tooltip-bottom" data-tooltip="Registered">
<i class="fa-solid fa-seal"></i> <i class="fa-solid fa-seal"></i>
</span>
</th>
<th>
<span class="icon has-tooltip-bottom" data-tooltip="Authenticated">
<i class="fa-solid fa-passport"></i>
</span>
</th>
<th>
<span class="icon has-tooltip-bottom" data-tooltip="Connected">
<i class="fa-solid fa-cloud-question"></i>
</span>
</th>
<th>
<span class="icon has-tooltip-bottom" data-tooltip="Enabled">
<i class="fa-solid fa-toggle-on"></i>
</span>
</th>
<th>
<span class="icon has-tooltip-bottom" data-tooltip="Channels">
<i class="fa-solid fa-hashtag"></i>
</span>
</th>
<th>
<span class="icon has-tooltip-bottom" data-tooltip="Chanlimit">
<i class="fa-solid fa-list-ol"></i>
</span>
</th>
<th>nick</th>
<th>
<span class="icon has-tooltip-bottom" data-tooltip="Actions">
<i class="fa-solid fa-wrench"></i>
</span>
</th>
</thead>
<tbody>
{% for relay in relays %}
<tr>
<td>{{ relay.id }}</td>
<td>
{% if relay.registered %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{% if relay.authed %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{% if relay.conn %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{% if relay.enabled %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{{ relay.chans }}
</td>
<td>{{ relay.limit }}</td>
<td>
{{ relay.nick }}
</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context' %}"
hx-vals='{"net": "{{ net }}",
"num": "{{ relay.id }}",
"source": "irc",
"channel": "*status",
"time": "None",
"date": "None",
"index": "int",
"type": "znc",
"mtype": "None",
"nick": "*status",
"dedup": "on"}'
hx-target="#modals-here"
hx-trigger="click"
class="button is-small has-background-info has-text-white">
<span class="icon has-tooltip-left" data-tooltip="ZNC context">
<i class="fa-brands fa-unity" aria-hidden="true"></i>
</span>
</a>
</td>
</tr>
<tr>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-delete="{% url 'threshold_irc_network_relay_del' relay|index:'net' relay|index:'id' %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-danger has-text-white">
<span class="icon" data-tooltip="Delete">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
</a>
</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_relay_provision' relay|index:'net' relay|index:'id' %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-info has-text-white">
<span class="icon" data-tooltip="Provision">
<i class="fa-solid fa-wrench" aria-hidden="true"></i>
</span>
</a>
</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_relay_auth' relay|index:'net' relay|index:'id' %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-info has-text-white">
<span class="icon" data-tooltip="Enable authentication">
<i class="fa-solid fa-passport" aria-hidden="true"></i>
</span>
</a>
</td>
<td></td>
<td>
{% if relay.enabled %}
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_relay_status' relay|index:'net' relay|index:'id' 0 %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-warning">
<span class="icon" data-tooltip="Disable">
<i class="fa-solid fa-wifi-slash" aria-hidden="true"></i>
</span> </span>
</th> </a>
<th> {% else %}
<span class="icon has-tooltip-bottom" data-tooltip="Authenticated"> <a
<i class="fa-solid fa-passport"></i> hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_relay_status' relay|index:'net' relay|index:'id' 1 %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-success has-text-white">
<span class="icon" data-tooltip="Enable">
<i class="fa-solid fa-wifi" aria-hidden="true"></i>
</span> </span>
</th> </a>
<th> {% endif %}
<span class="icon has-tooltip-bottom" data-tooltip="Connected"> </td>
<i class="fa-solid fa-cloud-question"></i> <td></td>
</span> <td></td>
</th> <td></td>
<th> <td>
<span class="icon has-tooltip-bottom" data-tooltip="Enabled"> <a
<i class="fa-solid fa-toggle-on"></i> hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
</span> hx-post="{% url 'modal_context' %}"
</th> hx-vals='{"net": "{{ net }}",
<th> "num": "{{ relay.id }}",
<span class="icon has-tooltip-bottom" data-tooltip="Channels"> "source": "irc",
<i class="fa-solid fa-hashtag"></i> "channel": "{{ sinst.entity }}",
</span> "time": "None",
</th> "date": "None",
<th> "index": "int",
<span class="icon has-tooltip-bottom" data-tooltip="Chanlimit"> "type": "auth",
<i class="fa-solid fa-list-ol"></i> "mtype": "None",
</span> "nick": "{{ sinst.entity }}",
</th> "dedup": "on"}'
<th>nick</th> hx-target="#modals-here"
<th> hx-trigger="click"
<span class="icon has-tooltip-bottom" data-tooltip="Actions"> class="button is-small has-background-info has-text-white">
<i class="fa-solid fa-wrench"></i> <span class="icon has-tooltip-left" data-tooltip="Auth ({{ sinst.entity }})">
</span> <i class="fa-solid fa-signature" aria-hidden="true"></i>
</th> </span>
</thead> </a>
<tbody> </td>
{% for relay in relays %} </tr>
<tr> {% endfor %}
<td>{{ relay.id }}</td> </tbody>
<td> </table>
{% if relay.registered %} <script>
<span class="icon has-text-success"> var modal_event = new Event('restore-relay-scroll');
<i class="fa-solid fa-check" aria-hidden="true"></i> document.dispatchEvent(modal_event);
</span> </script>
{% else %} {% include 'manage/threshold/partials/notify.html' %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{% if relay.authed %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{% if relay.conn %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{% if relay.enabled %}
<span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i>
</span>
{% else %}
<span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
{% endif %}
</td>
<td>
{{ relay.chans }}
</td>
<td>{{ relay.limit }}</td>
<td>
{{ relay.nick }}
</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context' %}"
hx-vals='{"net": "{{ net }}",
"num": "{{ relay.id }}",
"source": "irc",
"channel": "*status",
"time": "None",
"date": "None",
"index": "int",
"type": "znc",
"mtype": "None",
"nick": "*status",
"dedup": "on"}'
hx-target="#modals-here"
hx-trigger="click"
class="button is-small has-background-info has-text-white">
<span class="icon has-tooltip-left" data-tooltip="ZNC context">
<i class="fa-brands fa-unity" aria-hidden="true"></i>
</span>
</a>
</td>
</tr>
<tr>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-delete="{% url 'threshold_irc_network_relay_del' relay|index:'net' relay|index:'id' %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-danger has-text-white">
<span class="icon" data-tooltip="Delete">
<i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span>
</a>
</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_relay_provision' relay|index:'net' relay|index:'id' %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-info has-text-white">
<span class="icon" data-tooltip="Provision">
<i class="fa-solid fa-wrench" aria-hidden="true"></i>
</span>
</a>
</td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_network_relay_auth' relay|index:'net' relay|index:'id' %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-info has-text-white">
<span class="icon" data-tooltip="Enable authentication">
<i class="fa-solid fa-passport" aria-hidden="true"></i>
</span>
</a>
</td>
<td></td>
<td>
{% if relay.enabled %}
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_relay_status' relay|index:'net' relay|index:'id' 0 %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-warning">
<span class="icon" data-tooltip="Disable">
<i class="fa-solid fa-wifi-slash" aria-hidden="true"></i>
</span>
</a>
{% else %}
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_network_relay_status' relay|index:'net' relay|index:'id' 1 %}"
hx-target="#relays"
hx-swap="outerHTML"
class="button is-small has-background-success has-text-white">
<span class="icon" data-tooltip="Enable">
<i class="fa-solid fa-wifi" aria-hidden="true"></i>
</span>
</a>
{% endif %}
</td>
<td></td>
<td></td>
<td></td>
<td>
<a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context' %}"
hx-vals='{"net": "{{ net }}",
"num": "{{ relay.id }}",
"source": "irc",
"channel": "{{ sinst.entity }}",
"time": "None",
"date": "None",
"index": "int",
"type": "auth",
"mtype": "None",
"nick": "{{ sinst.entity }}",
"dedup": "on"}'
hx-target="#modals-here"
hx-trigger="click"
class="button is-small has-background-info has-text-white">
<span class="icon has-tooltip-left" data-tooltip="Auth ({{ sinst.entity }})">
<i class="fa-solid fa-signature" aria-hidden="true"></i>
</span>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
var modal_event = new Event('restore-relay-scroll');
document.dispatchEvent(modal_event);
</script>
{% include 'manage/threshold/partials/notify.html' %}
</div> </div>

@ -1,27 +1,27 @@
<div id="stats"> <div id="stats">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
{% if list is not None %} {% if list is not None %}
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>attribute</th> <th>attribute</th>
<th>value</th> <th>value</th>
</thead> </thead>
<tbody> <tbody>
{% for key, item in list.items %} {% for key, item in list.items %}
<tr> <tr>
<th>{{ key }}</th> <th>{{ key }}</th>
<td> <td>
{% if item is not None %} {% if item is not None %}
{{ item }} {{ item }}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>

@ -1,45 +1,45 @@
<div id="actions"> <div id="actions">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
<div class="buttons"> <div class="buttons">
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_actions_add-network' %}" hx-get="{% url 'threshold_irc_actions_add-network' %}"
hx-trigger="click" hx-trigger="click"
hx-target="#modals-here" hx-target="#modals-here"
class="button is-info"> class="button is-info">
<span class="icon-text"> <span class="icon-text">
<span class="icon"> <span class="icon">
<i class="fa-solid fa-plus"></i> <i class="fa-solid fa-plus"></i>
</span> </span>
<span>Network</span> <span>Network</span>
</span> </span>
</button> </button>
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="% url 'threshold_irc_actions_auto' %" hx-post="% url 'threshold_irc_actions_auto' %"
hx-trigger="click" hx-trigger="click"
hx-target="#actions" hx-target="#actions"
hx-swap="outerHTML" hx-swap="outerHTML"
class="button is-info"> class="button is-info">
<span class="icon-text"> <span class="icon-text">
<span class="icon"> <span class="icon">
<i class="fa-solid fa-wrench"></i> <i class="fa-solid fa-wrench"></i>
</span> </span>
<span>Auto</span> <span>Auto</span>
</span> </span>
</button> </button>
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_actions_registration' %}" hx-get="{% url 'threshold_irc_actions_registration' %}"
hx-trigger="click" hx-trigger="click"
hx-target="#modals-here" hx-target="#modals-here"
class="button is-info"> class="button is-info">
<span class="icon-text"> <span class="icon-text">
<span class="icon"> <span class="icon">
<i class="fa-solid fa-list"></i> <i class="fa-solid fa-list"></i>
</span> </span>
<span>Registration</span> <span>Registration</span>
</span> </span>
</button> </button>
</div> </div>
</div> </div>

@ -1,45 +1,45 @@
{% load joinsep %} {% load joinsep %}
<div id="aliases"> <div id="aliases">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
{% if aliases is not None %} {% if aliases is not None %}
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>num</th> <th>num</th>
<th>nick</th> <th>nick</th>
<th>realname</th> <th>realname</th>
<th>emails</th> <th>emails</th>
</thead> </thead>
<tbody> <tbody>
{% for alias in aliases %} {% for alias in aliases %}
<tr> <tr>
<td> <td>
{{ alias.num }} {{ alias.num }}
</td> </td>
<td> <td>
{{ alias.nick }} {{ alias.nick }}
</td> </td>
<td> <td>
{{ alias.realname }} {{ alias.realname }}
</td> </td>
<td> <td>
{{ alias.emails|joinsep:', ' }} {{ alias.emails|joinsep:', ' }}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<div hx-target="#modals-here"> <div hx-target="#modals-here">
<button hx-get="{% url 'threshold_irc_aliases_edit' %}" class="button is-info is-fullwidth"> <button hx-get="{% url 'threshold_irc_aliases_edit' %}" class="button is-info is-fullwidth">
<span class="icon" data-tooltip="Edit"> <span class="icon" data-tooltip="Edit">
<i class="fa-solid fa-pencil" aria-hidden="true"></i> <i class="fa-solid fa-pencil" aria-hidden="true"></i>
</span> </span>
</button> </button>
</div> </div>
{% endif %} {% endif %}
</div> </div>

@ -3,77 +3,77 @@
<script src="{% static 'modal.js' %}"></script> <script src="{% static 'modal.js' %}"></script>
<div id="modal" class="modal is-active is-clipped"> <div id="modal" class="modal is-active is-clipped">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content">
<div class="box"> <div class="box">
<h4 class="subtitle is-4">Add network</h4> <h4 class="subtitle is-4">Add network</h4>
<form <form
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-put="{% url 'threshold_irc_actions_add-network' %}" hx-put="{% url 'threshold_irc_actions_add-network' %}"
hx-target="#networks" hx-target="#networks"
hx-swap="outerHTML"> hx-swap="outerHTML">
<div class="field"> <div class="field">
<label class="label">Network name</label> <label class="label">Network name</label>
<div class="control"> <div class="control">
<input class="input" type="text" name="net" placeholder="freenode"> <input class="input" type="text" name="net" placeholder="freenode">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">Host</label> <label class="label">Host</label>
<div class="control"> <div class="control">
<input class="input" type="text" name="host" placeholder="irc.freenode.net"> <input class="input" type="text" name="host" placeholder="irc.freenode.net">
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label class="label">Port</label> <label class="label">Port</label>
<div class="control"> <div class="control">
<input class="input" type="text" name="port" placeholder="6697"> <input class="input" type="text" name="port" placeholder="6697">
</div> </div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label">Security</label>
<div class="control">
<div class="select">
<select name="security">
<option>ssl</option>
<option>plain</option>
</select>
</div> </div>
<div class="columns"> </div>
<div class="column"> </div>
<div class="field"> </div>
<label class="label">Security</label> <div class="column">
<div class="control"> <div class="field">
<div class="select"> <label class="label">Authentication</label>
<select name="security"> <div class="control">
<option>ssl</option> <div class="select">
<option>plain</option> <select name="auth">
</select> <option>sasl</option>
</div> <option>ns</option>
</div> <option>none</option>
</div> </select>
</div>
<div class="column">
<div class="field">
<label class="label">Authentication</label>
<div class="control">
<div class="select">
<select name="auth">
<option>sasl</option>
<option>ns</option>
<option>none</option>
</select>
</div>
</div>
</div>
</div>
</div> </div>
<button </div>
type="button" </div>
class="button is-light modal-close-button"> </div>
Cancel
</button>
<button type="submit" class="button is-info modal-close-button">Submit</button>
{# <script>activateButtons();</script> #}
</form>
</div> </div>
<button class="modal-close is-large" aria-label="close"></button> <button
type="button"
class="button is-light modal-close-button">
Cancel
</button>
<button type="submit" class="button is-info modal-close-button">Submit</button>
{# <script>activateButtons();</script> #}
</form>
</div> </div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
</div> </div>

@ -4,65 +4,65 @@
<script src="{% static 'modal.js' %}"></script> <script src="{% static 'modal.js' %}"></script>
<div id="modal" class="modal is-active is-clipped"> <div id="modal" class="modal is-active is-clipped">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content">
<div class="box"> <div class="box">
<h4 class="subtitle is-4">Edit aliases</h4> <h4 class="subtitle is-4">Edit aliases</h4>
<form <form
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'threshold_irc_aliases_edit' %}" hx-post="{% url 'threshold_irc_aliases_edit' %}"
hx-target="#aliases" hx-target="#aliases"
hx-swap="outerHTML"> hx-swap="outerHTML">
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>num</th> <th>num</th>
<th>nick</th> <th>nick</th>
<th>realname</th> <th>realname</th>
<th>emails</th> <th>emails</th>
</thead> </thead>
<tbody> <tbody>
{% for alias in aliases %} {% for alias in aliases %}
<tr> <tr>
<td> <td>
{{ alias.num }} {{ alias.num }}
</td> </td>
<td> <td>
<div class="field"> <div class="field">
<input class="input" type="text" name="{{ alias.num }}|nick" value="{{ alias.nick }}"> <input class="input" type="text" name="{{ alias.num }}|nick" value="{{ alias.nick }}">
</div> </div>
</td> </td>
<td> <td>
<div class="field"> <div class="field">
<input class="input" type="text" name="{{ alias.num }}|realname" value="{{ alias.realname }}"> <input class="input" type="text" name="{{ alias.num }}|realname" value="{{ alias.realname }}">
</div> </div>
</td> </td>
<td> <td>
<div class="field"> <div class="field">
<textarea class="textarea" name="{{ alias.num }}|emails">{{ alias.emails|nsep }}</textarea> <textarea class="textarea" name="{{ alias.num }}|emails">{{ alias.emails|nsep }}</textarea>
</div> </div>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div>
</div>
<button
type="button"
class="button is-light modal-close-button">
Cancel
</button>
<button type="submit" class="button is-info modal-close-button">Submit</button>
<script>activateButtons();</script>
</form>
</div>
</div> </div>
<button class="modal-close is-large" aria-label="close"></button> <button
type="button"
class="button is-light modal-close-button">
Cancel
</button>
<button type="submit" class="button is-info modal-close-button">Submit</button>
<script>activateButtons();</script>
</form>
</div> </div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
</div> </div>

@ -1,76 +1,76 @@
<div id="networks"> <div id="networks">
{% include 'manage/threshold/partials/notify.html' %} {% include 'manage/threshold/partials/notify.html' %}
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>net</th> <th>net</th>
<th> <th>
<span class="icon has-tooltip-bottom" data-tooltip="Relays"> <span class="icon has-tooltip-bottom" data-tooltip="Relays">
<i class="fa-brands fa-unity"></i> <i class="fa-brands fa-unity"></i>
</span> </span>
</th> </th>
<th> <th>
<span class="icon has-tooltip-bottom" data-tooltip="Active"> <span class="icon has-tooltip-bottom" data-tooltip="Active">
<i class="fa-solid fa-signal-bars-good"></i> <i class="fa-solid fa-signal-bars-good"></i>
</span> </span>
</th> </th>
<th> <th>
<span class="icon has-tooltip-bottom" data-tooltip="Channels"> <span class="icon has-tooltip-bottom" data-tooltip="Channels">
<i class="fa-solid fa-hashtag"></i> <i class="fa-solid fa-hashtag"></i>
</span> </span>
</th> </th>
<th> <th>
<span class="icon has-tooltip-bottom" data-tooltip="Records"> <span class="icon has-tooltip-bottom" data-tooltip="Records">
<i class="fa-solid fa-album"></i> <i class="fa-solid fa-album"></i>
</span> </span>
</th> </th>
<th> <th>
<span class="icon has-tooltip-bottom" data-tooltip="Actions"> <span class="icon has-tooltip-bottom" data-tooltip="Actions">
<i class="fa-solid fa-wrench" aria-hidden="true"></i> <i class="fa-solid fa-wrench" aria-hidden="true"></i>
</span> </span>
</th> </th>
</thead> </thead>
{% for key, net in networks.items %} {% for key, net in networks.items %}
<tr> <tr>
<th><a href="{% url 'threshold_irc_network' key %}">{{ key }}</a></th> <th><a href="{% url 'threshold_irc_network' key %}">{{ key }}</a></th>
<td> <td>
{{ net.relays }} {{ net.relays }}
</td> </td>
<td> <td>
{% if net.active %} {% if net.active %}
<span class="icon has-text-success"> <span class="icon has-text-success">
<i class="fa-solid fa-check" aria-hidden="true"></i> <i class="fa-solid fa-check" aria-hidden="true"></i>
</span> </span>
{% else %} {% else %}
<span class="icon has-text-danger"> <span class="icon has-text-danger">
<i class="fa-solid fa-xmark" aria-hidden="true"></i> <i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span> </span>
{% endif %} {% endif %}
</td> </td>
<td> <td>
{{ net.channels }} {{ net.channels }}
</td> </td>
<td> <td>
{{ net.records }} {{ net.records }}
</td> </td>
<td> <td>
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-delete="{% url 'threshold_irc_network_del' key %}" hx-delete="{% url 'threshold_irc_network_del' key %}"
hx-target="#networks" hx-target="#networks"
hx-swap="outerHTML" hx-swap="outerHTML"
class="button is-small is-danger"> class="button is-small is-danger">
<span class="icon" data-tooltip="Delete"> <span class="icon" data-tooltip="Delete">
<i class="fa-solid fa-xmark" aria-hidden="true"></i> <i class="fa-solid fa-xmark" aria-hidden="true"></i>
</span> </span>
</button> </button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
</div> </div>
<div id="modals-here-actions"> <div id="modals-here-actions">
</div> </div>
</div> </div>

@ -1,82 +1,82 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_stats' %}" hx-get="{% url 'threshold_irc_stats' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#stats" hx-target="#stats"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_networks' %}" hx-get="{% url 'threshold_irc_networks' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#networks" hx-target="#networks"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_aliases' %}" hx-get="{% url 'threshold_irc_aliases' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#aliases" hx-target="#aliases"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'threshold_irc_actions' %}" hx-get="{% url 'threshold_irc_actions' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#actions" hx-target="#actions"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="box"> <div class="box">
<div id="stats"> <div id="stats">
</div>
</div>
</div> </div>
<div class="column"> </div>
<div class="box"> </div>
<div id="networks"> <div class="column">
</div> <div class="box">
</div> <div id="networks">
</div> </div>
</div>
</div> </div>
</div>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="box"> <div class="box">
<div id="aliases"> <div id="aliases">
</div>
</div>
</div> </div>
<div class="column"> </div>
<div class="box"> </div>
<div id="alerts"> <div class="column">
Alerts here <div class="box">
</div> <div id="alerts">
</div> Alerts here
</div> </div>
</div>
</div> </div>
</div>
<div class="columns"> <div class="columns">
<div class="column"></div> <div class="column"></div>
<div class="column is-half"> <div class="column is-half">
<div class="box"> <div class="box">
<div id="actions"> <div id="actions">
</div>
</div>
</div> </div>
</div>
</div> </div>
<div id="modals-here"> </div>
</div> <div id="modals-here">
</div>
{% endblock %} {% endblock %}

@ -1,49 +1,49 @@
<div id="stats"> <div id="stats">
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<tr> <tr>
<th>attribute</th> <th>attribute</th>
<th>count</th> <th>count</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th>relays</th> <th>relays</th>
<td> <td>
{{ stats.servers_online_total }}/{{ stats.servers_total_total }} {{ stats.servers_online_total }}/{{ stats.servers_total_total }}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>networks</th> <th>networks</th>
<td> <td>
{{ stats.servers_online_unique }}/{{ stats.servers_total_unique }} {{ stats.servers_online_unique }}/{{ stats.servers_total_unique }}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>channels</th> <th>channels</th>
<td> <td>
{{ stats.channels}} {{ stats.channels}}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>records</th> <th>records</th>
<td> <td>
{{ stats.records }} {{ stats.records }}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>events</th> <th>events</th>
<td> <td>
{{ stats.eventrate }} {{ stats.eventrate }}
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div>
</div> </div>
</div>
</div> </div>

@ -1,5 +1,5 @@
{% if message is not None %} {% if message is not None %}
<div class="notification is-{{ class }}" hx-ext="remove-me" remove-me="3s"> <div class="notification is-{{ class }}" hx-ext="remove-me" remove-me="3s">
{{ message }} {{ message }}
</div> </div>
{% endif %} {% endif %}

@ -4,118 +4,118 @@
{% load static %} {% load static %}
{% block scripts %} {% block scripts %}
<script> <script>
document.addEventListener("restore-modal-scroll", function(event) { document.addEventListener("restore-modal-scroll", function(event) {
var modalContent = document.getElementsByClassName("modal-content")[0]; var modalContent = document.getElementsByClassName("modal-content")[0];
var maxScroll = modalContent.scrollHeight - modalContent.offsetHeight; var maxScroll = modalContent.scrollHeight - modalContent.offsetHeight;
var scrollpos = localStorage.getItem('scrollpos_modal_content'); var scrollpos = localStorage.getItem('scrollpos_modal_content');
if (scrollpos == 'BOTTOM') { if (scrollpos == 'BOTTOM') {
modalContent.scrollTop = maxScroll; modalContent.scrollTop = maxScroll;
} else if (scrollpos) { } else if (scrollpos) {
modalContent.scrollTop = scrollpos; modalContent.scrollTop = scrollpos;
}; };
}); });
document.addEventListener("htmx:beforeSwap", function(event) { document.addEventListener("htmx:beforeSwap", function(event) {
var modalContent = document.getElementsByClassName("modal-content")[0]; var modalContent = document.getElementsByClassName("modal-content")[0];
var scrollpos = modalContent.scrollTop; var scrollpos = modalContent.scrollTop;
if(modalContent.scrollTop === (modalContent.scrollHeight - modalContent.offsetHeight)) { if(modalContent.scrollTop === (modalContent.scrollHeight - modalContent.offsetHeight)) {
localStorage.setItem('scrollpos_modal_content', 'BOTTOM'); localStorage.setItem('scrollpos_modal_content', 'BOTTOM');
} else { } else {
localStorage.setItem('scrollpos_modal_content', scrollpos); localStorage.setItem('scrollpos_modal_content', scrollpos);
} }
}); });
</script> </script>
{% endblock %} {% endblock %}
{% block styles %} {% block styles %}
<style> <style>
#tab-content-{{ unique }} div { #tab-content-{{ unique }} div {
display: none; display: none;
} }
#tab-content-{{ unique }} div.is-active { #tab-content-{{ unique }} div.is-active {
display: block; display: block;
} }
</style> </style>
{% endblock %} {% endblock %}
{% block modal_content %} {% block modal_content %}
{% include 'partials/notify.html' %} {% include 'partials/notify.html' %}
<div class="tabs is-toggle is-fullwidth is-info" id="tabs-{{ unique }}"> <div class="tabs is-toggle is-fullwidth is-info" id="tabs-{{ unique }}">
<ul> <ul>
<li class="is-active" data-tab="1"> <li class="is-active" data-tab="1">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-message-arrow-down"></i></span> <span class="icon is-small"><i class="fa-solid fa-message-arrow-down"></i></span>
<span>Scrollback</span> <span>Scrollback</span>
</a> </a>
</li> </li>
<li data-tab="2"> <li data-tab="2">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-messages"></i></span> <span class="icon is-small"><i class="fa-solid fa-messages"></i></span>
<span>Context</span> <span>Context</span>
</a> </a>
</li> </li>
<li data-tab="3"> <li data-tab="3">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-message"></i></span> <span class="icon is-small"><i class="fa-solid fa-message"></i></span>
<span>Message</span> <span>Message</span>
</a> </a>
</li> </li>
<li data-tab="4"> <li data-tab="4">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-asterisk"></i></span> <span class="icon is-small"><i class="fa-solid fa-asterisk"></i></span>
<span>Info</span> <span>Info</span>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div id="tab-content-{{ unique }}"> <div id="tab-content-{{ unique }}">
<div class="is-active" data-content="1"> <div class="is-active" data-content="1">
<h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{% if num is not None %}{{ num }}{% endif %}</h4> <h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{% if num is not None %}{{ num }}{% endif %}</h4>
{% include 'partials/context_table.html' %} {% include 'partials/context_table.html' %}
{% if user.is_superuser and source == 'irc' %} {% if user.is_superuser and source == 'irc' %}
<form method="PUT"> <form method="PUT">
<article class="field has-addons"> <article class="field has-addons">
<article class="control is-expanded has-icons-left"> <article class="control is-expanded has-icons-left">
<input id="context-input" name="msg" class="input" type="text" placeholder="Type your message here"> <input id="context-input" name="msg" class="input" type="text" placeholder="Type your message here">
<span class="icon is-small is-left"> <span class="icon is-small is-left">
<i class="fas fa-magnifying-glass"></i> <i class="fas fa-magnifying-glass"></i>
</span> </span>
</article> </article>
<article class="control"> <article class="control">
<article class="field"> <article class="field">
<button <button
id="search" id="search"
class="button is-info is-fullwidth" class="button is-info is-fullwidth"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-put="{% url 'threshold_irc_msg' net num %}" hx-put="{% url 'threshold_irc_msg' net num %}"
hx-vals='{"channel": "{{ channel }}", "nick": "{{ nick }}"}' hx-vals='{"channel": "{{ channel }}", "nick": "{{ nick }}"}'
hx-trigger="click" hx-trigger="click"
hx-target="#context-input" hx-target="#context-input"
hx-swap="outerHTML"> hx-swap="outerHTML">
Send Send
</button> </button>
</article> </article>
</article> </article>
</article> </article>
</form> </form>
{% endif %} {% endif %}
</div>
<div data-content="2">
<h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{{ num }} around {{ ts }}</h4>
Context
</div>
<div data-content="3">
<h4 class="subtitle is-4">Message details</h4>
Message deetails
</div>
<div data-content="4">
<h4 class="subtitle is-4">Information about {{ channel }} on {{ net }}{{ num }}</h4>
info
</div>
</div> </div>
<script>initTabs("{{ unique }}");</script> <div data-content="2">
<h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{{ num }} around {{ ts }}</h4>
Context
</div>
<div data-content="3">
<h4 class="subtitle is-4">Message details</h4>
Message deetails
</div>
<div data-content="4">
<h4 class="subtitle is-4">Information about {{ channel }} on {{ net }}{{ num }}</h4>
info
</div>
</div>
<script>initTabs("{{ unique }}");</script>
{% endblock %} {% endblock %}

@ -1,5 +1,5 @@
{% extends 'wm/modal.html' %} {% extends 'wm/modal.html' %}
{% block modal_content %} {% block modal_content %}
{% include 'window-content/drilldown.html' %} {% include 'window-content/drilldown.html' %}
{% endblock %} {% endblock %}

@ -1,177 +1,177 @@
<article class="table-container" id="modal-context-table"> <article class="table-container" id="modal-context-table">
<table class="table is-fullwidth"> <table class="table is-fullwidth">
<thead> <thead>
<th></th> <th></th>
<th></th> <th></th>
<th></th> <th></th>
</thead> </thead>
<tbody> <tbody>
{% for item in object_list %} {% for item in object_list %}
{% if item.type == 'control' %} {% if item.type == 'control' %}
<tr> <tr>
<td></td> <td></td>
<td> <td>
<span class="icon has-text-grey" data-tooltip="Hidden"> <span class="icon has-text-grey" data-tooltip="Hidden">
<i class="fa-solid fa-file-slash"></i> <i class="fa-solid fa-file-slash"></i>
</span> </span>
</td> </td>
<td> <td>
<p class="has-text-grey">Hidden {{ item.hidden }} similar result{% if item.hidden > 1%}s{% endif %}</p> <p class="has-text-grey">Hidden {{ item.hidden }} similar result{% if item.hidden > 1%}s{% endif %}</p>
</td> </td>
</tr> </tr>
{% else %} {% else %}
<tr> <tr>
<td>{{ item.time }}</td> <td>{{ item.time }}</td>
<td> <td>
{% if item.type != 'znc' and item.type != 'self' and query is not True %} {% if item.type != 'znc' and item.type != 'self' and query is not True %}
<article class="nowrap-parent"> <article class="nowrap-parent">
<article class="nowrap-child"> <article class="nowrap-child">
{% 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>
</span> </span>
{% elif item.type == 'join' %} {% elif item.type == 'join' %}
<span class="icon" data-tooltip="Join"> <span class="icon" data-tooltip="Join">
<i class="fa-solid fa-person-to-portal"></i> <i class="fa-solid fa-person-to-portal"></i>
</span> </span>
{% elif item.type == 'part' %} {% elif item.type == 'part' %}
<span class="icon" data-tooltip="Part"> <span class="icon" data-tooltip="Part">
<i class="fa-solid fa-person-from-portal"></i> <i class="fa-solid fa-person-from-portal"></i>
</span> </span>
{% elif item.type == 'quit' %} {% elif item.type == 'quit' %}
<span class="icon" data-tooltip="Quit"> <span class="icon" data-tooltip="Quit">
<i class="fa-solid fa-circle-xmark"></i> <i class="fa-solid fa-circle-xmark"></i>
</span> </span>
{% elif item.type == 'kick' %} {% elif item.type == 'kick' %}
<span class="icon" data-tooltip="Kick"> <span class="icon" data-tooltip="Kick">
<i class="fa-solid fa-user-slash"></i> <i class="fa-solid fa-user-slash"></i>
</span> </span>
{% elif item.type == 'nick' %} {% elif item.type == 'nick' %}
<span class="icon" data-tooltip="Nick"> <span class="icon" data-tooltip="Nick">
<i class="fa-solid fa-signature"></i> <i class="fa-solid fa-signature"></i>
</span> </span>
{% elif item.type == 'mode' %} {% elif item.type == 'mode' %}
<span class="icon" data-tooltip="Mode"> <span class="icon" data-tooltip="Mode">
<i class="fa-solid fa-gear"></i> <i class="fa-solid fa-gear"></i>
</span> </span>
{% elif item.type == 'action' %} {% elif item.type == 'action' %}
<span class="icon" data-tooltip="Action"> <span class="icon" data-tooltip="Action">
<i class="fa-solid fa-exclamation"></i> <i class="fa-solid fa-exclamation"></i>
</span> </span>
{% elif item.type == 'notice' %} {% elif item.type == 'notice' %}
<span class="icon" data-tooltip="Notice"> <span class="icon" data-tooltip="Notice">
<i class="fa-solid fa-message-code"></i> <i class="fa-solid fa-message-code"></i>
</span> </span>
{% elif item.type == 'conn' %} {% elif item.type == 'conn' %}
<span class="icon" data-tooltip="Connection"> <span class="icon" data-tooltip="Connection">
<i class="fa-solid fa-cloud-exclamation"></i> <i class="fa-solid fa-cloud-exclamation"></i>
</span> </span>
{% elif item.type == 'znc' %} {% elif item.type == 'znc' %}
<span class="icon" data-tooltip="ZNC"> <span class="icon" data-tooltip="ZNC">
<i class="fa-brands fa-unity"></i> <i class="fa-brands fa-unity"></i>
</span> </span>
{% elif item.type == 'query' %} {% elif item.type == 'query' %}
<span class="icon" data-tooltip="Query"> <span class="icon" data-tooltip="Query">
<i class="fa-solid fa-message"></i> <i class="fa-solid fa-message"></i>
</span> </span>
{% elif item.type == 'highlight' %} {% elif item.type == 'highlight' %}
<span class="icon" data-tooltip="Highlight"> <span class="icon" data-tooltip="Highlight">
<i class="fa-solid fa-exclamation"></i> <i class="fa-solid fa-exclamation"></i>
</span> </span>
{% elif item.type == 'who' %} {% elif item.type == 'who' %}
<span class="icon" data-tooltip="Who"> <span class="icon" data-tooltip="Who">
<i class="fa-solid fa-passport"></i> <i class="fa-solid fa-passport"></i>
</span> </span>
{% elif item.type == 'topic' %} {% elif item.type == 'topic' %}
<span class="icon" data-tooltip="Topic"> <span class="icon" data-tooltip="Topic">
<i class="fa-solid fa-sign"></i> <i class="fa-solid fa-sign"></i>
</span> </span>
{% else %} {% else %}
{{ item.type }} {{ item.type }}
{% endif %} {% endif %}
{% if item.online is True %} {% if item.online is True %}
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online"> <span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% elif item.online is False %} {% elif item.online is False %}
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline"> <span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% else %} {% else %}
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown"> <span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% endif %} {% endif %}
{% if item.src == 'irc' %} {% if item.src == 'irc' %}
<a <a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' %}" hx-post="{% url 'modal_drilldown' %}"
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}", "channel": "{{ item.channel }}"}' hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}", "channel": "{{ item.channel }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" hx-trigger="click"
class="has-text-black"> class="has-text-black">
<span class="icon" data-tooltip="Open drilldown modal"> <span class="icon" data-tooltip="Open drilldown modal">
<i class="fa-solid fa-album"></i> <i class="fa-solid fa-album"></i>
</span> </span>
</a> </a>
{% endif %} {% endif %}
</article> </article>
<a class="nowrap-child has-text-link is-underlined" onclick="populateSearch('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 != '—' %} {% if item.num_chans != '—' %}
<article class="nowrap-child"> <article class="nowrap-child">
<span class="tag"> <span class="tag">
{{ item.num_chans }} {{ item.num_chans }}
</span> </span>
</article> </article>
{% endif %} {% endif %}
</article> </article>
{% endif %} {% endif %}
{% if item.type == 'self' %} {% if item.type == 'self' %}
<span class="icon has-text-primary" data-tooltip="You"> <span class="icon has-text-primary" data-tooltip="You">
<i class="fa-solid fa-message-check"></i> <i class="fa-solid fa-message-check"></i>
</span> </span>
{% elif item.type == 'znc' %} {% elif item.type == 'znc' %}
<span class="icon has-text-info" data-tooltip="ZNC"> <span class="icon has-text-info" data-tooltip="ZNC">
<i class="fa-brands fa-unity"></i> <i class="fa-brands fa-unity"></i>
</span> </span>
{% elif query %} {% elif query %}
<span class="icon has-text-info" data-tooltip="Auth"> <span class="icon has-text-info" data-tooltip="Auth">
<i class="fa-solid fa-passport"></i> <i class="fa-solid fa-passport"></i>
</span> </span>
{% endif %} {% endif %}
</td> </td>
<td class="wrap">{{ item.msg }}</td> <td class="wrap">{{ item.msg }}</td>
</tr> </tr>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% if object_list %} {% if object_list %}
<div <div
class="modal-refresh" class="modal-refresh"
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context_table' %}" hx-post="{% url 'modal_context_table' %}"
hx-vals='{"net": "{{ net }}", hx-vals='{"net": "{{ net }}",
"num": "{{ num }}", "num": "{{ num }}",
"source": "{{ source }}", "source": "{{ source }}",
"channel": "{{ channel }}", "channel": "{{ channel }}",
"time": "{{ time }}", "time": "{{ time }}",
"date": "{{ date }}", "date": "{{ date }}",
"index": "{{ index }}", "index": "{{ index }}",
"type": "{{ type }}", "type": "{{ type }}",
"mtype": "{{ mtype }}", "mtype": "{{ mtype }}",
"nick": "{{ nick }}", "nick": "{{ nick }}",
"dedup": "{{ params.dedup }}"}' "dedup": "{{ params.dedup }}"}'
hx-target="#modal-context-table" hx-target="#modal-context-table"
hx-trigger="every 5s"> hx-trigger="every 5s">
</div> </div>
{% endif %} {% endif %}
</article> </article>
<script> <script>
var modal_event = new Event('restore-modal-scroll'); var modal_event = new Event('restore-modal-scroll');
document.dispatchEvent(modal_event); document.dispatchEvent(modal_event);
</script> </script>

@ -1,5 +1,5 @@
{% if message is not None %} {% if message is not None %}
<main class="notification is-{{ class }}" hx-ext="remove-me" remove-me="3s"> <main class="notification is-{{ class }}" hx-ext="remove-me" remove-me="3s">
{{ message }} {{ message }}
</main> </main>
{% endif %} {% endif %}

@ -1,5 +1,5 @@
{% if message is not None %} {% if message is not None %}
<div class="notification is-{{ class }}" hx-ext="remove-me" remove-me="3s"> <div class="notification is-{{ class }}" hx-ext="remove-me" remove-me="3s">
{{ message }} {{ message }}
</div> </div>
{% endif %} {% endif %}

@ -3,46 +3,46 @@
{% for plan in plans %} {% for plan in plans %}
<div class="box"> <div class="box">
<article class="media"> <article class="media">
<div class="media-left"> <div class="media-left">
<figure class="image is-64x64"> <figure class="image is-64x64">
<img src="{% static plan.image %}" alt="Image"> <img src="{% static plan.image %}" alt="Image">
</figure> </figure>
</div> </div>
<div class="media-content"> <div class="media-content">
<div class="content"> <div class="content">
<p> <p>
<strong>{{ plan.name }}</strong> <small>£{{ plan.cost }}</small> <strong>{{ plan.name }}</strong> <small>£{{ plan.cost }}</small>
{% if plan in user_plans %} {% if plan in user_plans %}
<i class="fas fa-check" aria-hidden="true"></i> <i class="fas fa-check" aria-hidden="true"></i>
{% endif %} {% endif %}
<br> <br>
{{ plan.description }} {{ plan.description }}
</p> </p>
</div> </div>
<nav class="level is-mobile"> <nav class="level is-mobile">
<div class="level-left"> <div class="level-left">
{% if plan not in user_plans %} {% if plan not in user_plans %}
<a class="level-item" href="/order/{{ plan.name }}"> <a class="level-item" href="/order/{{ plan.name }}">
<span class="icon is-small has-text-success"> <span class="icon is-small has-text-success">
<i class="fas fa-plus" aria-hidden="true"></i> <i class="fas fa-plus" aria-hidden="true"></i>
</span> </span>
</a> </a>
{% endif %} {% endif %}
{% if plan in user_plans %} {% if plan in user_plans %}
<a class="level-item" href="/cancel_subscription/{{ plan.name }}"> <a class="level-item" href="/cancel_subscription/{{ plan.name }}">
<span class="icon is-small has-text-info"> <span class="icon is-small has-text-info">
<i class="fas fa-cancel" aria-hidden="true"></i> <i class="fas fa-cancel" aria-hidden="true"></i>
</span> </span>
</a> </a>
{% endif %} {% endif %}
</div> </div>
</nav> </nav>
</div> </div>
</article> </article>
</div> </div>
{% endfor %} {% endfor %}

@ -3,23 +3,23 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %} {% block content %}
<section class="hero is-fullheight"> <section class="hero is-fullheight">
<div class="hero-body"> <div class="hero-body">
<div class="container"> <div class="container">
<div class="columns is-centered"> <div class="columns is-centered">
<div class="column is-5-tablet is-4-desktop is-3-widescreen"> <div class="column is-5-tablet is-4-desktop is-3-widescreen">
<form method="POST" class="box"> <form method="POST" class="box">
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}
<div class="field"> <div class="field">
<button class="button is-success"> <button class="button is-success">
Login Login
</button> </button>
</div> </div>
</form> </form>
</div> </div>
</div>
</div>
</div> </div>
</section> </div>
</div>
</section>
{% endblock %} {% endblock %}

@ -3,23 +3,23 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %} {% block content %}
<section class="hero is-fullheight"> <section class="hero is-fullheight">
<div class="hero-body"> <div class="hero-body">
<div class="container"> <div class="container">
<div class="columns is-centered"> <div class="columns is-centered">
<div class="column is-5-tablet is-4-desktop is-3-widescreen"> <div class="column is-5-tablet is-4-desktop is-3-widescreen">
<form method="POST" class="box"> <form method="POST" class="box">
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}
<div class="field"> <div class="field">
<button class="button is-success"> <button class="button is-success">
Sign up Sign up
</button> </button>
</div> </div>
</form> </form>
</div> </div>
</div>
</div>
</div> </div>
</section> </div>
</div>
</section>
{% endblock %} {% endblock %}

@ -2,8 +2,8 @@
{% block content %} {% block content %}
<section> <section>
<p>Subscription {{ plan }} cancelled!</p> <p>Subscription {{ plan }} cancelled!</p>
</section> </section>
{% endblock %} {% endblock %}

@ -1,11 +1,11 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<h1 class="title">Pathogen Data Insights</h1> <h1 class="title">Pathogen Data Insights</h1>
<div class="container"> <div class="container">
<h2 class="subtitle">Thank you for your order!</h2> <h2 class="subtitle">Thank you for your order!</h2>
<div class="col"> <div class="col">
<h2 class="subtitle">The customer portal will be available <a href="{% url 'billing' %} ">in your profile</a> shortly.</h2> <h2 class="subtitle">The customer portal will be available <a href="{% url 'billing' %} ">in your profile</a> shortly.</h2>
</div>
</div> </div>
</div>
{% endblock %} {% endblock %}

@ -2,141 +2,141 @@
{% load static %} {% load static %}
{% load joinsep %} {% load joinsep %}
{% block outer_content %} {% block outer_content %}
{% if params.modal == 'context' %} {% if params.modal == 'context' %}
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context' %}" hx-post="{% url 'modal_context' %}"
hx-vals='{"net": "{{ params.net|escapejs }}", hx-vals='{"net": "{{ params.net|escapejs }}",
"num": "{{ params.num|escapejs }}", "num": "{{ params.num|escapejs }}",
"source": "{{ params.source|escapejs }}", "source": "{{ params.source|escapejs }}",
"channel": "{{ params.channel|escapejs }}", "channel": "{{ params.channel|escapejs }}",
"time": "{{ params.time|escapejs }}", "time": "{{ params.time|escapejs }}",
"date": "{{ params.date|escapejs }}", "date": "{{ params.date|escapejs }}",
"index": "{{ params.index }}", "index": "{{ params.index }}",
"type": "{{ params.type|escapejs }}", "type": "{{ params.type|escapejs }}",
"mtype": "{{ params.mtype|escapejs }}", "mtype": "{{ params.mtype|escapejs }}",
"nick": "{{ params.nick|escapejs }}"}' "nick": "{{ params.nick|escapejs }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="load"> hx-trigger="load">
</div> </div>
{% endif %} {% endif %}
<script src="{% static 'js/chart.js' %}"></script> <script src="{% static 'js/chart.js' %}"></script>
<script src="{% static 'tabs.js' %}"></script> <script src="{% static 'tabs.js' %}"></script>
<script> <script>
function setupTags() { function setupTags() {
var inputTags = document.getElementById('tags'); var inputTags = document.getElementById('tags');
new BulmaTagsInput(inputTags); new BulmaTagsInput(inputTags);
inputTags.BulmaTagsInput().on('before.add', function(item) { inputTags.BulmaTagsInput().on('before.add', function(item) {
if (item.includes(": ")) { if (item.includes(": ")) {
var spl = item.split(": "); var spl = item.split(": ");
} else { } else {
var spl = item.split(":"); 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 field = spl[0];
var inputTags = document.getElementById('tags'); try {
inputTags.BulmaTagsInput().add(field+": "+value); var value = JSON.parse(spl[1]);
//htmx.trigger("#search", "click"); } catch {
var value = spl[1];
} }
</script> 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" 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" gs-w="7" gs-h="10" gs-y="0" gs-x="1">
<div class="grid-stack-item-content"> <div class="grid-stack-item-content">
<nav class="panel"> <nav class="panel">
<p class="panel-heading" style="padding: .2em; line-height: .5em;"> <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> <i class="fa-solid fa-arrows-up-down-left-right has-text-grey-light"></i>
Search Search
</p> </p>
<article class="panel-block is-active"> <article class="panel-block is-active">
{% include 'ui/drilldown/search_partial.html' %} {% include 'ui/drilldown/search_partial.html' %}
</article> </article>
</nav> </nav>
</div> </div>
</div>
</div> </div>
</div>
<script> <script>
var grid = GridStack.init({ var grid = GridStack.init({
cellHeight: 20, cellHeight: 20,
cellWidth: 50, cellWidth: 50,
auto: true, auto: true,
float: true, float: true,
draggable: {handle: '.panel-heading', scroll: false, appendTo: 'body'}, draggable: {handle: '.panel-heading', scroll: false, appendTo: 'body'},
removable: false, removable: false,
}); });
// GridStack.init(); // GridStack.init();
setupTags(); setupTags();
// a widget is ready to be loaded // a widget is ready to be loaded
document.addEventListener('load-widget', function(event) { document.addEventListener('load-widget', function(event) {
let container = htmx.find('#drilldown-widget'); let container = htmx.find('#drilldown-widget');
// get the scripts, they won't be run on the new element so we need to eval them // get the scripts, they won't be run on the new element so we need to eval them
var scripts = htmx.findAll(container, "script"); var scripts = htmx.findAll(container, "script");
let widgetelement = container.firstElementChild.cloneNode(true); let widgetelement = container.firstElementChild.cloneNode(true);
// check if there's an existing element like the one we want to swap // check if there's an existing element like the one we want to swap
let grid_element = htmx.find('#grid-stack-main'); let grid_element = htmx.find('#grid-stack-main');
let existing_widget = htmx.find(grid_element, '#drilldown-widget-results'); let existing_widget = htmx.find(grid_element, '#drilldown-widget-results');
// get the size and position attributes // get the size and position attributes
if (existing_widget) { if (existing_widget) {
let attrs = existing_widget.getAttributeNames(); let attrs = existing_widget.getAttributeNames();
for (let i = 0, len = attrs.length; i < len; i++) { for (let i = 0, len = attrs.length; i < len; i++) {
if (attrs[i].startsWith('gs-')) { // only target gridstack attributes if (attrs[i].startsWith('gs-')) { // only target gridstack attributes
widgetelement.setAttribute(attrs[i], existing_widget.getAttribute(attrs[i])); widgetelement.setAttribute(attrs[i], existing_widget.getAttribute(attrs[i]));
} }
} }
} }
// clear the queue element // clear the queue element
container.outerHTML = ""; container.outerHTML = "";
// temporary workaround, other widgets can be duplicated, but not results // temporary workaround, other widgets can be duplicated, but not results
if (widgetelement.id == 'drilldown-widget-results') { if (widgetelement.id == 'drilldown-widget-results') {
grid.removeWidget("drilldown-widget-{{ unique }}"); grid.removeWidget("drilldown-widget-{{ unique }}");
} }
grid.addWidget(widgetelement); grid.addWidget(widgetelement);
// re-create the HTMX JS listeners, otherwise HTMX won't work inside the grid // re-create the HTMX JS listeners, otherwise HTMX won't work inside the grid
htmx.process(widgetelement); htmx.process(widgetelement);
// run the JS scripts inside the added element again // run the JS scripts inside the added element again
// for instance, this will fix the dropdown // for instance, this will fix the dropdown
for (var i = 0; i < scripts.length; i++) { for (var i = 0; i < scripts.length; i++) {
eval(scripts[i].innerHTML); eval(scripts[i].innerHTML);
} }
}); });
</script> </script>
<div id="modals-here"> <div id="modals-here">
</div> </div>
<div id="items-here"> <div id="items-here">
</div> </div>
<div id="widgets-here" style="display: none;"> <div id="widgets-here" style="display: none;">
</div> </div>
<div id="results" style="display: none;"> <div id="results" style="display: none;">
{% if table %} {% if table %}
{% include 'widgets/table_results.html' %} {% include 'widgets/table_results.html' %}
{% endif %} {% endif %}
</div> </div>
<script> <script>
</script> </script>
{% endblock %} {% endblock %}

@ -1,401 +1,401 @@
<form class="skipEmptyFields" method="POST" hx-post="{% url 'search' %}" <form class="skipEmptyFields" method="POST" hx-post="{% url 'search' %}"
hx-trigger="change" hx-trigger="change"
hx-target="#results" hx-target="#results"
hx-swap="innerHTML" hx-swap="innerHTML"
hx-indicator="#spinner"> hx-indicator="#spinner">
{% csrf_token %} {% csrf_token %}
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field has-addons"> <div class="field has-addons">
<div id="query" class="control is-expanded has-icons-left"> <div id="query" class="control is-expanded has-icons-left">
<input <input
hx-post="{% url 'search' %}" hx-post="{% url 'search' %}"
hx-trigger="keyup changed delay:200ms" hx-trigger="keyup changed delay:200ms"
hx-target="#results" hx-target="#results"
hx-swap="innerHTML" hx-swap="innerHTML"
name="query" name="query"
value="{{ params.query }}" value="{{ params.query }}"
class="input" class="input"
type="text" type="text"
placeholder="Search something"> placeholder="Search something">
<span class="icon is-small is-left"> <span class="icon is-small is-left">
<i class="fas fa-magnifying-glass"></i> <i class="fas fa-magnifying-glass"></i>
</span> </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>
<div class="column is-3"> <div class="control">
<div class="nowrap-parent"> <div class="field">
<div <button
data-script="on click toggle .is-hidden on #options" id="search"
class="button is-light has-text-link is-right nowrap-child"> class="button is-info is-fullwidth"
Options hx-post="{% url 'search' %}"
</div> hx-trigger="click"
<div class="nowrap-child"> hx-target="#results"
<span id="spinner" class="button is-light has-text-link is-loading htmx-indicator">Static</span> hx-swap="innerHTML">
</div> Search
</div> </button>
</div>
</div> </div>
</div>
</div> </div>
<div id="options" class="block is-hidden"> <div class="column is-3">
<div class="columns is-multiline"> <div class="nowrap-parent">
<div class="column is-narrow"> <div
<div class="field has-addons"> data-script="on click toggle .is-hidden on #options"
<div class="control has-icons-left"> class="button is-light has-text-link is-right nowrap-child">
<span class="select"> Options
<select name="size"> </div>
{% for size in sizes %} <div class="nowrap-child">
{% if size == params.size %} <span id="spinner" class="button is-light has-text-link is-loading htmx-indicator">Static</span>
<option selected value="{{ size }}">{{ size }}</option> </div>
{% else %} </div>
<option value="{{ size }}">{{ size }}</option> </div>
{% endif %} </div>
{% endfor %} <div id="options" class="block is-hidden">
</select> <div class="columns is-multiline">
<span class="icon is-small is-left"> <div class="column is-narrow">
<i class="fas fa-magnifying-glass"></i> <div class="field has-addons">
</span> <div class="control has-icons-left">
</span> <span class="select">
</div> <select name="size">
<p class="control"> {% for size in sizes %}
<a class="button is-static"> {% if size == params.size %}
results <option selected value="{{ size }}">{{ size }}</option>
</a> {% else %}
</p> <option value="{{ size }}">{{ size }}</option>
</div> {% endif %}
</div> {% endfor %}
<div class="column is-narrow"> </select>
<div class="field has-addons block"> <span class="icon is-small is-left">
<div class="control has-icons-left"> <i class="fas fa-magnifying-glass"></i>
<span class="select"> </span>
<select id="source" name="source"> </span>
{% if params.source == 'irc' %} </div>
<option selected value="irc">IRC</option> <p class="control">
{% else %} <a class="button is-static">
<option value="irc">IRC</option> results
{% endif %} </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' %} {% if params.source == 'dis' %}
<option selected value="dis">Discord</option> <option selected value="dis">Discord</option>
{% else %} {% else %}
<option value="dis">Discord</option> <option value="dis">Discord</option>
{% endif %} {% endif %}
{% if params.source == None %} {% if params.source == None %}
<option selected value="4ch">4chan</option> <option selected value="4ch">4chan</option>
{% elif params.source == '4ch' %} {% elif params.source == '4ch' %}
<option selected value="4ch">4chan</option> <option selected value="4ch">4chan</option>
{% else %} {% else %}
<option value="4ch">4chan</option> <option value="4ch">4chan</option>
{% endif %} {% endif %}
{% if params.source == 'all' %} {% if params.source == 'all' %}
<option selected value="all">All</option> <option selected value="all">All</option>
{% else %} {% else %}
<option value="all">All</option> <option value="all">All</option>
{% endif %} {% endif %}
</select> </select>
<span class="icon is-small is-left"> <span class="icon is-small is-left">
<i class="fas fa-magnifying-glass"></i> <i class="fas fa-magnifying-glass"></i>
</span> </span>
</span> </span>
</div> </div>
<p class="control"> <p class="control">
<a class="button is-static"> <a class="button is-static">
source source
</a> </a>
</p> </p>
</div> </div>
<div class="control"> <div class="control">
<div class="field"> <div class="field">
<input <input
id="dedup_switch" id="dedup_switch"
type="checkbox" type="checkbox"
class="switch is-rounded is-info" class="switch is-rounded is-info"
name="dedup" name="dedup"
{% if params.dedup == "on" %} {% if params.dedup == "on" %}
checked="checked" checked="checked"
{% endif %}> {% endif %}>
<label <label
for="dedup_switch"> for="dedup_switch">
Deduplicate results Deduplicate results
</label> </label>
</div> </div>
</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> </div>
<div class="column is-narrow"> <p class="control">
<div id="sentiment"> <a class="button is-static">
<div class="field has-addons"> sentiment
<div class="control"> </a>
<input </p>
{% if params.check_sentiment != "on" %} </div>
disabled="undefined" <div class="control">
{% endif %} <label class="radio button has-text-link">
name="sentiment" id="sliderWithValue" class="slider has-output-tooltip is-fullwidth" min="-1" max="1" <input
{% if params.sentiment == None %} type="radio"
value="0" value="below"
{% else %} class="sentiment-radio"
value="{{ params.sentiment }}" {% if params.sentiment_method == 'below' %}
{% endif %} checked
step="0.05" type="range"> {% endif %}
<output for="sliderWithValue" class="slider-output"> name="sentiment_method"
{% if params.sentiment == None %} {% if params.check_sentiment != "on" %}
0 disabled
{% else %} {% endif %}>
{{ params.sentiment }} <span class="icon" data-tooltip="Below">
{% endif %} <i class="fa-solid fa-face-frown"></i>
</output> </span>
<script>bulmaSlider.attach();</script> </label>
</div> <label class="radio button has-text-link is-hidden">
<p class="control"> <input
<a class="button is-static"> type="radio"
sentiment value="exact"
</a> class="sentiment-radio"
</p> {% if params.sentiment_method == 'exact' %}
</div> checked
<div class="control"> {% endif %}
<label class="radio button has-text-link"> name="sentiment_method"
<input {% if params.check_sentiment != "on" %}
type="radio" disabled
value="below" {% endif %}>
class="sentiment-radio" <span class="icon" data-tooltip="Exact">
{% if params.sentiment_method == 'below' %} <i class="fa-solid fa-face-smile"></i>
checked </span>
{% endif %} </label>
name="sentiment_method" <label class="radio button has-text-link">
{% if params.check_sentiment != "on" %} <input
disabled type="radio"
{% endif %}> value="above"
<span class="icon" data-tooltip="Below"> class="sentiment-radio"
<i class="fa-solid fa-face-frown"></i> {% if params.sentiment_method == 'above' %}
</span> checked
</label> {% endif %}
<label class="radio button has-text-link is-hidden"> name="sentiment_method"
<input {% if params.check_sentiment != "on" %}
type="radio" disabled
value="exact" {% endif %}>
class="sentiment-radio" <span class="icon" data-tooltip="Above">
{% if params.sentiment_method == 'exact' %} <i class="fa-solid fa-face-smile"></i>
checked </span>
{% endif %} </label>
name="sentiment_method" <label class="radio button has-text-link">
{% if params.check_sentiment != "on" %} <input
disabled type="radio"
{% endif %}> value="nonzero"
<span class="icon" data-tooltip="Exact"> class="sentiment-radio"
<i class="fa-solid fa-face-smile"></i> {% if params.sentiment_method == 'nonzero' %}
</span> checked
</label> {% endif %}
<label class="radio button has-text-link"> name="sentiment_method"
<input {% if params.check_sentiment != "on" %}
type="radio" disabled
value="above" {% endif %}>
class="sentiment-radio" <span class="icon" data-tooltip="Nonzero">
{% if params.sentiment_method == 'above' %} <i class="fa-solid fa-face-meh-blank"></i>
checked </span>
{% endif %} </label>
name="sentiment_method" </div>
{% 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>
<div class="control"> <div class="control">
<div class="field"> <div class="field">
<input <input
id="sentiment_switch" id="sentiment_switch"
type="checkbox" type="checkbox"
class="switch is-rounded is-info" class="switch is-rounded is-info"
name="check_sentiment" name="check_sentiment"
data-script="on click toggle @disabled on #sliderWithValue then toggle @disabled on #sentiment then toggle @disabled on .sentiment-radio" data-script="on click toggle @disabled on #sliderWithValue then toggle @disabled on #sentiment then toggle @disabled on .sentiment-radio"
{% if params.check_sentiment == "on" %} {% if params.check_sentiment == "on" %}
checked checked
{% endif %}> {% endif %}>
<label <label
for="sentiment_switch"> for="sentiment_switch">
Check sentiment Check sentiment
</label> </label>
</div> </div>
</div> </div>
<div class="control"> <div class="control">
<div class="field"> <div class="field">
<input <input
id="sentiment_graph_switch" id="sentiment_graph_switch"
type="checkbox" type="checkbox"
class="switch is-rounded is-info" class="switch is-rounded is-info"
name="show_sentiment" name="show_sentiment"
data-script="on click toggle .is-hidden on #sentiment-container"> data-script="on click toggle .is-hidden on #sentiment-container">
<label <label
for="sentiment_graph_switch"> for="sentiment_graph_switch">
Show graph Show graph
</label> </label>
</div> </div>
</div> </div>
</div> </div>
<div class="column is-narrow"> <div class="column is-narrow">
<div id="date"> <div id="date">
<div class="field"> <div class="field">
<div class="control"> <div class="control">
<input type="date" name="dates" value="{{ params.date }}"> <input type="date" name="dates" value="{{ params.date }}">
<script> <script>
var options = { var options = {
"type": "datetime", "type": "datetime",
"isRange": true, "isRange": true,
"color": "info", "color": "info",
"validateLabel": "Save", "validateLabel": "Save",
"dateFormat": "yyyy-MM-dd", "dateFormat": "yyyy-MM-dd",
"startDate": "{{ params.from_date|escapejs }}", "startDate": "{{ params.from_date|escapejs }}",
"startTime": "{{ params.from_time|escapejs }}", "startTime": "{{ params.from_time|escapejs }}",
"endDate": "{{ params.to_date|escapejs }}", "endDate": "{{ params.to_date|escapejs }}",
"endTime": "{{ params.to_time|escapejs }}", "endTime": "{{ params.to_time|escapejs }}",
"displayMode": "dialog" "displayMode": "dialog"
}; };
// Initialize all input of type date // Initialize all input of type date
var calendars = bulmaCalendar.attach('[type="date"]', options); var calendars = bulmaCalendar.attach('[type="date"]', options);
// Loop on each calendar initialized // Loop on each calendar initialized
for(var i = 0; i < calendars.length; i++) { for(var i = 0; i < calendars.length; i++) {
// Add listener to select event // Add listener to select event
calendars[i].on('save', date => { calendars[i].on('save', date => {
htmx.trigger("#search", "click"); htmx.trigger("#search", "click");
}); });
} }
</script> </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>
<div class="column is-narrow rounded-tooltip"> </div>
<div class="field has-addons"> <div class="control">
<div class="control has-icons-left"> <label class="radio button has-text-link">
<span class="select is-warning"> <input
<select {% if not user.is_superuser %}disabled{% endif %} id="index" name="index"> type="radio"
{% if params.index == 'main' %} value="desc"
<option selected value="main">Main</option> name="sorting"
{% elif params.index == None %} {% if params.sorting == None %}
<option selected value="main">Main</option> checked
{% else %} {% elif params.sorting == 'desc' %}
<option value="main">Main</option> checked
{% endif %} {% endif %}>
<span class="icon" data-tooltip="Sort descending">
{% if params.index == 'int' %} <i class="fa-solid fa-sort-down"></i>
<option selected value="int">Internal</option> </span>
{% else %} </label>
<option value="int">Internal</option> <label class="radio button">
{% endif %} <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 == 'meta' %} {% if params.index == 'int' %}
<option selected value="meta">Meta</option> <option selected value="int">Internal</option>
{% else %} {% else %}
<option value="meta">Meta</option> <option value="int">Internal</option>
{% endif %} {% endif %}
</select> {% if params.index == 'meta' %}
<span class="icon is-small is-left"> <option selected value="meta">Meta</option>
<i class="fas fa-magnifying-glass"></i> {% else %}
</span> <option value="meta">Meta</option>
</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 %} {% endif %}
</div>
</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> </div>
{% if not user.is_superuser %}
<span class="tooltiptext tag is-danger is-light">No access</span>
{% endif %}
</div>
</div> </div>
<div class="block"> </div>
<input <div class="block">
hx-trigger="change" <input
hx-post="{% url 'search' %}" hx-trigger="change"
hx-target="#results" hx-post="{% url 'search' %}"
hx-swap="innerHTML" hx-target="#results"
id="tags" hx-swap="innerHTML"
class="input" id="tags"
type="tags" class="input"
name="tags" type="tags"
placeholder="Tag search: nick: john" name="tags"
value="{{ params.tags }}"> placeholder="Tag search: nick: john"
</div> value="{{ params.tags }}">
<div class="is-hidden"></div> </div>
<div class="is-hidden"></div>
</form> </form>

@ -3,8 +3,8 @@
</div> </div>
{% if params.index != 'int' and params.index != 'meta' %} {% if params.index != 'int' and params.index != 'meta' %}
<div id="sentiment-container" {% if params.show_sentiment is None %} class="is-hidden" {% endif %}> <div id="sentiment-container" {% if params.show_sentiment is None %} class="is-hidden" {% endif %}>
<canvas id="sentiment-chart"></canvas> <canvas id="sentiment-chart"></canvas>
</div> </div>
<script src="{% static 'chart.js' %}"></script> <script src="{% static 'chart.js' %}"></script>
{% endif %} {% endif %}

@ -22,10 +22,10 @@
{% for column in table.columns %} {% for column in table.columns %}
{% if column.name in show %} {% if column.name in show %}
<a class="btn-shift-column dropdown-item" <a class="btn-shift-column dropdown-item"
data-td-class="{{ column.name }}" data-td-class="{{ column.name }}"
data-state="on" data-state="on"
{% if not forloop.last %} style="border-bottom:1px solid #ccc;" {%endif %} {% if not forloop.last %} style="border-bottom:1px solid #ccc;" {%endif %}
data-table-class-container="drilldown-table"> data-table-class-container="drilldown-table">
<span class="check icon" data-tooltip="Visible" style="display:none;"> <span class="check icon" data-tooltip="Visible" style="display:none;">
<i class="fa-solid fa-check"></i> <i class="fa-solid fa-check"></i>
</span> </span>
@ -125,13 +125,13 @@
</tr> </tr>
{% else %} {% else %}
<tr class=" <tr class="
{% if row.cells.exemption == True %}has-background-grey-lighter {% if row.cells.exemption == True %}has-background-grey-lighter
{% elif cell == 'join' %}has-background-success-light {% elif cell == 'join' %}has-background-success-light
{% elif cell == 'quit' %}has-background-danger-light {% elif cell == 'quit' %}has-background-danger-light
{% elif cell == 'kick' %}has-background-danger-light {% elif cell == 'kick' %}has-background-danger-light
{% elif cell == 'part' %}has-background-warning-light {% elif cell == 'part' %}has-background-warning-light
{% elif cell == 'mode' %}has-background-info-light {% elif cell == 'mode' %}has-background-info-light
{% endif %}"> {% endif %}">
{% for column, cell in row.items %} {% for column, cell in row.items %}
{% if column.name in show %} {% if column.name in show %}
{% block table.tbody.td %} {% block table.tbody.td %}
@ -147,7 +147,7 @@
</td> </td>
{% elif column.name == 'src' %} {% elif column.name == 'src' %}
<td class="{{ column.name }}"> <td class="{{ column.name }}">
<a <a
class="has-text-link is-underlined" class="has-text-link is-underlined"
onclick="populateSearch('src', '{{ cell|escapejs }}')"> onclick="populateSearch('src', '{{ cell|escapejs }}')">
{% if row.cells.src == 'irc' %} {% if row.cells.src == 'irc' %}
@ -172,7 +172,7 @@
</td> </td>
{% elif column.name == 'type' or column.name == 'mtype' %} {% elif column.name == 'type' or column.name == 'mtype' %}
<td class="{{ column.name }}"> <td class="{{ column.name }}">
<a <a
class="has-text-link is-underlined" class="has-text-link is-underlined"
onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')"> onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')">
{% if cell == 'msg' %} {% if cell == 'msg' %}
@ -247,17 +247,17 @@
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context' %}" hx-post="{% url 'modal_context' %}"
hx-vals='{"net": "{{ row.cells.net|escapejs }}", hx-vals='{"net": "{{ row.cells.net|escapejs }}",
"num": "{{ row.cells.num|escapejs }}", "num": "{{ row.cells.num|escapejs }}",
"source": "{{ row.cells.src|escapejs }}", "source": "{{ row.cells.src|escapejs }}",
"channel": "{{ row.cells.channel|escapejs }}", "channel": "{{ row.cells.channel|escapejs }}",
"time": "{{ row.cells.time|escapejs }}", "time": "{{ row.cells.time|escapejs }}",
"date": "{{ row.cells.date|escapejs }}", "date": "{{ row.cells.date|escapejs }}",
"index": "{{ params.index }}", "index": "{{ params.index }}",
"type": "{{ row.cells.type }}", "type": "{{ row.cells.type }}",
"mtype": "{{ row.cells.mtype }}", "mtype": "{{ row.cells.mtype }}",
"nick": "{{ row.cells.nick|escapejs }}", "nick": "{{ row.cells.nick|escapejs }}",
"dedup": "{{ params.dedup }}"}' "dedup": "{{ params.dedup }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" 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}}"> 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 }} {{ row.cells.msg }}
@ -290,7 +290,7 @@
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' %}" hx-post="{% url 'modal_drilldown' %}"
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}' hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" hx-trigger="click"
class="has-text-black"> class="has-text-black">
<span class="icon" data-tooltip="Open drilldown modal"> <span class="icon" data-tooltip="Open drilldown modal">
@ -313,7 +313,7 @@
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' type='widget' %}" hx-post="{% url 'modal_drilldown' type='widget' %}"
hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}' hx-vals='{"net": "{{ row.cells.net }}", "nick": "{{ row.cells.nick }}", "channel": "{{ row.cells.channel }}"}'
hx-target="#widgets-here" hx-target="#widgets-here"
hx-trigger="click" hx-trigger="click"
class="has-text-black"> class="has-text-black">
<span class="icon" data-tooltip="Open drilldown widget"> <span class="icon" data-tooltip="Open drilldown widget">
@ -335,7 +335,7 @@
<td class="{{ column.name }}"> <td class="{{ column.name }}">
{% if cell != '—' %} {% if cell != '—' %}
<div class="nowrap-parent"> <div class="nowrap-parent">
<a <a
class="nowrap-child has-text-link is-underlined" class="nowrap-child has-text-link is-underlined"
onclick="populateSearch('channel', '{{ cell|escapejs }}')"> onclick="populateSearch('channel', '{{ cell|escapejs }}')">
{{ cell }} {{ cell }}
@ -366,7 +366,7 @@
</td> </td>
{% else %} {% else %}
<td class="{{ column.name }}"> <td class="{{ column.name }}">
<a <a
class="has-text-link is-underlined" class="has-text-link is-underlined"
onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')"> onclick="populateSearch('{{ column.name }}', '{{ cell|escapejs }}')">
{{ cell }} {{ cell }}
@ -444,7 +444,7 @@
disabled disabled
{% endif %} {% endif %}
style="order:3;" style="order:3;"
> >
{% block pagination.next.text %} {% block pagination.next.text %}
<span aria-hidden="true">&raquo;</span> <span aria-hidden="true">&raquo;</span>
{% endblock pagination.next.text %} {% endblock pagination.next.text %}
@ -469,7 +469,7 @@
hx-swap="innerHTML" hx-swap="innerHTML"
hx-indicator="#spinner" hx-indicator="#spinner"
{% endif %} {% endif %}
> >
{% if p == '...' %} {% if p == '...' %}
<span class="pagination-ellipsis">&hellip;</span> <span class="pagination-ellipsis">&hellip;</span>
{% else %} {% else %}

@ -1,30 +1,30 @@
{% load index %} {% load index %}
<div id="channels"> <div id="channels">
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<tbody> <tbody>
{% for chan in chans %} {% for chan in chans %}
<tr> <tr>
<td> <td>
<span <span
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' %}" hx-post="{% url 'modal_drilldown' %}"
hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}' hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" hx-trigger="click"
class="button is-small"> class="button is-small">
{{ chan }} {{ chan }}
</span> </span>
{% if chan in num_users %} {% if chan in num_users %}
<span class="tag"> <span class="tag">
{{ num_users|index:chan }} {{ num_users|index:chan }}
</span> </span>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>

@ -1,103 +1,103 @@
{% load static %} {% load static %}
{% load index %} {% load index %}
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}' hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
hx-post="{% url 'chans_insights' %}" hx-post="{% url 'chans_insights' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#channels" hx-target="#channels"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}' hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
hx-post="{% url 'nicks_insights' %}" hx-post="{% url 'nicks_insights' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#nicks" hx-target="#nicks"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div id="info"> <div id="info">
{% include 'partials/notify.html' %} {% include 'partials/notify.html' %}
{% if item is not None %} {% if item is not None %}
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<thead> <thead>
<th>attribute</th> <th>attribute</th>
<th>value</th> <th>value</th>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<th>src</th> <th>src</th>
<td> <td>
{% 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>
</span> </span>
IRC IRC
{% elif item.src == 'dis' %} {% elif item.src == 'dis' %}
<span class="icon" data-tooltip="Discord"> <span class="icon" data-tooltip="Discord">
<i class="fa-brands fa-discord" aria-hidden="true"></i> <i class="fa-brands fa-discord" aria-hidden="true"></i>
</span> </span>
Discord Discord
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>nick</th> <th>nick</th>
<td> <td>
{% if item.online is True %} {% if item.online is True %}
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online"> <span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{{ item.nick }} {{ item.nick }}
{% elif item.online is False %} {% elif item.online is False %}
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline"> <span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{{ item.nick }} {{ item.nick }}
{% else %} {% else %}
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown"> <span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{{ item.nick }} {{ item.nick }}
{% endif %} {% endif %}
{% if item.num_chans is not None %} {% if item.num_chans is not None %}
<span class="tag"> <span class="tag">
{{ item.num_chans }} {{ item.num_chans }}
</span> </span>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>host</th> <th>host</th>
<td>{{ item.host }}</td> <td>{{ item.host }}</td>
</tr> </tr>
<tr> <tr>
<th>actions</th> <th>actions</th>
<td> <td>
{% if item.src == 'irc' %} {% if item.src == 'irc' %}
<button <button
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_insights' %}" hx-post="{% url 'modal_insights' %}"
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}", "channel": "{{ item.channel }}"}' hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}", "channel": "{{ item.channel }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" hx-trigger="click"
class="button is-small"> class="button is-small">
Information Information
</button> </button>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>net</th> <th>net</th>
<td>{{ item.net }}</td> <td>{{ item.net }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>

@ -1,101 +1,101 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load static %} {% load static %}
{% block content %} {% block content %}
{% include 'partials/notify.html' %} {% include 'partials/notify.html' %}
<script> <script>
// tabbed browsing for the modal // tabbed browsing for the modal
function initTabs() { function initTabs() {
TABS.forEach((tab) => { TABS.forEach((tab) => {
tab.addEventListener('click', (e) => { tab.addEventListener('click', (e) => {
let selected = tab.getAttribute('data-tab'); let selected = tab.getAttribute('data-tab');
updateActiveTab(tab); updateActiveTab(tab);
updateActiveContent(selected); updateActiveContent(selected);
}) })
}) })
} }
function updateActiveTab(selected) { function updateActiveTab(selected) {
TABS.forEach((tab) => { TABS.forEach((tab) => {
if (tab && tab.classList.contains(ACTIVE_CLASS)) { if (tab && tab.classList.contains(ACTIVE_CLASS)) {
tab.classList.remove(ACTIVE_CLASS); tab.classList.remove(ACTIVE_CLASS);
}
});
selected.classList.add(ACTIVE_CLASS);
} }
});
selected.classList.add(ACTIVE_CLASS);
}
function updateActiveContent(selected) { function updateActiveContent(selected) {
CONTENT.forEach((item) => { CONTENT.forEach((item) => {
if (item && item.classList.contains(ACTIVE_CLASS)) { if (item && item.classList.contains(ACTIVE_CLASS)) {
item.classList.remove(ACTIVE_CLASS); item.classList.remove(ACTIVE_CLASS);
}
let data = item.getAttribute('data-content');
if (data === selected) {
item.classList.add(ACTIVE_CLASS);
}
});
} }
</script> let data = item.getAttribute('data-content');
<style> if (data === selected) {
.icon { border-bottom: 0px !important;} item.classList.add(ACTIVE_CLASS);
</style> }
<div class="tile is-ancestor"> });
<div class="tile is-vertical is-9"> }
<div class="tile"> </script>
<div class="tile is-parent is-vertical"> <style>
<article class="tile is-child box"> .icon { border-bottom: 0px !important;}
<form method="POST"> </style>
{% csrf_token %} <div class="tile is-ancestor">
<div class="field has-addons"> <div class="tile is-vertical is-9">
<div class="control is-expanded has-icons-left"> <div class="tile">
<input id="query_full" name="query_full" class="input" type="text" placeholder="nickname"> <div class="tile is-parent is-vertical">
<span class="icon is-small is-left"> <article class="tile is-child box">
<i class="fas fa-magnifying-glass"></i> <form method="POST">
</span> {% csrf_token %}
</div> <div class="field has-addons">
<div class="control"> <div class="control is-expanded has-icons-left">
<button <input id="query_full" name="query_full" class="input" type="text" placeholder="nickname">
class="button is-info is-fullwidth" <span class="icon is-small is-left">
hx-post="{% url 'search_insights' %}" <i class="fas fa-magnifying-glass"></i>
hx-trigger="click" </span>
hx-target="#info"
hx-swap="outerHTML">
Search
</button>
</div>
</div>
</form>
</article>
</div> </div>
<div class="tile is-parent"> <div class="control">
<article class="tile is-child box"> <button
<h5 class="subtitle is-5">Nicks</h5> class="button is-info is-fullwidth"
<div id="nicks"></div> hx-post="{% url 'search_insights' %}"
</article> hx-trigger="click"
hx-target="#info"
hx-swap="outerHTML">
Search
</button>
</div> </div>
</div> </div>
<div class="tile"> </form>
<div class="tile is-parent is-vertical"> </article>
<article class="tile is-child box">
<h5 class="subtitle is-5">Info</h5>
<div id="info"></div>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<h5 class="subtitle is-5">Meta</h5>
<div id="meta"></div>
</article>
</div>
</div>
</div> </div>
<div class="tile is-parent"> <div class="tile is-parent">
<article class="tile is-child box"> <article class="tile is-child box">
<h5 class="subtitle is-5">Channels</h5> <h5 class="subtitle is-5">Nicks</h5>
<div id="channels"></div> <div id="nicks"></div>
</article> </article>
</div> </div>
</div>
<div class="tile">
<div class="tile is-parent is-vertical">
<article class="tile is-child box">
<h5 class="subtitle is-5">Info</h5>
<div id="info"></div>
</article>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<h5 class="subtitle is-5">Meta</h5>
<div id="meta"></div>
</article>
</div>
</div>
</div>
<div class="tile is-parent">
<article class="tile is-child box">
<h5 class="subtitle is-5">Channels</h5>
<div id="channels"></div>
</article>
</div> </div>
<div id="modals-here"></div> </div>
<div id="modals-here"></div>
{% endblock %} {% endblock %}

@ -1,20 +1,20 @@
<div id="meta"> <div id="meta">
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<div class="table-container"> <div class="table-container">
{% for key,items in meta.items %} {% for key,items in meta.items %}
<th><strong>{{ key }}</strong></th> <th><strong>{{ key }}</strong></th>
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<tbody> <tbody>
{% for item in items %} {% for item in items %}
<tr> <tr>
<td> <td>
{{ item }} {{ item }}
</td> </td>
</tr> </tr>
{% endfor %}
</tbody>
</table>
{% endfor %} {% endfor %}
</div> </tbody>
</table>
{% endfor %}
</div> </div>
</div>
</div> </div>

@ -1,54 +1,54 @@
{% load index %} {% load index %}
<div <div
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-vals='{"net": "{{ net }}", "nicks": "{{ nicks }}"}' hx-vals='{"net": "{{ net }}", "nicks": "{{ nicks }}"}'
hx-post="{% url 'meta_insights' %}" hx-post="{% url 'meta_insights' %}"
hx-trigger="load" hx-trigger="load"
hx-target="#meta" hx-target="#meta"
hx-swap="outerHTML"> hx-swap="outerHTML">
</div> </div>
<div id="nicks"> <div id="nicks">
<div class="content" style="max-height: 30em; overflow: auto;"> <div class="content" style="max-height: 30em; overflow: auto;">
<table class="table is-fullwidth is-hoverable"> <table class="table is-fullwidth is-hoverable">
<tbody> <tbody>
{% for nick in nicks %} {% for nick in nicks %}
<tr> <tr>
<td> <td>
{% if nick in online %} {% if nick in online %}
{% if online|index:nick is True %} {% if online|index:nick is True %}
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online"> <span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% elif online|index:nick is False %} {% elif online|index:nick is False %}
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline"> <span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% else %} {% else %}
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown"> <span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% endif %} {% endif %}
{% endif %} {% endif %}
<span <span
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' %}" hx-post="{% url 'modal_drilldown' %}"
hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}' hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" hx-trigger="click"
class="button is-small"> class="button is-small">
{{ nick }} {{ nick }}
</span> </span>
<a <a
class="icon has-text-info has-tooltip-info" class="icon has-text-info has-tooltip-info"
data-tooltip="Populate search" data-tooltip="Populate search"
onclick="document.getElementById('query').value='nick: {{ nick }}';"> onclick="document.getElementById('query').value='nick: {{ nick }}';">
<i class="fa-solid fa-arrow-left-long-to-line"></i> <i class="fa-solid fa-arrow-left-long-to-line"></i>
</a> </a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>

@ -2,18 +2,18 @@
{% block widget_options %} {% block widget_options %}
gs-w="5" gs-h="15" gs-w="5" gs-h="15"
{% endblock %} {% endblock %}
{% block heading %} {% block heading %}
Drilldown Drilldown
{% endblock %} {% endblock %}
{% block panel_content %} {% block panel_content %}
{% include 'window-content/drilldown.html' %} {% include 'window-content/drilldown.html' %}
{% endblock %} {% endblock %}
{% block custom_script_end %} {% block custom_script_end %}
initTabs("{{ unique }}"); initTabs("{{ unique }}");
{% endblock %} {% endblock %}

@ -2,49 +2,41 @@
{% load static %} {% load static %}
{% block widget_options %} {% block widget_options %}
gs-w="10" gs-h="30" gs-y="10" gs-x="1" gs-w="10" gs-h="30" gs-y="10" gs-x="1"
{% endblock %} {% endblock %}
{% block heading %} {% block heading %}
Results Results
{% endblock %} {% endblock %}
{% block close_button %} {% block close_button %}
<i <i
class="fa-solid fa-xmark has-text-grey-light float-right" class="fa-solid fa-xmark has-text-grey-light float-right"
onclick='grid.removeWidget("drilldown-widget-{{ unique }}"); //grid.compact();'></i> onclick='grid.removeWidget("drilldown-widget-{{ unique }}"); //grid.compact();'></i>
{% endblock %} {% endblock %}
{% block panel_content %} {% block panel_content %}
{% include 'partials/notify.html' %} {% include 'partials/notify.html' %}
<script src="{% static 'js/column-shifter.js' %}"></script> <script src="{% static 'js/column-shifter.js' %}"></script>
<span class="icon has-tooltip-bottom" data-tooltip="{{ card }} hits total"> <span class="icon has-tooltip-bottom">
<i class="fa-solid fa-chart-mixed"></i> <i class="fa-solid fa-chart-mixed"></i>
</span> </span>
{{ table.data|length }} hits in {{ took }}ms showing {{ table.data|length }} of {{ card }} hits in {{ took }}ms
{% if exemption is not None %} {% if cache is not None %}
<span class="icon has-tooltip-bottom" data-tooltip="God mode"> {% endif %}
<i class="fa-solid fa-book-bible"></i> {% if exemption is not None %}
</span> <span class="icon has-tooltip-bottom" data-tooltip="God mode">
{% else %} <i class="fa-solid fa-book-bible"></i>
{% if redacted is not None %} </span>
<span class="icon has-tooltip-bottom" data-tooltip="{{ redacted }} redacted"> {% else %}
<i class="fa-solid fa-mask"></i> {% if redacted is not None %}
</span> <span class="icon has-tooltip-bottom" data-tooltip="{{ redacted }} redacted">
{% endif %} <i class="fa-solid fa-mask"></i>
{% endif %} </span>
{% if delay is not None %}
<span class="icon has-tooltip-bottom" data-tooltip="delayed by {{ delay }} days">
<i class="fa-solid fa-clock"></i>
</span>
{% endif %}
{% if randomised is True %}
<span class="icon has-tooltip-bottom" data-tooltip="integer fields randomised">
<i class="fa-solid fa-shuffle"></i>
</span>
{% endif %} {% endif %}
{% endif %}
{% include 'ui/drilldown/table_results_partial.html' %} {% include 'ui/drilldown/table_results_partial.html' %}
{% include 'ui/drilldown/sentiment_partial.html' %} {% include 'ui/drilldown/sentiment_partial.html' %}
{% endblock %} {% endblock %}

@ -3,120 +3,120 @@
<script src="{% static 'modal.js' %}"></script> <script src="{% static 'modal.js' %}"></script>
<script> <script>
document.addEventListener("restore-modal-scroll", function(event) { document.addEventListener("restore-modal-scroll", function(event) {
var modalContent = document.getElementsByClassName("modal-content")[0]; var modalContent = document.getElementsByClassName("modal-content")[0];
var maxScroll = modalContent.scrollHeight - modalContent.offsetHeight; var maxScroll = modalContent.scrollHeight - modalContent.offsetHeight;
var scrollpos = localStorage.getItem('scrollpos_modal_content'); var scrollpos = localStorage.getItem('scrollpos_modal_content');
if (scrollpos == 'BOTTOM') { if (scrollpos == 'BOTTOM') {
modalContent.scrollTop = maxScroll; modalContent.scrollTop = maxScroll;
} else if (scrollpos) { } else if (scrollpos) {
modalContent.scrollTop = scrollpos; modalContent.scrollTop = scrollpos;
}; };
}); });
document.addEventListener("htmx:beforeSwap", function(event) { document.addEventListener("htmx:beforeSwap", function(event) {
var modalContent = document.getElementsByClassName("modal-content")[0]; var modalContent = document.getElementsByClassName("modal-content")[0];
var scrollpos = modalContent.scrollTop; var scrollpos = modalContent.scrollTop;
if(modalContent.scrollTop === (modalContent.scrollHeight - modalContent.offsetHeight)) { if(modalContent.scrollTop === (modalContent.scrollHeight - modalContent.offsetHeight)) {
localStorage.setItem('scrollpos_modal_content', 'BOTTOM'); localStorage.setItem('scrollpos_modal_content', 'BOTTOM');
} else { } else {
localStorage.setItem('scrollpos_modal_content', scrollpos); localStorage.setItem('scrollpos_modal_content', scrollpos);
} }
}); });
</script> </script>
<style> <style>
#tab-content-{{ unique }} div { #tab-content-{{ unique }} div {
display: none; display: none;
} }
#tab-content-{{ unique }} div.is-active { #tab-content-{{ unique }} div.is-active {
display: block; display: block;
} }
</style> </style>
<div id="modal" class="modal is-active is-clipped"> <div id="modal" class="modal is-active is-clipped">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content">
<div class="box"> <div class="box">
{% include 'partials/notify.html' %} {% include 'partials/notify.html' %}
<div class="tabs is-toggle is-fullwidth is-info" id="tabs-{{ unique }}"> <div class="tabs is-toggle is-fullwidth is-info" id="tabs-{{ unique }}">
<ul> <ul>
<li class="is-active" data-tab="1"> <li class="is-active" data-tab="1">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-message-arrow-down"></i></span> <span class="icon is-small"><i class="fa-solid fa-message-arrow-down"></i></span>
<span>Scrollback</span> <span>Scrollback</span>
</a> </a>
</li> </li>
<li data-tab="2"> <li data-tab="2">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-messages"></i></span> <span class="icon is-small"><i class="fa-solid fa-messages"></i></span>
<span>Context</span> <span>Context</span>
</a> </a>
</li> </li>
<li data-tab="3"> <li data-tab="3">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-message"></i></span> <span class="icon is-small"><i class="fa-solid fa-message"></i></span>
<span>Message</span> <span>Message</span>
</a> </a>
</li> </li>
<li data-tab="4"> <li data-tab="4">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-asterisk"></i></span> <span class="icon is-small"><i class="fa-solid fa-asterisk"></i></span>
<span>Info</span> <span>Info</span>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div id="tab-content-{{ unique }}"> <div id="tab-content-{{ unique }}">
<div class="is-active" data-content="1"> <div class="is-active" data-content="1">
<h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{{ num }}</h4> <h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{{ num }}</h4>
{% include 'modals/context_table.html' %} {% include 'modals/context_table.html' %}
{% if user.is_superuser and src == 'irc' %} {% if user.is_superuser and src == 'irc' %}
<form method="PUT"> <form method="PUT">
<article class="field has-addons"> <article class="field has-addons">
<article class="control is-expanded has-icons-left"> <article class="control is-expanded has-icons-left">
<input id="context-input" name="msg" class="input" type="text" placeholder="Type your message here"> <input id="context-input" name="msg" class="input" type="text" placeholder="Type your message here">
<span class="icon is-small is-left"> <span class="icon is-small is-left">
<i class="fas fa-magnifying-glass"></i> <i class="fas fa-magnifying-glass"></i>
</span> </span>
</article> </article>
<article class="control"> <article class="control">
<article class="field"> <article class="field">
<button <button
id="search" id="search"
class="button is-info is-fullwidth" class="button is-info is-fullwidth"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-put="{% url 'threshold_irc_msg' net num %}" hx-put="{% url 'threshold_irc_msg' net num %}"
hx-vals='{"channel": "{{ channel }}", "nick": "{{ nick }}"}' hx-vals='{"channel": "{{ channel }}", "nick": "{{ nick }}"}'
hx-trigger="click" hx-trigger="click"
hx-target="#context-input" hx-target="#context-input"
hx-swap="outerHTML"> hx-swap="outerHTML">
Send Send
</button> </button>
</article> </article>
</article> </article>
</article> </article>
</form> </form>
{% endif %} {% endif %}
</div>
<div data-content="2">
<h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{{ num }} around {{ ts }}</h4>
Context
</div>
<div data-content="3">
<h4 class="subtitle is-4">Message details</h4>
Message deetails
</div>
<div data-content="4">
<h4 class="subtitle is-4">Information about {{ channel }} on {{ net }}{{ num }}</h4>
info
</div>
</div>
</div> </div>
<script>initTabs("{{ unique }}");</script> <div data-content="2">
<button class="modal-close is-large" aria-label="close"></button> <h4 class="subtitle is-4">Scrollback of {{ channel }} on {{ net }}{{ num }} around {{ ts }}</h4>
Context
</div>
<div data-content="3">
<h4 class="subtitle is-4">Message details</h4>
Message deetails
</div>
<div data-content="4">
<h4 class="subtitle is-4">Information about {{ channel }} on {{ net }}{{ num }}</h4>
info
</div>
</div>
</div> </div>
<script>initTabs("{{ unique }}");</script>
<button class="modal-close is-large" aria-label="close"></button>
</div>
</div> </div>

@ -1,177 +1,177 @@
<article class="table-container" id="modal-context-table"> <article class="table-container" id="modal-context-table">
<table class="table is-fullwidth"> <table class="table is-fullwidth">
<thead> <thead>
<th></th> <th></th>
<th></th> <th></th>
<th></th> <th></th>
</thead> </thead>
<tbody> <tbody>
{% for item in object_list %} {% for item in object_list %}
{% if item.type == 'control' %} {% if item.type == 'control' %}
<tr> <tr>
<td></td> <td></td>
<td> <td>
<span class="icon has-text-grey" data-tooltip="Hidden"> <span class="icon has-text-grey" data-tooltip="Hidden">
<i class="fa-solid fa-file-slash"></i> <i class="fa-solid fa-file-slash"></i>
</span> </span>
</td> </td>
<td> <td>
<p class="has-text-grey">Hidden {{ item.hidden }} similar result{% if item.hidden > 1%}s{% endif %}</p> <p class="has-text-grey">Hidden {{ item.hidden }} similar result{% if item.hidden > 1%}s{% endif %}</p>
</td> </td>
</tr> </tr>
{% else %} {% else %}
<tr> <tr>
<td>{{ item.time }}</td> <td>{{ item.time }}</td>
<td> <td>
{% if item.type != 'znc' and item.type != 'self' and query is not True %} {% if item.type != 'znc' and item.type != 'self' and query is not True %}
<article class="nowrap-parent"> <article class="nowrap-parent">
<article class="nowrap-child"> <article class="nowrap-child">
{% 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>
</span> </span>
{% elif item.type == 'join' %} {% elif item.type == 'join' %}
<span class="icon" data-tooltip="Join"> <span class="icon" data-tooltip="Join">
<i class="fa-solid fa-person-to-portal"></i> <i class="fa-solid fa-person-to-portal"></i>
</span> </span>
{% elif item.type == 'part' %} {% elif item.type == 'part' %}
<span class="icon" data-tooltip="Part"> <span class="icon" data-tooltip="Part">
<i class="fa-solid fa-person-from-portal"></i> <i class="fa-solid fa-person-from-portal"></i>
</span> </span>
{% elif item.type == 'quit' %} {% elif item.type == 'quit' %}
<span class="icon" data-tooltip="Quit"> <span class="icon" data-tooltip="Quit">
<i class="fa-solid fa-circle-xmark"></i> <i class="fa-solid fa-circle-xmark"></i>
</span> </span>
{% elif item.type == 'kick' %} {% elif item.type == 'kick' %}
<span class="icon" data-tooltip="Kick"> <span class="icon" data-tooltip="Kick">
<i class="fa-solid fa-user-slash"></i> <i class="fa-solid fa-user-slash"></i>
</span> </span>
{% elif item.type == 'nick' %} {% elif item.type == 'nick' %}
<span class="icon" data-tooltip="Nick"> <span class="icon" data-tooltip="Nick">
<i class="fa-solid fa-signature"></i> <i class="fa-solid fa-signature"></i>
</span> </span>
{% elif item.type == 'mode' %} {% elif item.type == 'mode' %}
<span class="icon" data-tooltip="Mode"> <span class="icon" data-tooltip="Mode">
<i class="fa-solid fa-gear"></i> <i class="fa-solid fa-gear"></i>
</span> </span>
{% elif item.type == 'action' %} {% elif item.type == 'action' %}
<span class="icon" data-tooltip="Action"> <span class="icon" data-tooltip="Action">
<i class="fa-solid fa-exclamation"></i> <i class="fa-solid fa-exclamation"></i>
</span> </span>
{% elif item.type == 'notice' %} {% elif item.type == 'notice' %}
<span class="icon" data-tooltip="Notice"> <span class="icon" data-tooltip="Notice">
<i class="fa-solid fa-message-code"></i> <i class="fa-solid fa-message-code"></i>
</span> </span>
{% elif item.type == 'conn' %} {% elif item.type == 'conn' %}
<span class="icon" data-tooltip="Connection"> <span class="icon" data-tooltip="Connection">
<i class="fa-solid fa-cloud-exclamation"></i> <i class="fa-solid fa-cloud-exclamation"></i>
</span> </span>
{% elif item.type == 'znc' %} {% elif item.type == 'znc' %}
<span class="icon" data-tooltip="ZNC"> <span class="icon" data-tooltip="ZNC">
<i class="fa-brands fa-unity"></i> <i class="fa-brands fa-unity"></i>
</span> </span>
{% elif item.type == 'query' %} {% elif item.type == 'query' %}
<span class="icon" data-tooltip="Query"> <span class="icon" data-tooltip="Query">
<i class="fa-solid fa-message"></i> <i class="fa-solid fa-message"></i>
</span> </span>
{% elif item.type == 'highlight' %} {% elif item.type == 'highlight' %}
<span class="icon" data-tooltip="Highlight"> <span class="icon" data-tooltip="Highlight">
<i class="fa-solid fa-exclamation"></i> <i class="fa-solid fa-exclamation"></i>
</span> </span>
{% elif item.type == 'who' %} {% elif item.type == 'who' %}
<span class="icon" data-tooltip="Who"> <span class="icon" data-tooltip="Who">
<i class="fa-solid fa-passport"></i> <i class="fa-solid fa-passport"></i>
</span> </span>
{% elif item.type == 'topic' %} {% elif item.type == 'topic' %}
<span class="icon" data-tooltip="Topic"> <span class="icon" data-tooltip="Topic">
<i class="fa-solid fa-sign"></i> <i class="fa-solid fa-sign"></i>
</span> </span>
{% else %} {% else %}
{{ item.type }} {{ item.type }}
{% endif %} {% endif %}
{% if item.online is True %} {% if item.online is True %}
<span class="icon has-text-success has-tooltip-success" data-tooltip="Online"> <span class="icon has-text-success has-tooltip-success" data-tooltip="Online">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% elif item.online is False %} {% elif item.online is False %}
<span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline"> <span class="icon has-text-danger has-tooltip-danger" data-tooltip="Offline">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% else %} {% else %}
<span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown"> <span class="icon has-text-warning has-tooltip-warning" data-tooltip="Unknown">
<i class="fa-solid fa-circle"></i> <i class="fa-solid fa-circle"></i>
</span> </span>
{% endif %} {% endif %}
{% if item.src == 'irc' %} {% if item.src == 'irc' %}
<a <a
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' %}" hx-post="{% url 'modal_drilldown' %}"
hx-vals='{"net": "{{ item.net|escapejs }}", "nick": "{{ item.nick|escapejs }}", "channel": "{{ item.channel|escapejs }}"}' hx-vals='{"net": "{{ item.net|escapejs }}", "nick": "{{ item.nick|escapejs }}", "channel": "{{ item.channel|escapejs }}"}'
hx-target="#modals-here" hx-target="#modals-here"
hx-trigger="click" hx-trigger="click"
class="has-text-black"> class="has-text-black">
<span class="icon" data-tooltip="Open drilldown modal"> <span class="icon" data-tooltip="Open drilldown modal">
<i class="fa-solid fa-album"></i> <i class="fa-solid fa-album"></i>
</span> </span>
</a> </a>
{% endif %} {% endif %}
</article> </article>
<a class="nowrap-child has-text-link is-underlined" onclick="populateSearch('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 != '—' %} {% if item.num_chans != '—' %}
<article class="nowrap-child"> <article class="nowrap-child">
<span class="tag"> <span class="tag">
{{ item.num_chans }} {{ item.num_chans }}
</span> </span>
</article> </article>
{% endif %} {% endif %}
</article> </article>
{% endif %} {% endif %}
{% if item.type == 'self' %} {% if item.type == 'self' %}
<span class="icon has-text-primary" data-tooltip="You"> <span class="icon has-text-primary" data-tooltip="You">
<i class="fa-solid fa-message-check"></i> <i class="fa-solid fa-message-check"></i>
</span> </span>
{% elif item.type == 'znc' %} {% elif item.type == 'znc' %}
<span class="icon has-text-info" data-tooltip="ZNC"> <span class="icon has-text-info" data-tooltip="ZNC">
<i class="fa-brands fa-unity"></i> <i class="fa-brands fa-unity"></i>
</span> </span>
{% elif query %} {% elif query %}
<span class="icon has-text-info" data-tooltip="Auth"> <span class="icon has-text-info" data-tooltip="Auth">
<i class="fa-solid fa-passport"></i> <i class="fa-solid fa-passport"></i>
</span> </span>
{% endif %} {% endif %}
</td> </td>
<td class="wrap">{{ item.msg }}</td> <td class="wrap">{{ item.msg }}</td>
</tr> </tr>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% if object_list %} {% if object_list %}
<div <div
class="modal-refresh" class="modal-refresh"
style="display: none;" style="display: none;"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_context_table' %}" hx-post="{% url 'modal_context_table' %}"
hx-vals='{"net": "{{ net }}", hx-vals='{"net": "{{ net }}",
"num": "{{ num }}", "num": "{{ num }}",
"src": "{{ src }}", "src": "{{ src }}",
"channel": "{{ channel }}", "channel": "{{ channel }}",
"time": "{{ time }}", "time": "{{ time }}",
"date": "{{ date }}", "date": "{{ date }}",
"index": "{{ index }}", "index": "{{ index }}",
"type": "{{ type }}", "type": "{{ type }}",
"mtype": "{{ mtype }}", "mtype": "{{ mtype }}",
"nick": "{{ nick }}", "nick": "{{ nick }}",
"dedup": "{{ params.dedup }}"}' "dedup": "{{ params.dedup }}"}'
hx-target="#modal-context-table" hx-target="#modal-context-table"
hx-trigger="every 5s"> hx-trigger="every 5s">
</div> </div>
{% endif %} {% endif %}
</article> </article>
<script> <script>
var modal_event = new Event('restore-modal-scroll'); var modal_event = new Event('restore-modal-scroll');
document.dispatchEvent(modal_event); document.dispatchEvent(modal_event);
</script> </script>

@ -1,107 +1,107 @@
{% load index %} {% load index %}
{% load static %} {% load static %}
<style> <style>
#tab-content-{{ unique }} div { #tab-content-{{ unique }} div {
display: none; display: none;
} }
#tab-content-{{ unique }} div.is-active { #tab-content-{{ unique }} div.is-active {
display: block; display: block;
} }
</style> </style>
<div class="tabs is-toggle is-fullwidth is-info" id="tabs-{{ unique }}"> <div class="tabs is-toggle is-fullwidth is-info" id="tabs-{{ unique }}">
<ul> <ul>
<li class="is-active" data-tab="1"> <li class="is-active" data-tab="1">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-user"></i></span> <span class="icon is-small"><i class="fa-solid fa-user"></i></span>
<span>Channels</span> <span>Channels</span>
</a> </a>
</li> </li>
<li data-tab="2"> <li data-tab="2">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-hashtag"></i></span> <span class="icon is-small"><i class="fa-solid fa-hashtag"></i></span>
<span>Users</span> <span>Users</span>
</a> </a>
</li> </li>
<li data-tab="3"> <li data-tab="3">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-people"></i></span> <span class="icon is-small"><i class="fa-solid fa-people"></i></span>
<span>Intersection</span> <span>Intersection</span>
</a> </a>
</li> </li>
<li data-tab="4"> <li data-tab="4">
<a> <a>
<span class="icon is-small"><i class="fa-solid fa-hashtag"></i></span> <span class="icon is-small"><i class="fa-solid fa-hashtag"></i></span>
<span>Intersection</span> <span>Intersection</span>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div id="tab-content-{{ unique }}"> <div id="tab-content-{{ unique }}">
<div class="is-active" data-content="1"> <div class="is-active" data-content="1">
<h4 class="subtitle is-4">Channels for {{ nick }} on {{ net }}</h4> <h4 class="subtitle is-4">Channels for {{ nick }} on {{ net }}</h4>
{% for channel in chans %} {% for channel in chans %}
<a class="panel-block is-active"> <a class="panel-block is-active">
<span class="panel-icon"> <span class="panel-icon">
<i class="fa-solid fa-hashtag" aria-hidden="true"></i> <i class="fa-solid fa-hashtag" aria-hidden="true"></i>
</span> </span>
{{ channel }} {{ channel }}
{% if nick in num_chans %} {% if nick in num_chans %}
<span class="tag"> <span class="tag">
{{ num_users|index:channel }} {{ num_users|index:channel }}
</span> </span>
{% endif %} {% endif %}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>
<div data-content="2"> <div data-content="2">
<h4 class="subtitle is-4">Users on {{ channel }} for {{ net }}</h4> <h4 class="subtitle is-4">Users on {{ channel }} for {{ net }}</h4>
{% for user in users %} {% for user in users %}
<a class="panel-block is-active"> <a class="panel-block is-active">
<span class="panel-icon"> <span class="panel-icon">
<i class="fa-solid fa-user" aria-hidden="true"></i> <i class="fa-solid fa-user" aria-hidden="true"></i>
</span> </span>
{{ user }} {{ user }}
{% if channel in num_users %} {% if channel in num_users %}
<span class="tag"> <span class="tag">
{{ num_chans|index:user }} {{ num_chans|index:user }}
</span> </span>
{% endif %} {% endif %}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>
<div data-content="3"> <div data-content="3">
<h4 class="subtitle is-4">Users sharing channels with {{ nick }} on {{ net }}</h4> <h4 class="subtitle is-4">Users sharing channels with {{ nick }} on {{ net }}</h4>
{% for user in inter_users %} {% for user in inter_users %}
<a class="panel-block is-active"> <a class="panel-block is-active">
<span class="panel-icon"> <span class="panel-icon">
<i class="fa-solid fa-user" aria-hidden="true"></i> <i class="fa-solid fa-user" aria-hidden="true"></i>
</span> </span>
{{ user }} {{ user }}
{% if channel in num_users %} {% if channel in num_users %}
<span class="tag"> <span class="tag">
{{ num_chans|index:user }} {{ num_chans|index:user }}
</span> </span>
{% endif %} {% endif %}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>
<div data-content="4"> <div data-content="4">
<h4 class="subtitle is-4">Channels sharing users with {{ channel }} on {{ net }}</h4> <h4 class="subtitle is-4">Channels sharing users with {{ channel }} on {{ net }}</h4>
{% for channel in inter_chans %} {% for channel in inter_chans %}
<a class="panel-block is-active"> <a class="panel-block is-active">
<span class="panel-icon"> <span class="panel-icon">
<i class="fa-solid fa-hashtag" aria-hidden="true"></i> <i class="fa-solid fa-hashtag" aria-hidden="true"></i>
</span> </span>
{{ channel }} {{ channel }}
{% if nick in num_chans %} {% if nick in num_chans %}
<span class="tag"> <span class="tag">
{{ num_users|index:channel }} {{ num_users|index:channel }}
</span> </span>
{% endif %} {% endif %}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>
<script>initTabs("{{ unique }}");</script> <script>initTabs("{{ unique }}");</script>
</div> </div>

@ -1,9 +1,9 @@
{% extends 'wm/magnet.html' %} {% extends 'wm/magnet.html' %}
{% block heading %} {% block heading %}
Drilldown Drilldown
{% endblock %} {% endblock %}
{% block panel_content %} {% block panel_content %}
{% include 'window-content/drilldown.html' %} {% include 'window-content/drilldown.html' %}
{% endblock %} {% endblock %}

@ -1,8 +1,8 @@
<magnet-block attract-distance="10" align-to="outer|center" class="floating-window"> <magnet-block attract-distance="10" align-to="outer|center" class="floating-window">
{% extends 'wm/panel.html' %} {% extends 'wm/panel.html' %}
{% block heading %} {% block heading %}
{% endblock %} {% endblock %}
{% block panel_content %} {% block panel_content %}
{% endblock %} {% endblock %}
</magnet-block> </magnet-block>

@ -8,12 +8,12 @@
{% endblock %} {% endblock %}
<div id="modal" class="modal is-active is-clipped"> <div id="modal" class="modal is-active is-clipped">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content">
<div class="box"> <div class="box">
{% block modal_content %} {% block modal_content %}
{% endblock %} {% endblock %}
<button class="modal-close is-large" aria-label="close"></button> <button class="modal-close is-large" aria-label="close"></button>
</div>
</div> </div>
</div>
</div> </div>

@ -1,19 +1,19 @@
<nav class="panel"> <nav class="panel">
<p class="panel-heading" style="padding: .2em; line-height: .5em;"> <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> <i class="fa-solid fa-arrows-up-down-left-right has-text-grey-light"></i>
{% block close_button %} {% block close_button %}
<i <i
class="fa-solid fa-xmark has-text-grey-light float-right" class="fa-solid fa-xmark has-text-grey-light float-right"
data-script="on click remove the closest <nav/>"></i> data-script="on click remove the closest <nav/>"></i>
{% endblock %} {% endblock %}
{% block heading %} {% block heading %}
{% endblock %} {% endblock %}
</p> </p>
<article class="panel-block is-active"> <article class="panel-block is-active">
<div class="control"> <div class="control">
{% block panel_content %} {% block panel_content %}
{% endblock %} {% endblock %}
</div> </div>
</article> </article>
</nav> </nav>

@ -1,37 +1,37 @@
<div id="drilldown-widget"> <div id="drilldown-widget">
<div id="drilldown-widget-{{ unique }}" class="grid-stack-item" {% block widget_options %}{% endblock %}> <div id="drilldown-widget-{{ unique }}" class="grid-stack-item" {% block widget_options %}{% endblock %}>
<div class="grid-stack-item-content"> <div class="grid-stack-item-content">
<nav class="panel"> <nav class="panel">
<p class="panel-heading" style="padding: .2em; line-height: .5em;"> <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> <i class="fa-solid fa-arrows-up-down-left-right has-text-grey-light"></i>
{% block close_button %} {% block close_button %}
<i <i
class="fa-solid fa-xmark has-text-grey-light float-right" class="fa-solid fa-xmark has-text-grey-light float-right"
onclick='grid.removeWidget("drilldown-widget-{{ unique }}");'></i> onclick='grid.removeWidget("drilldown-widget-{{ unique }}");'></i>
{% endblock %} {% endblock %}
<i <i
class="fa-solid fa-arrows-minimize has-text-grey-light float-right" class="fa-solid fa-arrows-minimize has-text-grey-light float-right"
onclick='grid.compact();'></i> onclick='grid.compact();'></i>
{% block heading %} {% block heading %}
{% endblock %} {% endblock %}
</p> </p>
<article class="panel-block is-active"> <article class="panel-block is-active">
<div class="control"> <div class="control">
{% block panel_content %} {% block panel_content %}
{% endblock %} {% endblock %}
</div> </div>
</article> </article>
</nav> </nav>
</div>
</div> </div>
</div>
</div> </div>
<script> <script>
{% block custom_script %} {% block custom_script %}
{% endblock %} {% endblock %}
var widget_event = new Event('load-widget'); var widget_event = new Event('load-widget');
document.dispatchEvent(widget_event); document.dispatchEvent(widget_event);
{% block custom_script_end %} {% block custom_script_end %}
{% endblock %} {% endblock %}
</script> </script>

@ -11,7 +11,7 @@ exclude = '''
) )
''' '''
[tool.curlylint.rules] [tool.curlylint.rules]
indent = 2 #indent = 2
html_has_lang = 'en-GB' html_has_lang = 'en-GB'
# All role attributes must be valid. # All role attributes must be valid.
# See https://www.curlylint.org/docs/rules/aria_role. # See https://www.curlylint.org/docs/rules/aria_role.

Loading…
Cancel
Save