Implement paginated sortable table for results
This commit is contained in:
parent
62133a8cbb
commit
44f05ad63b
|
@ -51,7 +51,10 @@ from core.views.manage.threshold.threshold import (
|
||||||
)
|
)
|
||||||
|
|
||||||
# Main tool pages
|
# Main tool pages
|
||||||
from core.views.ui.drilldown import Drilldown, ThresholdInfoModal # DrilldownTableView,
|
from core.views.ui.drilldown import ( # DrilldownTableView,; Drilldown,
|
||||||
|
DrilldownTableView,
|
||||||
|
ThresholdInfoModal,
|
||||||
|
)
|
||||||
from core.views.ui.insights import (
|
from core.views.ui.insights import (
|
||||||
Insights,
|
Insights,
|
||||||
InsightsChannels,
|
InsightsChannels,
|
||||||
|
@ -62,7 +65,8 @@ from core.views.ui.insights import (
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", Drilldown.as_view(), name="home"),
|
path("", DrilldownTableView.as_view(), name="home"),
|
||||||
|
path("search/", DrilldownTableView.as_view(), name="search"),
|
||||||
path("about/", About.as_view(), name="about"),
|
path("about/", About.as_view(), name="about"),
|
||||||
path("callback", Callback.as_view(), name="callback"),
|
path("callback", Callback.as_view(), name="callback"),
|
||||||
path("billing/", Billing.as_view(), name="billing"),
|
path("billing/", Billing.as_view(), name="billing"),
|
||||||
|
|
|
@ -299,7 +299,7 @@ def query_results(request, query_params, size=None):
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"query": query,
|
"query": query,
|
||||||
"results": results_parsed,
|
"object_list": results_parsed,
|
||||||
"card": results["hits"]["total"]["value"],
|
"card": results["hits"]["total"]["value"],
|
||||||
"took": results["took"],
|
"took": results["took"],
|
||||||
"redacted": results["redacted"],
|
"redacted": results["redacted"],
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<div>
|
<div>
|
||||||
<form method="POST" hx-post="{% url 'home' %}"
|
<form method="POST" hx-post="{% url 'search' %}"
|
||||||
hx-trigger="change"
|
hx-trigger="change"
|
||||||
hx-target="#results"
|
hx-target="#results"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<div class="control is-expanded has-icons-left">
|
<div class="control is-expanded has-icons-left">
|
||||||
<input
|
<input
|
||||||
hx-post="{% url 'home' %}"
|
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" id="query" name="query" value="{{ params.query }}" class="input" type="text" placeholder="msg: science AND nick: BillNye AND channel: #science">
|
hx-swap="innerHTML" id="query" name="query" value="{{ params.query }}" class="input" type="text" placeholder="msg: science AND nick: BillNye AND channel: #science">
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
<button
|
<button
|
||||||
id="search"
|
id="search"
|
||||||
class="button is-info is-fullwidth"
|
class="button is-info is-fullwidth"
|
||||||
hx-post="{% url 'home' %}"
|
hx-post="{% url 'search' %}"
|
||||||
hx-trigger="click"
|
hx-trigger="click"
|
||||||
hx-target="#results"
|
hx-target="#results"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
|
@ -365,8 +365,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div id="results">
|
<div id="results">
|
||||||
{% if results %}
|
<!-- {% if results %}
|
||||||
{% include 'ui/drilldown/results.html' %}
|
{% include 'ui/drilldown/results.html' %}
|
||||||
|
{% endif %} -->
|
||||||
|
{% if table %}
|
||||||
|
{% include 'ui/drilldown/table_results.html' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<i class="fa-solid fa-chart-mixed"></i>
|
<i class="fa-solid fa-chart-mixed"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="nowrap-child">
|
<div class="nowrap-child">
|
||||||
<p>fetched {{ results|length }} of {{ card }} hits in {{ took }}ms</p>
|
<p>fetched {{ table.data|length }} of {{ card }} hits in {{ took }}ms</p>
|
||||||
</div>
|
</div>
|
||||||
{% if exemption is not None %}
|
{% if exemption is not None %}
|
||||||
<div class="nowrap-child">
|
<div class="nowrap-child">
|
||||||
|
@ -24,6 +24,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="box">
|
||||||
|
<div style="height: 30rem">
|
||||||
|
<canvas id="volume"></canvas>
|
||||||
|
</div>
|
||||||
|
<script src="{% static 'chart.js' %}"></script>
|
||||||
|
</div>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
{% include 'ui/drilldown/table_results_partial.html' %}
|
{% include 'ui/drilldown/table_results_partial.html' %}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
{% extends 'django-tables2/bulma.html' %}
|
||||||
|
|
||||||
|
{% load django_tables2 %}
|
||||||
|
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block table.thead %}
|
||||||
|
{% if table.show_header %}
|
||||||
|
<thead {{ table.attrs.thead.as_html }}>
|
||||||
|
<tr>
|
||||||
|
{% for column in table.columns %}
|
||||||
|
<th
|
||||||
|
{{ column.attrs.th.as_html }}
|
||||||
|
hx-get="search/{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}&{{ uri }}"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-target="#results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-indicator=".progress"
|
||||||
|
style="cursor: pointer;">
|
||||||
|
{{ column.header }}
|
||||||
|
</th>
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock table.thead %}
|
||||||
|
|
||||||
|
{# Pagination block overrides #}
|
||||||
|
{% block pagination.previous %}
|
||||||
|
{% if table.page.has_previous %}
|
||||||
|
<li class="pagination-previous">
|
||||||
|
<div
|
||||||
|
hx-get="search/{% querystring table.prefixed_page_field=table.page.previous_page_number %}&{{ uri }}"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-target="#results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-indicator=".progress"
|
||||||
|
class="pagination-link">
|
||||||
|
<span aria-hidden="true">«</span>
|
||||||
|
{% trans 'previous' %}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock pagination.previous %}
|
||||||
|
|
||||||
|
{% block pagination.range %}
|
||||||
|
{% for p in table.page|table_page_range:table.paginator %}
|
||||||
|
<li class="page-item{% if table.page.number == p %} active{% endif %}">
|
||||||
|
<div
|
||||||
|
class="pagination-link"
|
||||||
|
{% if p != '...' %}hx-get="search/{% querystring table.prefixed_page_field=p %}&{{ uri }}"{% endif %}
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-target="#results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-indicator=".progress">
|
||||||
|
{{ p }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock pagination.range %}
|
||||||
|
{% if table.page.has_next %}
|
||||||
|
{% block pagination.next %}
|
||||||
|
<li class="pagination-next">
|
||||||
|
<div
|
||||||
|
hx-get="search/{% querystring table.prefixed_page_field=table.page.next_page_number %}&{{ uri }}"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-target="#results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-indicator=".progress"
|
||||||
|
class="pagination-link">
|
||||||
|
{% trans 'next' %}
|
||||||
|
<span aria-hidden="true">»</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endblock pagination.next %}
|
||||||
|
{% endif %}
|
|
@ -1,75 +1,163 @@
|
||||||
{% extends 'django-tables2/bulma.html' %}
|
|
||||||
|
|
||||||
{% load django_tables2 %}
|
{% load django_tables2 %}
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% load django_tables2_bulma_template %}
|
||||||
{% block table.thead %}
|
{% block table-wrapper %}
|
||||||
|
<div class="container">
|
||||||
|
{% block table %}
|
||||||
|
<table {% render_attrs table.attrs class="table is-striped is-hoverable is-fullwidth" %}>
|
||||||
|
{% block table.thead %}
|
||||||
{% if table.show_header %}
|
{% if table.show_header %}
|
||||||
<thead {{ table.attrs.thead.as_html }}>
|
<thead {% render_attrs table.attrs.thead class="" %}>
|
||||||
|
{% block table.thead.row %}
|
||||||
<tr>
|
<tr>
|
||||||
{% for column in table.columns %}
|
{% for column in table.columns %}
|
||||||
<th
|
{% block table.thead.th %}
|
||||||
{{ column.attrs.th.as_html }}
|
<th {% render_attrs column.attrs.th class="" %}>
|
||||||
hx-post="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}"
|
{% if column.orderable %}
|
||||||
|
{% if column.is_ordered %}
|
||||||
|
{% is_descending column.order_by as descending %}
|
||||||
|
{% if descending %}
|
||||||
|
<span aria-hidden="true">{% block table.desc_icon %}↓{% endblock table.desc_icon %}</span>
|
||||||
|
{% else %}
|
||||||
|
<span aria-hidden="true">{% block table.asc_icon %}↑{% endblock table.asc_icon %}</span>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span aria-hidden="true">{% block table.orderable_icon %}⥯{% endblock table.orderable_icon %}</span>
|
||||||
|
{% endif %}
|
||||||
|
<a
|
||||||
|
hx-get="search/{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}&{{ uri }}"
|
||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
hx-trigger="click"
|
hx-trigger="click"
|
||||||
hx-target="div.table-container"
|
hx-target="#results"
|
||||||
hx-swap="outerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-indicator=".progress"
|
hx-indicator=".progress"
|
||||||
style="cursor: pointer;">
|
style="cursor: pointer;">
|
||||||
{{ column.header }}
|
{{ column.header }}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{{ column.header }}
|
||||||
|
{% endif %}
|
||||||
</th>
|
</th>
|
||||||
|
{% endblock table.thead.th %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endblock table.thead.row %}
|
||||||
</thead>
|
</thead>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock table.thead %}
|
{% endblock table.thead %}
|
||||||
|
{% block table.tbody %}
|
||||||
{# Pagination block overrides #}
|
<tbody {{ table.attrs.tbody.as_html }}>
|
||||||
{% block pagination.previous %}
|
{% for row in table.paginated_rows %}
|
||||||
<li class="previous page-item">
|
{% block table.tbody.row %}
|
||||||
<div
|
<tr {{ row.attrs.as_html }}>
|
||||||
hx-post="{% querystring table.prefixed_page_field=table.page.previous_page_number %}"
|
{% for column, cell in row.items %}
|
||||||
|
{% block table.tbody.td %}
|
||||||
|
<td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
|
||||||
|
{% endblock table.tbody.td %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endblock table.tbody.row %}
|
||||||
|
{% empty %}
|
||||||
|
{% if table.empty_text %}
|
||||||
|
{% block table.tbody.empty_text %}
|
||||||
|
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
|
||||||
|
{% endblock table.tbody.empty_text %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
{% endblock table.tbody %}
|
||||||
|
{% block table.tfoot %}
|
||||||
|
{% if table.has_footer %}
|
||||||
|
<tfoot {{ table.attrs.tfoot.as_html }}>
|
||||||
|
{% block table.tfoot.row %}
|
||||||
|
<tr>
|
||||||
|
{% for column in table.columns %}
|
||||||
|
{% block table.tfoot.td %}
|
||||||
|
<td {{ column.attrs.tf.as_html }}>{{ column.footer }}</td>
|
||||||
|
{% endblock table.tfoot.td %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endblock table.tfoot.row %}
|
||||||
|
</tfoot>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock table.tfoot %}
|
||||||
|
</table>
|
||||||
|
{% endblock table %}
|
||||||
|
{% block pagination %}
|
||||||
|
{% if table.page and table.paginator.num_pages > 1 %}
|
||||||
|
<nav class="pagination is-justify-content-flex-end" role="navigation" aria-label="pagination">
|
||||||
|
{% block pagination.previous %}
|
||||||
|
<a
|
||||||
|
class="pagination-previous is-flex-grow-0 {% if not table.page.has_previous %}is-hidden-mobile{% endif %}"
|
||||||
|
{% if table.page.has_previous %}
|
||||||
|
hx-get="search/{% querystring table.prefixed_page_field=table.page.previous_page_number %}&{{ uri }}"
|
||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
hx-trigger="click"
|
hx-trigger="click"
|
||||||
hx-target="div.table-container"
|
hx-target="#results"
|
||||||
hx-swap="outerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-indicator=".progress"
|
hx-indicator=".progress"
|
||||||
class="page-link">
|
{% else %}
|
||||||
|
href="#"
|
||||||
|
disabled
|
||||||
|
{% endif %}
|
||||||
|
style="order:1;">
|
||||||
|
{% block pagination.previous.text %}
|
||||||
<span aria-hidden="true">«</span>
|
<span aria-hidden="true">«</span>
|
||||||
{% trans 'previous' %}
|
{% endblock pagination.previous.text %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
{% endblock pagination.previous %}
|
||||||
{% endblock pagination.previous %}
|
{% block pagination.next %}
|
||||||
{% block pagination.range %}
|
<a class="pagination-next is-flex-grow-0 {% if not table.page.has_next %}is-hidden-mobile{% endif %}"
|
||||||
{% for p in table.page|table_page_range:table.paginator %}
|
{% if table.page.has_next %}
|
||||||
<li class="page-item{% if table.page.number == p %} active{% endif %}">
|
hx-get="search/{% querystring table.prefixed_page_field=table.page.next_page_number %}&{{ uri }}"
|
||||||
<div
|
|
||||||
class="page-link"
|
|
||||||
{% if p != '...' %}hx-post="{% querystring table.prefixed_page_field=p %}"{% endif %}
|
|
||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
hx-trigger="click"
|
hx-trigger="click"
|
||||||
hx-target="div.table-container"
|
hx-target="#results"
|
||||||
hx-swap="outerHTML"
|
hx-swap="innerHTML"
|
||||||
hx-indicator=".progress">
|
hx-indicator=".progress"
|
||||||
|
{% else %}
|
||||||
|
href="#"
|
||||||
|
disabled
|
||||||
|
{% endif %}
|
||||||
|
style="order:3;"
|
||||||
|
>
|
||||||
|
{% block pagination.next.text %}
|
||||||
|
<span aria-hidden="true">»</span>
|
||||||
|
{% endblock pagination.next.text %}
|
||||||
|
</a>
|
||||||
|
{% endblock pagination.next %}
|
||||||
|
{% if table.page.has_previous or table.page.has_next %}
|
||||||
|
{% block pagination.range %}
|
||||||
|
<ul class="pagination-list is-flex-grow-0" style="order:2;">
|
||||||
|
{% for p in table.page|table_page_range:table.paginator %}
|
||||||
|
<li>
|
||||||
|
<a class="pagination-link {% if p == table.page.number %}is-current{% endif %}"
|
||||||
|
aria-label="Page {{ p }}" block
|
||||||
|
{% if p == table.page.number %}aria-current="page"{% endif %}
|
||||||
|
{% if p == table.page.number %}
|
||||||
|
href="#"
|
||||||
|
{% else %}
|
||||||
|
hx-get="search/{% querystring table.prefixed_page_field=p %}&{{ uri }}"
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-trigger="click"
|
||||||
|
hx-target="#results"
|
||||||
|
hx-swap="innerHTML"
|
||||||
|
hx-indicator=".progress"
|
||||||
|
{% endif %}
|
||||||
|
>
|
||||||
|
{% if p == '...' %}
|
||||||
|
<span class="pagination-ellipsis">…</span>
|
||||||
|
{% else %}
|
||||||
{{ p }}
|
{{ p }}
|
||||||
</div>
|
{% endif %}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock pagination.range %}
|
</ul>
|
||||||
{% block pagination.next %}
|
{% endblock pagination.range %}
|
||||||
<li class="next page-item">
|
{% endif %}
|
||||||
<div
|
</nav>
|
||||||
hx-post="{% querystring table.prefixed_page_field=table.page.next_page_number %}"
|
{% endif %}
|
||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
{% endblock pagination %}
|
||||||
hx-trigger="click"
|
|
||||||
hx-target="div.table-container"
|
|
||||||
hx-swap="outerHTML"
|
|
||||||
hx-indicator=".progress"
|
|
||||||
class="page-link">
|
|
||||||
{% trans 'next' %}
|
|
||||||
<span aria-hidden="true">»</span>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
{% endblock table-wrapper %}
|
||||||
{% endblock pagination.next %}
|
|
|
@ -6,7 +6,7 @@ from django.http import HttpResponse, JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django_tables2 import SingleTableMixin
|
from django_tables2 import SingleTableView
|
||||||
from rest_framework.parsers import FormParser
|
from rest_framework.parsers import FormParser
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
@ -20,30 +20,6 @@ from core.lib.threshold import (
|
||||||
from core.views.ui.tables import DrilldownTable
|
from core.views.ui.tables import DrilldownTable
|
||||||
|
|
||||||
|
|
||||||
class DrilldownTableView(View, SingleTableMixin):
|
|
||||||
table_class = DrilldownTable
|
|
||||||
template_name = "ui/drilldown/table_results.html"
|
|
||||||
paginate_by = 5
|
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
context = query_results(request)
|
|
||||||
table = DrilldownTable(context["results"])
|
|
||||||
context["table"] = table
|
|
||||||
del context["results"]
|
|
||||||
if "message" in context:
|
|
||||||
return render(request, self.template_name, context)
|
|
||||||
|
|
||||||
if self.request.htmx:
|
|
||||||
template_name = "ui/drilldown/table_results.html"
|
|
||||||
else:
|
|
||||||
template_name = "ui/drilldown/table_results_partial.html"
|
|
||||||
|
|
||||||
if context:
|
|
||||||
return render(request, template_name, context)
|
|
||||||
else:
|
|
||||||
return HttpResponse("No results")
|
|
||||||
|
|
||||||
|
|
||||||
def parse_dates(dates):
|
def parse_dates(dates):
|
||||||
spl = dates.split(" - ")
|
spl = dates.split(" - ")
|
||||||
if all(spl):
|
if all(spl):
|
||||||
|
@ -76,12 +52,52 @@ def create_tags(query):
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
|
||||||
def drilldown_search(request):
|
def make_table(context):
|
||||||
template_name = "ui/drilldown/results.html"
|
table = DrilldownTable(context["object_list"])
|
||||||
|
context["table"] = table
|
||||||
|
# del context["results"]
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
def make_graph(results):
|
||||||
|
graph = json.dumps(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"text": item.get("msg", None) or item.get("id"),
|
||||||
|
"nick": item.get("nick", None),
|
||||||
|
"value": item.get("sentiment", None) or None,
|
||||||
|
"date": item.get("ts"),
|
||||||
|
}
|
||||||
|
for item in results
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return graph
|
||||||
|
|
||||||
|
|
||||||
|
def drilldown_search(request, return_context=False, template=None):
|
||||||
|
if not template:
|
||||||
|
template_name = "ui/drilldown/table_results.html"
|
||||||
|
else:
|
||||||
|
template_name = template
|
||||||
|
if request.user.is_anonymous:
|
||||||
|
sizes = settings.OPENSEARCH_MAIN_SIZES_ANON
|
||||||
|
else:
|
||||||
|
sizes = settings.OPENSEARCH_MAIN_SIZES
|
||||||
|
|
||||||
if request.GET:
|
if request.GET:
|
||||||
|
print("GET")
|
||||||
|
if not request.htmx:
|
||||||
|
print("NOT REQUEST HTMX")
|
||||||
|
template_name = "ui/drilldown/drilldown.html"
|
||||||
query_params = request.GET.dict()
|
query_params = request.GET.dict()
|
||||||
elif request.POST:
|
elif request.POST:
|
||||||
|
print("POST")
|
||||||
query_params = request.POST.dict()
|
query_params = request.POST.dict()
|
||||||
|
else:
|
||||||
|
print("ELSE")
|
||||||
|
template_name = "ui/drilldown/drilldown.html"
|
||||||
|
context = {"sizes": sizes}
|
||||||
|
return render(request, template_name, context)
|
||||||
|
|
||||||
# Parse the dates
|
# Parse the dates
|
||||||
if "dates" in query_params:
|
if "dates" in query_params:
|
||||||
|
@ -99,54 +115,126 @@ def drilldown_search(request):
|
||||||
context = query_results(request, query_params)
|
context = query_results(request, query_params)
|
||||||
elif request.POST:
|
elif request.POST:
|
||||||
context = query_results(request, query_params)
|
context = query_results(request, query_params)
|
||||||
|
print("QUERY PARAMS", query_params)
|
||||||
|
|
||||||
# Turn the query into tags for populating the taglist
|
# Turn the query into tags for populating the taglist
|
||||||
|
if "query" in query_params:
|
||||||
tags = create_tags(query_params["query"])
|
tags = create_tags(query_params["query"])
|
||||||
context["tags"] = tags
|
context["tags"] = tags
|
||||||
|
|
||||||
context["params"] = query_params
|
context["params"] = query_params
|
||||||
if "message" in context:
|
if "message" in context:
|
||||||
|
print("MESSAGE IN CONTEXT")
|
||||||
return render(request, template_name, context)
|
return render(request, template_name, context)
|
||||||
|
|
||||||
context["data"] = json.dumps(
|
# Create data for chart.js sentiment graph
|
||||||
[
|
graph = make_graph(context["object_list"])
|
||||||
{
|
context["data"] = graph
|
||||||
"text": item.get("msg", None) or item.get("id"),
|
print("MADE GRAPH")
|
||||||
"nick": item.get("nick", None),
|
|
||||||
"value": item.get("sentiment", None) or None,
|
|
||||||
"date": item.get("ts"),
|
|
||||||
}
|
|
||||||
for item in context["results"]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
if context:
|
if context:
|
||||||
response = render(request, template_name, context)
|
context["sizes"] = sizes
|
||||||
if request.GET:
|
context = make_table(context)
|
||||||
return context
|
|
||||||
elif request.POST:
|
# URI we're passing to the template for linking
|
||||||
|
if "csrfmiddlewaretoken" in query_params:
|
||||||
del query_params["csrfmiddlewaretoken"]
|
del query_params["csrfmiddlewaretoken"]
|
||||||
url_params = urllib.parse.urlencode(query_params)
|
url_params = urllib.parse.urlencode(query_params)
|
||||||
|
context["client_uri"] = url_params
|
||||||
|
|
||||||
|
# URI we're passing to the template for linking, table fields removed
|
||||||
|
table_fields = ["page", "sort"]
|
||||||
|
clean_params = {k: v for k, v in query_params.items() if k not in table_fields}
|
||||||
|
clean_url_params = urllib.parse.urlencode(clean_params)
|
||||||
|
context["uri"] = clean_url_params
|
||||||
|
|
||||||
|
response = render(request, template_name, context)
|
||||||
|
if request.GET:
|
||||||
|
print("IS GET")
|
||||||
|
if request.htmx:
|
||||||
|
print("IS HTMX PUSHING", url_params)
|
||||||
response["HX-Push"] = reverse("home") + "?" + url_params
|
response["HX-Push"] = reverse("home") + "?" + url_params
|
||||||
|
elif request.POST:
|
||||||
|
print("IS POST")
|
||||||
|
print("TEMPLATE", template_name)
|
||||||
|
response["HX-Push"] = reverse("home") + "?" + url_params
|
||||||
|
if return_context:
|
||||||
|
return context
|
||||||
return response
|
return response
|
||||||
else:
|
else:
|
||||||
|
print("NO RESULTS", context)
|
||||||
return HttpResponse("No results")
|
return HttpResponse("No results")
|
||||||
|
|
||||||
|
|
||||||
|
class DrilldownTableView(SingleTableView):
|
||||||
|
table_class = DrilldownTable
|
||||||
|
template_name = "ui/drilldown/table_results.html"
|
||||||
|
paginate_by = 5
|
||||||
|
|
||||||
|
def get_queryset(self, request, **kwargs):
|
||||||
|
print("QUERYSET KWARGS", kwargs)
|
||||||
|
context = drilldown_search(request, return_context=True)
|
||||||
|
# Save the context as we will need to merge other attributes later
|
||||||
|
self.context = context
|
||||||
|
print(
|
||||||
|
"VIEW CONTEXT",
|
||||||
|
{k: v for k, v in context.items() if k not in ["object_list", "data"]},
|
||||||
|
)
|
||||||
|
if "object_list" in context:
|
||||||
|
return context["object_list"]
|
||||||
|
else:
|
||||||
|
print("NO OBJ LIST IN CONTEXT", context)
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
self.object_list = self.get_queryset(request)
|
||||||
|
allow_empty = self.get_allow_empty()
|
||||||
|
|
||||||
|
if not allow_empty:
|
||||||
|
# When pagination is enabled and object_list is a queryset,
|
||||||
|
# it's better to do a cheap query than to load the unpaginated
|
||||||
|
# queryset in memory.
|
||||||
|
if self.get_paginate_by(self.object_list) is not None and hasattr(
|
||||||
|
self.object_list, "exists"
|
||||||
|
):
|
||||||
|
is_empty = not self.object_list.exists() # noqa
|
||||||
|
else:
|
||||||
|
is_empty = not self.object_list # noqa
|
||||||
|
context = self.get_context_data()
|
||||||
|
if isinstance(self.context, HttpResponse):
|
||||||
|
return self.context
|
||||||
|
print(
|
||||||
|
"TABLE CONTEXT",
|
||||||
|
{k: v for k, v in context.items() if k not in ["object_list", "data"]},
|
||||||
|
)
|
||||||
|
for k, v in self.context.items():
|
||||||
|
if k not in context:
|
||||||
|
context[k] = v
|
||||||
|
print(
|
||||||
|
"FINAL CONTEXT",
|
||||||
|
{k: v for k, v in context.items() if k not in ["object_list", "data"]},
|
||||||
|
)
|
||||||
|
if request.method == "GET":
|
||||||
|
if not request.htmx:
|
||||||
|
print("NOT REQUEST HTMX")
|
||||||
|
self.template_name = "ui/drilldown/drilldown.html"
|
||||||
|
response = self.render_to_response(context)
|
||||||
|
# if not request.method == "GET":
|
||||||
|
if "client_uri" in context:
|
||||||
|
print("PUSHING CLIENT URI", context["client_uri"])
|
||||||
|
response["HX-Push"] = reverse("home") + "?" + context["client_uri"]
|
||||||
|
return response
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
return self.get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Drilldown(View):
|
class Drilldown(View):
|
||||||
template_name = "ui/drilldown/drilldown.html"
|
template_name = "ui/drilldown/drilldown.html"
|
||||||
plan_name = "drilldown"
|
plan_name = "drilldown"
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
if request.user.is_anonymous:
|
return drilldown_search(request)
|
||||||
sizes = settings.OPENSEARCH_MAIN_SIZES_ANON
|
|
||||||
else:
|
|
||||||
sizes = settings.OPENSEARCH_MAIN_SIZES
|
|
||||||
|
|
||||||
context = {}
|
|
||||||
if request.GET:
|
|
||||||
context = drilldown_search(request)
|
|
||||||
context["sizes"] = sizes
|
|
||||||
return render(request, self.template_name, context)
|
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
return drilldown_search(request)
|
return drilldown_search(request)
|
||||||
|
|
|
@ -32,3 +32,5 @@ class DrilldownTable(Table):
|
||||||
status = Column()
|
status = Column()
|
||||||
user = Column()
|
user = Column()
|
||||||
version_sentiment = Column()
|
version_sentiment = Column()
|
||||||
|
template_name = "ui/drilldown/table_results.html"
|
||||||
|
paginate_by = 5
|
||||||
|
|
Loading…
Reference in New Issue