Implement channel pane for insights

This commit is contained in:
Mark Veidemanis 2022-07-21 13:52:06 +01:00
parent 20d513bef1
commit 9de9ddff6f
Signed by: m
GPG Key ID: 5ACFCEED46C0904F
8 changed files with 299 additions and 377 deletions

View File

@ -32,7 +32,7 @@
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-content"> <div class="modal-content">
<div class="box"> <div class="box">
<div class="tabs is-toggle is-fullwidth" id="tabs"> <div class="tabs is-toggle is-fullwidth is-primary" id="tabs">
<ul> <ul>
<li class="is-active" data-tab="1"> <li class="is-active" data-tab="1">
<a> <a>
@ -64,7 +64,7 @@
<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"> <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>
@ -80,7 +80,7 @@
<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"> <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>
@ -96,7 +96,7 @@
<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"> <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>
@ -112,7 +112,7 @@
<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"> <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>

View File

@ -1,132 +0,0 @@
{% load index %}
<script>
var modal = document.querySelector('.modal'); // assuming you have only 1
var html = document.querySelector('html');
modal.querySelector('.modal-background').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});
modal.querySelector('.modal-close').addEventListener('click', function(e) {
e.preventDefault();
modal.classList.remove('is-active');
html.classList.remove('is-clipped');
});
var TABS = [...document.querySelectorAll('#tabs li')];
var CONTENT = [...document.querySelectorAll('#tab-content div')];
var ACTIVE_CLASS = 'is-active';
initTabs();
</script>
<style>
#tab-content div {
display: none;
}
#tab-content div.is-active {
display: block;
}
</style>
<div class="modal is-active is-clipped">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">
<div class="tabs is-toggle is-fullwidth" id="tabs">
<ul>
<li class="is-active" data-tab="1">
<a>
<span class="icon is-small"><i class="fa-solid fa-user"></i></span>
<span>Channels</span>
</a>
</li>
<li data-tab="2">
<a>
<span class="icon is-small"><i class="fa-solid fa-hashtag"></i></span>
<span>Users</span>
</a>
</li>
<li data-tab="3">
<a>
<span class="icon is-small"><i class="fa-solid fa-people"></i></span>
<span>Intersection</span>
</a>
</li>
<li data-tab="4">
<a>
<span class="icon is-small"><i class="fa-solid fa-hashtag"></i></span>
<span>Intersection</span>
</a>
</li>
</ul>
</div>
<div id="tab-content">
<div class="is-active" data-content="1">
<h4 class="subtitle is-4">Channels for {{ nick }} on {{ net }}</h4>
{% for channel in chans %}
<a class="panel-block">
<span class="panel-icon">
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
</span>
{{ channel }}
{% if nick in num_chans %}
<span class="tag">
{{ num_users|index:channel }}
</span>
{% endif %}
</a>
{% endfor %}
</div>
<div data-content="2">
<h4 class="subtitle is-4">Users on {{ channel }} for {{ net }}</h4>
{% for user in users %}
<a class="panel-block">
<span class="panel-icon">
<i class="fa-solid fa-user" aria-hidden="true"></i>
</span>
{{ user }}
{% if channel in num_users %}
<span class="tag">
{{ num_chans|index:user }}
</span>
{% endif %}
</a>
{% endfor %}
</div>
<div data-content="3">
<h4 class="subtitle is-4">Users sharing channels with {{ nick }} on {{ net }}</h4>
{% for user in inter_users %}
<a class="panel-block">
<span class="panel-icon">
<i class="fa-solid fa-user" aria-hidden="true"></i>
</span>
{{ user }}
{% if channel in num_users %}
<span class="tag">
{{ num_chans|index:user }}
</span>
{% endif %}
</a>
{% endfor %}
</div>
<div data-content="4">
<h4 class="subtitle is-4">Channels sharing users with {{ channel }} on {{ net }}</h4>
{% for channel in inter_chans %}
<a class="panel-block">
<span class="panel-icon">
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
</span>
{{ channel }}
{% if nick in num_chans %}
<span class="tag">
{{ num_users|index:channel }}
</span>
{% endif %}
</a>
{% endfor %}
</div>
</div>
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
</div>

View File

@ -79,7 +79,7 @@
hx-post="{% url 'search_drilldown' %}" hx-post="{% url 'search_drilldown' %}"
hx-trigger="click" hx-trigger="click"
hx-target="#results" hx-target="#results"
hx-swap="outerHTML"> hx-swap="innerHTML">
Search Search
</button> </button>
</div> </div>
@ -90,5 +90,6 @@
<div id="results"> <div id="results">
</div> </div>
<div id="modals-here">
</div>
{% endblock %} {% endblock %}

View File

@ -1,8 +1,7 @@
{% load static %} {% load static %}
{% load index %} {% load index %}
<div id="results"> {% if results is not None %}
{% if results is not None %}
<div style="display: none" id="jsonData" data-json="{{ data }}"> <div style="display: none" id="jsonData" data-json="{{ data }}">
</div> </div>
<div class="box"> <div class="box">
@ -114,7 +113,6 @@
class="button is-small"> class="button is-small">
Information Information
</button> </button>
<div id="modals-here"></div>
{% endif %} {% endif %}
</td> </td>
<td> <td>
@ -153,5 +151,4 @@
</div> </div>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div>

