Improve chat experience and begin search implementation
This commit is contained in:
225
core/templates/partials/osint/list-table.html
Normal file
225
core/templates/partials/osint/list-table.html
Normal file
@@ -0,0 +1,225 @@
|
||||
{% include 'mixins/partials/notify.html' %}
|
||||
<div
|
||||
id="{{ osint_table_id }}"
|
||||
class="osint-table-shell"
|
||||
hx-get="{{ osint_refresh_url }}"
|
||||
hx-target="#{{ osint_table_id }}"
|
||||
hx-swap="outerHTML"
|
||||
{% if osint_event_name %}hx-trigger="{{ osint_event_name }} from:body"{% endif %}>
|
||||
|
||||
{% if osint_show_search %}
|
||||
<form
|
||||
method="get"
|
||||
action="{{ osint_search_url }}"
|
||||
class="osint-table-toolbar"
|
||||
hx-get="{{ osint_search_url }}"
|
||||
hx-target="#{{ osint_table_id }}"
|
||||
hx-swap="outerHTML">
|
||||
<div class="field has-addons is-flex-wrap-wrap">
|
||||
<div class="control is-expanded" style="min-width: 14rem;">
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
name="q"
|
||||
value="{{ osint_search_query }}"
|
||||
placeholder="Search {{ osint_title|lower }}...">
|
||||
</div>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="field">
|
||||
{% for field in osint_search_fields %}
|
||||
<option
|
||||
value="{{ field.value }}"
|
||||
{% if field.value == osint_search_field %}selected{% endif %}>
|
||||
{{ field.label }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-link is-light" type="submit">
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-light" href="{{ osint_search_url }}">
|
||||
Reset
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<div class="table-container osint-results-table-wrap">
|
||||
<table class="table is-fullwidth is-hoverable osint-results-table">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for column in osint_columns %}
|
||||
<th>
|
||||
{% if column.sortable %}
|
||||
<a
|
||||
class="osint-sort-link"
|
||||
href="{{ column.sort_url }}"
|
||||
hx-get="{{ column.sort_url }}"
|
||||
hx-target="#{{ osint_table_id }}"
|
||||
hx-swap="outerHTML">
|
||||
<span>{{ column.label }}</span>
|
||||
<span class="icon is-small">
|
||||
{% if column.is_sorted and column.is_desc %}
|
||||
<i class="fa-solid fa-sort-down"></i>
|
||||
{% elif column.is_sorted %}
|
||||
<i class="fa-solid fa-sort-up"></i>
|
||||
{% else %}
|
||||
<i class="fa-solid fa-sort"></i>
|
||||
{% endif %}
|
||||
</span>
|
||||
</a>
|
||||
{% else %}
|
||||
{{ column.label }}
|
||||
{% endif %}
|
||||
</th>
|
||||
{% endfor %}
|
||||
{% if osint_show_actions %}<th>Actions</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in osint_rows %}
|
||||
<tr>
|
||||
{% for cell in row.cells %}
|
||||
<td>
|
||||
{% if cell.kind == "id_copy" %}
|
||||
<a
|
||||
class="button is-small has-text-grey"
|
||||
onclick="window.prompt('Copy to clipboard: Ctrl+C, Enter', '{{ cell.value }}');">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-copy"></i>
|
||||
</span>
|
||||
<span>{{ cell.value }}</span>
|
||||
</a>
|
||||
{% elif cell.kind == "bool" %}
|
||||
{% if cell.value %}
|
||||
<span class="icon has-text-success">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="icon has-text-grey">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
{% elif cell.kind == "datetime" %}
|
||||
{% if cell.value %}
|
||||
{{ cell.value|date:"M j, Y P" }}
|
||||
{% else %}
|
||||
<span class="has-text-grey">-</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if cell.value or cell.value == 0 %}
|
||||
{{ cell.value }}
|
||||
{% else %}
|
||||
<span class="has-text-grey">-</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% if osint_show_actions %}
|
||||
<td>
|
||||
<div class="buttons are-small">
|
||||
{% for action in row.actions %}
|
||||
{% if action.mode == "hx-get" %}
|
||||
<button
|
||||
class="button"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-get="{{ action.url }}"
|
||||
hx-target="{{ action.target }}"
|
||||
hx-swap="innerHTML"
|
||||
title="{{ action.title }}">
|
||||
<span class="icon"><i class="{{ action.icon }}"></i></span>
|
||||
</button>
|
||||
{% elif action.mode == "hx-delete" %}
|
||||
<button
|
||||
class="button"
|
||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||
hx-delete="{{ action.url }}"
|
||||
hx-target="{{ action.target }}"
|
||||
hx-swap="innerHTML"
|
||||
{% if action.confirm %}hx-confirm="{{ action.confirm }}"{% endif %}
|
||||
title="{{ action.title }}">
|
||||
<span class="icon"><i class="{{ action.icon }}"></i></span>
|
||||
</button>
|
||||
{% elif action.mode == "link" %}
|
||||
<a class="button" href="{{ action.url }}" title="{{ action.title }}">
|
||||
<span class="icon"><i class="{{ action.icon }}"></i></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="{% if osint_show_actions %}{{ osint_columns|length|add:'1' }}{% else %}{{ osint_columns|length }}{% endif %}">
|
||||
<p class="has-text-grey">No results found.</p>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if osint_pagination.enabled %}
|
||||
<nav class="pagination is-small" role="navigation" aria-label="pagination">
|
||||
{% if osint_pagination.has_previous %}
|
||||
<a
|
||||
class="pagination-previous"
|
||||
href="{{ osint_pagination.previous_url }}"
|
||||
hx-get="{{ osint_pagination.previous_url }}"
|
||||
hx-target="#{{ osint_table_id }}"
|
||||
hx-swap="outerHTML">
|
||||
Previous
|
||||
</a>
|
||||
{% else %}
|
||||
<a class="pagination-previous is-disabled">Previous</a>
|
||||
{% endif %}
|
||||
|
||||
{% if osint_pagination.has_next %}
|
||||
<a
|
||||
class="pagination-next"
|
||||
href="{{ osint_pagination.next_url }}"
|
||||
hx-get="{{ osint_pagination.next_url }}"
|
||||
hx-target="#{{ osint_table_id }}"
|
||||
hx-swap="outerHTML">
|
||||
Next
|
||||
</a>
|
||||
{% else %}
|
||||
<a class="pagination-next is-disabled">Next</a>
|
||||
{% endif %}
|
||||
|
||||
<ul class="pagination-list">
|
||||
{% for page in osint_pagination.pages %}
|
||||
{% if page.ellipsis %}
|
||||
<li><span class="pagination-ellipsis">…</span></li>
|
||||
{% elif page.current %}
|
||||
<li><a class="pagination-link is-current">{{ page.number }}</a></li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a
|
||||
class="pagination-link"
|
||||
href="{{ page.url }}"
|
||||
hx-get="{{ page.url }}"
|
||||
hx-target="#{{ osint_table_id }}"
|
||||
hx-swap="outerHTML">
|
||||
{{ page.number }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<p class="help has-text-grey">
|
||||
{{ osint_result_count }} result{% if osint_result_count != 1 %}s{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
78
core/templates/partials/osint/search-panel.html
Normal file
78
core/templates/partials/osint/search-panel.html
Normal file
@@ -0,0 +1,78 @@
|
||||
<div class="box">
|
||||
<form
|
||||
class="osint-search-form"
|
||||
method="get"
|
||||
action="{{ osint_search_url }}"
|
||||
hx-get="{{ osint_search_url }}"
|
||||
hx-target="#osint-search-results"
|
||||
hx-swap="innerHTML">
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-4">
|
||||
<label class="label">Scope</label>
|
||||
<div class="select is-fullwidth">
|
||||
<select name="scope">
|
||||
{% for option in scope_options %}
|
||||
<option
|
||||
value="{{ option.value }}"
|
||||
{% if option.value == selected_scope %}selected{% endif %}>
|
||||
{{ option.label }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<label class="label">Field</label>
|
||||
<div class="select is-fullwidth">
|
||||
<select name="field">
|
||||
<option value="__all__" {% if selected_field == "__all__" %}selected{% endif %}>
|
||||
All Fields
|
||||
</option>
|
||||
{% for option in field_options %}
|
||||
<option
|
||||
value="{{ option.value }}"
|
||||
{% if option.value == selected_field %}selected{% endif %}>
|
||||
{{ option.label }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<label class="label">Rows Per Page</label>
|
||||
<div class="select is-fullwidth">
|
||||
<select name="per_page">
|
||||
<option value="10" {% if selected_per_page == 10 %}selected{% endif %}>10</option>
|
||||
<option value="20" {% if selected_per_page == 20 %}selected{% endif %}>20</option>
|
||||
<option value="50" {% if selected_per_page == 50 %}selected{% endif %}>50</option>
|
||||
<option value="100" {% if selected_per_page == 100 %}selected{% endif %}>100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-9">
|
||||
<label class="label">Search Query</label>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
name="q"
|
||||
value="{{ search_query }}"
|
||||
placeholder="Search text, values, or relation names...">
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<label class="label"> </label>
|
||||
<div class="buttons">
|
||||
<button class="button is-link is-light is-fullwidth" type="submit">
|
||||
Search
|
||||
</button>
|
||||
<a class="button is-light is-fullwidth" href="{{ osint_search_url }}">
|
||||
Reset
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="osint-search-results">
|
||||
{% include "partials/results_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user