View File

@ -0,0 +1,28 @@
<div class="tile is-parent" id="chans1">
<div class="tile is-child ">
<div class="panel is-primary" style="height: 30rem; overflow: auto">
<p class="panel-heading">
Channels
</p>
{% for chan in chans %}
<a class="panel-block is-active">
<span class="panel-icon">
<i class="fa-solid fa-hashtag" aria-hidden="true"></i>
</span>
<span
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{% url 'modal_drilldown' %}"
hx-vals='{"net": "{{ net }}", "nick": "{{ nick }}", "channel": "{{ chan }}"}'
hx-target="#modals-here"
hx-trigger="click"
class="button is-small">
{{ chan }}
</span>
</a>
{% endfor %}
</div>
</div>
</div>

View File

@ -63,7 +63,7 @@
hx-post="{% url 'search_insights' %}" hx-post="{% url 'search_insights' %}"
hx-trigger="click" hx-trigger="click"
hx-target="#results" hx-target="#results"
hx-swap="outerHTML"> hx-swap="innerHTML">
Search Search
</button> </button>
</div> </div>
@ -76,16 +76,8 @@
</div> </div>
<div class="tile is-parent"> <article id="chans1">
<div class="tile is-child box"> </article>
<p> 2</p>
</div> </div>
</div> <div id="modals-here"></div>
</div>
{% endblock %} {% endblock %}

View File

@ -1,22 +1,25 @@
{% load static %} {% load static %}
{% load index %} {% load index %}
<div class="panel is-primary">
<div id="results"> <p class="panel-heading">
<div class="tile is-child box"> Information
</p>
<div class="panel-block is-active">
<div class="tile is-child">
{% if item is not None %} {% if item is not None %}
<div class="table-container"> <div class="table-container">
<table class="table is-fullwidth"> <table class="table is-fullwidth is-hoverable">
<tbody> <tbody>
<tr> <tr>
<th>src</th> <th>src</th>
<td> <td>
{% if item|index:'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|index:'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>
@ -27,25 +30,25 @@
<tr> <tr>
<th>nick</th> <th>nick</th>
<td> <td>
{% if item|index:'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|index:'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|index:'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|index:'nick'}} {{ item.nick }}
{% endif %} {% endif %}
{% if item|index:'num_chans' is not None %} {% if item.num_chans is not None %}
<span class="tag"> <span class="tag">
{{ item|index:'num_chans' }} {{ item.num_chans }}
</span> </span>
{% endif %} {% endif %}
</td> </td>
@ -67,7 +70,6 @@
class="button is-small"> class="button is-small">
Information Information
</button> </button>
<div id="modals-here"></div>
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
@ -80,4 +82,13 @@
</div> </div>
{% endif %} {% endif %}
</div> </div>
</div>
</div>
<div
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-vals='{"net": "{{ item.net }}", "nick": "{{ item.nick }}"}'
hx-post="{% url 'chans_insights' %}"
hx-trigger="load"
hx-target="#chans1"
hx-swap="outerHTML">
</div> </div>

View File

@ -22,7 +22,6 @@ class InsightsSearch(LoginRequiredMixin, View):
def post(self, request): def post(self, request):
if not request.user.has_plan(self.plan_name): if not request.user.has_plan(self.plan_name):
return HttpResponseForbidden() return HttpResponseForbidden()
results, context = query_single_result(request) results, context = query_single_result(request)
if not context: if not context:
return HttpResponseForbidden() return HttpResponseForbidden()
@ -32,10 +31,36 @@ class InsightsSearch(LoginRequiredMixin, View):
return HttpResponse("No results") return HttpResponse("No results")
class InsightsChannels(LoginRequiredMixin, APIView):
parser_classes = [FormParser]
template_name = "ui/insights/channels.html"
plan_name = "drilldown"
def post(self, request):
if not request.user.has_plan(self.plan_name):
return HttpResponseForbidden()
if "net" not in request.data:
return HttpResponse("No net")
if "nick" not in request.data:
return HttpResponse("No nick")
net = request.data["net"]
nick = request.data["nick"]
print("Insights channels item", nick)
chans = get_chans(net, [nick])
print("GET CHANS", chans)
if not chans:
return HttpResponseForbidden()
context = {"net": net, "nick": nick, "chans": chans}
if chans:
return render(request, self.template_name, context)
else:
return HttpResponse("No results")
class InsightsInfoModal(LoginRequiredMixin, APIView): class InsightsInfoModal(LoginRequiredMixin, APIView):
parser_classes = [FormParser] parser_classes = [FormParser]
plan_name = "drilldown" plan_name = "drilldown"
template_name = "modals/insights.html" template_name = "modals/drilldown.html"
def post(self, request): def post(self, request):
if not request.user.has_plan(self.plan_name): if not request.user.has_plan(self.plan_name):