mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-15 00:03:28 +01:00
Make search page more intuitive (#794)
* Add date-range feedback for i18n * Make search page more intuitive and add help text * Add a clear-options button to the search page
This commit is contained in:
parent
cdab280669
commit
43e5c8bac0
@ -956,11 +956,11 @@ RenderCalendar.prototype.niceDateRange = function() {
|
||||
var from = this.queryInfo.searchParams.from;
|
||||
var to = this.queryInfo.searchParams.to;
|
||||
if (from && to) {
|
||||
return 'From ' + from + ' to ' + to;
|
||||
return [text.from, from, text.until, to].join(' ');
|
||||
} else if (from) {
|
||||
return 'From ' + from + ' until ' + 'present';
|
||||
return [text.from, from, text.until, text.present].join(' ');
|
||||
}
|
||||
return 'From earliest until ' + to;
|
||||
return [text.from, text.earliest, text.until, to].join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -14,17 +14,33 @@ var elemIds = {
|
||||
},
|
||||
dateTime: {
|
||||
from: 'dt-from',
|
||||
fromTime: 'ts-from',
|
||||
fromBad: 'dt-from-bad',
|
||||
to: 'dt-to',
|
||||
toTime: 'ts-to',
|
||||
toBad: 'dt-to-bad'
|
||||
},
|
||||
match: 'match-type-select',
|
||||
url: 'search-url',
|
||||
form: 'search-form',
|
||||
resultsNewWindow: 'open-results-new-window',
|
||||
advancedOptions: 'advanced-options'
|
||||
advancedOptions: 'advanced-options',
|
||||
clearOptions: 'clear-options',
|
||||
};
|
||||
|
||||
function clearOptions(event) {
|
||||
for (const field of [
|
||||
elemIds.match,
|
||||
elemIds.dateTime.from,
|
||||
elemIds.dateTime.fromTime,
|
||||
elemIds.dateTime.to,
|
||||
elemIds.dateTime.toTime,
|
||||
]) {
|
||||
document.getElementById(field).value = '';
|
||||
}
|
||||
clearFilters(event);
|
||||
}
|
||||
|
||||
function makeCheckDateRangeChecker(dtInputId, dtBadNotice) {
|
||||
var dtInput = document.getElementById(dtInputId);
|
||||
dtInput.onblur = function() {
|
||||
@ -138,11 +154,13 @@ function performQuery(url) {
|
||||
}
|
||||
var fromT = document.getElementById(elemIds.dateTime.from).value;
|
||||
if (fromT) {
|
||||
query.push('from=' + fromT.trim());
|
||||
fromT += document.getElementById(elemIds.dateTime.fromTime).value;
|
||||
query.push('from=' + fromT.replace(/[^0-9]/g, ''));
|
||||
}
|
||||
var toT = document.getElementById(elemIds.dateTime.to).value;
|
||||
if (toT) {
|
||||
query.push('to=' + toT.trim());
|
||||
toT += document.getElementById(elemIds.dateTime.toTime).value;
|
||||
query.push('to=' + toT.replace(/[^0-9]/g, ''));
|
||||
}
|
||||
var builtQuery = query.join('&');
|
||||
if (document.getElementById(elemIds.resultsNewWindow).checked) {
|
||||
@ -188,6 +206,7 @@ $(document).ready(function() {
|
||||
elemIds.dateTime.to,
|
||||
document.getElementById(elemIds.dateTime.toBad)
|
||||
);
|
||||
document.getElementById(elemIds.clearOptions).onclick = clearOptions;
|
||||
document.getElementById(elemIds.filtering.add).onclick = addFilter;
|
||||
document.getElementById(elemIds.filtering.clear).onclick = clearFilters;
|
||||
var searchURLInput = document.getElementById(elemIds.url);
|
||||
@ -195,9 +214,6 @@ $(document).ready(function() {
|
||||
form.addEventListener('submit', function(event) {
|
||||
submitForm(event, form, searchURLInput);
|
||||
});
|
||||
document.getElementById(elemIds.advancedOptions).onclick = function() {
|
||||
validateFields(form);
|
||||
}
|
||||
var filteringExpression = document.getElementById(elemIds.filtering.expression);
|
||||
filteringExpression.addEventListener("keypress", function(event) {
|
||||
if (event.key === "Enter") {
|
||||
|
216
pywb/templates/instructions.html
Normal file
216
pywb/templates/instructions.html
Normal file
@ -0,0 +1,216 @@
|
||||
<div class="modal fade" id="searchInstructions" tabindex="-1" role="dialog" aria-labelledby="searchInstructionsTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h6 class="modal-title text-muted" id="searchInstructionsTitle">{{ _("Search instructions") }}</h6>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="{{ _('Close') }}">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h5>{{ _("URL") }}</h5>
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}A URL consists of several parts:{%endtrans%}
|
||||
{%trans%}<code>protocol</code>://<code>host</code>:<code>port</code>/<code>path</code>?<code>query</code>{%endtrans%}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{%trans%}The <code>protocol://</code> prefix is ignored when searching as it's not part of the searchable data.{%endtrans%}
|
||||
</p>
|
||||
<p>
|
||||
{%trans%}A leading <kbd>www.</kbd> in the <code>host</code> will also be ignored for the same reason.{%endtrans%}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{%trans%}The <code>host</code> contains one or more parts separated by periods (<kbd>.</kbd>).{%endtrans%}
|
||||
{%trans%}The part before the first period is called the <code>hostname</code>.{%endtrans%}
|
||||
{%trans%}The part after the last period is the <code>top level domain</code>.{%endtrans%}
|
||||
{%trans%}Every part added to the left of the top level domain <code>sub-domain</code>.{%endtrans%}
|
||||
{%trans%}I.e. <code>x.y.z</code> is a <code>sub-domain</code> of <code>y.z</code>{%endtrans%}
|
||||
{%trans%}which in turn is a <code>sub-domain</code> of the <code>top level domain</code> <code>z</code>{%endtrans%}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{%trans%}See <em>Match Type</em> below for interpretations of the search string.{%endtrans%}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h5>{{ _("Results Display") }}</h5>
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}For the <em>Default</em> search mode, the results are shown in a calendar view unless a filter is also added.{%endtrans%}
|
||||
{%trans%}For all other cases the results will be displayed in a list.{%endtrans%}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h5>{{ _("Search Options") }}</h5>
|
||||
<h6>{{ _("Match Type") }}</h6>
|
||||
<p> {{ _("There are four different search modes:") }}</p>
|
||||
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<td><em>{{ _("Default") }}</em></td>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}In the default mode the exact URL (minus the ignored prefixes mentioned above) is searched for.{%endtrans%}
|
||||
{%trans%}If one leading or trailing wildcard asterisk (<kbd>*</kbd>) is added, see <em>Prefix</em> and <em>Domain</em> below.{%endtrans%}
|
||||
</p>
|
||||
<p class="text-muted">
|
||||
{%trans%}Any other asterisks will be considered literal parts of the search string.{%endtrans%}
|
||||
{%trans%}Hence, adding both a leading and a trailing wildcard asterisk is not possible.{%endtrans%}
|
||||
</p>
|
||||
|
||||
{%trans%}Example:{%endtrans%}
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>https://http.cat/206</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Default") }}</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=https://http.cat/206&match-type-select=');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=https://http.cat/206&match-type-select=', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><em>{{ _("Prefix") }}</em></td>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}This will return all URL:s that begin with the given string.{%endtrans%}
|
||||
{%trans%}It returns the same results as <em>Default</em> with a trailing wildcard asterisk.{%endtrans%}
|
||||
</p>
|
||||
|
||||
{%trans%}Examples:{%endtrans%}
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>https://http.cat/2</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Prefix") }}</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=https://http.cat/2&match-type-select=prefix');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=https://http.cat/2&match-type-select=prefix', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>https://http.cat/2*</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Default") }}</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=https://http.cat/2*&match-type-select=');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=https://http.cat/2*&match-type-select=', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><em>{{ _("Host") }}</em></td>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}This will ignore any path and query parts of the URL and return all URL:s with the specified <code>host</code> part.{%endtrans%}
|
||||
</p>
|
||||
|
||||
{%trans%}Example:{%endtrans%}
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>https://http.cat/</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Host") }}</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=https://http.cat/&match-type-select=host');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=https://http.cat/&match-type-select=host', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><em>{{ _("Domain") }}</em></td>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}This is similar to the previous but doesn't require the whole <code>host</code>.{%endtrans%}
|
||||
{%trans%}It returns the same results as <em>Default</em> with a leading wildcard asterisk and a period (i.e. <kbd>*.</kbd>).{%endtrans%}
|
||||
{%trans%}The leading wildcard matches zero or more <code>sub-domains</code> as well as zero or one <code>hostname</code>.{%endtrans%}
|
||||
</p>
|
||||
|
||||
{%trans%}Examples:{%endtrans%}
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>cat/</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Domain") }}</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=cat/&match-type-select=domain');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=cat/&match-type-select=domain', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>*.cat/</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Default") }}</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=*.cat/&match-type-select=');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=*.cat/&match-type-select=', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h6>{{ _("Date/Time Range") }}</h6>
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}One may specify a start and/or an end timestamp to further restrict the search - both are inclusive.{%endtrans%}
|
||||
{%trans%}The timestamps consist of a date and an optional time of day.{%endtrans%}
|
||||
{%trans%}The layout of these input fields are subject to which browser is used.{%endtrans%}
|
||||
</p>
|
||||
|
||||
{%trans%}Example:{%endtrans%}
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>https://http.cat/2</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Prefix") }}</strong></em> & <em>{{ _("From") }}: <strong>2022-02-02 09:00</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=https://http.cat/2&match-type-select=prefix&dt-from=2022-02-02&ts-from=09:00');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=https://http.cat/2&match-type-select=prefix&dt-from=2022-02-02&ts-from=09:00', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h6>{{ _("Filtering") }}</h6>
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<td>
|
||||
<p>
|
||||
{%trans%}Finally one may add extra filters for Mime Type, Status and URL.{%endtrans%}
|
||||
{%trans%}For each filter one needs to specify one of the three attributes, one of a set of relations and a string.{%endtrans%}
|
||||
{%trans%}If more than one filter is added, they will all be applied to the list of results.{%endtrans%}
|
||||
</p>
|
||||
<p class="text-muted">{%trans%}Remember to actually add the filter before submitting the search.{%endtrans%}</p>
|
||||
|
||||
{%trans%}Example:{%endtrans%}
|
||||
<p class="ml-5 text-lowercase">
|
||||
<em>{{ _("URL") }}: <strong>https://http.cat/2/</strong></em> & <em>{{ _("Match Type") }}: <strong>{{ _("Prefix") }}</strong></em> & <em>{{ _("Filtering") }}: <strong>{{ _("HTTP Status") }} {{ _("Is Not") }} "301"</strong></em>
|
||||
<span class="float-right">
|
||||
<button onclick="fillForm('search-url=https://http.cat/2&match-type-select=prefix&filter-by=status&filter-modifier==!=&filter-expression=301');" class="btn btn-outline-info" role="button" aria-label="{{ _('Fill') }}">{{ _('Fill') }}</button>
|
||||
<button onclick="fillForm('search-url=https://http.cat/2&match-type-select=prefix&filter-by=status&filter-modifier==!=&filter-expression=301', true);" class="btn btn-outline-primary" role="button" aria-label="{{ _('Search') }}">{{ _('Search') }}</button>
|
||||
</span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function fillForm(query, search = false) {
|
||||
$('#searchInstructions').modal('hide');
|
||||
$('#advancedOptions').collapse('show');
|
||||
for (const item of query.split('&')) {
|
||||
var pair = item.split('=');
|
||||
var field = document.getElementById(pair[0]);
|
||||
if (field) field.value = pair.slice(1).join('=');
|
||||
if (pair[0] == "filter-expression") addFilter(event);
|
||||
}
|
||||
if (search) $('#search-button').click();
|
||||
}
|
||||
</script>
|
@ -69,6 +69,10 @@
|
||||
'host': "{{ _('host') }}",
|
||||
'domain': "{{ _('domain') }}",
|
||||
},
|
||||
from: "{{ _('From') }}",
|
||||
until: "{{ _('until') }}",
|
||||
present: "{{ _('present') }}",
|
||||
earliest: "{{ _('earliest') }}",
|
||||
};
|
||||
|
||||
var filterMods = {
|
||||
|
@ -31,15 +31,20 @@
|
||||
<form class="needs-validation" id="search-form" novalidate>
|
||||
<div class="form-row">
|
||||
<div class="col-12">
|
||||
<label for="search-url" class="lead" aria-label="Search For Col">
|
||||
<label for="search-url" class="lead" aria-label="{{ _('Search Collection') }}">
|
||||
{% set coll_title = metadata.title if metadata and metadata.title else coll %}
|
||||
{% autoescape false %}
|
||||
{% trans %}Search the {{ coll_title }} collection by url:{% endtrans %}
|
||||
{% endautoescape %}
|
||||
</label>
|
||||
<input aria-label="url" aria-required="true" class="form-control form-control-lg" id="search-url"
|
||||
<a tabindex="0" class="btn btn-sm float-right btn-light" role="button" data-toggle="modal" data-target="#searchInstructions">{{ _('Help') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-12">
|
||||
<input aria-label="{{ _('URL') }}" aria-required="true" class="form-control form-control-lg" id="search-url"
|
||||
name="search" placeholder="{{ _('Enter a URL to search for') }}"
|
||||
title="{{ _('Enter a URL to search for') }}" type="search" required/>
|
||||
title="{{ _('Enter a URL to search for') }}" type="search" required autofocus />
|
||||
<div class="invalid-feedback">
|
||||
{% trans %}Please enter a URL{% endtrans %}
|
||||
</div>
|
||||
@ -53,23 +58,26 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<button type="submit" class="btn btn-outline-primary float-right" role="button" aria-label="Search">
|
||||
<button type="submit" id="search-button" class="btn btn-outline-primary float-right" role="button" aria-label="{{ _('Search') }}">
|
||||
{% trans %}Search{% endtrans %}
|
||||
</button>
|
||||
<button class="btn btn-outline-info float-right mr-3" type="button" role="button"
|
||||
data-toggle="collapse" data-target="#advancedOptions" id="advanced-options"
|
||||
aria-expanded="false" aria-controls="advancedOptions" aria-label="Advanced Search Options">
|
||||
{{ _('Advanced Search Options') }}
|
||||
aria-expanded="false" aria-controls="advancedOptions" aria-label="{{ _('Search Options') }}">
|
||||
{{ _('Search Options') }}
|
||||
</button>
|
||||
<button id="clear-options" class="btn btn-outline-warning float-right mr-3" type="button" role="button" aria-label="{{ _('Reset Options') }}">
|
||||
{{ _('Reset Options') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse mt-3" id="advancedOptions">
|
||||
<div class="form-group form-row">
|
||||
<label for="match-type-select" class="col-sm-2 col-form-label" aria-label="Match Type">
|
||||
<label for="match-type-select" class="col-sm-2 col-form-label" aria-label="{{ _('Match Type') }}">
|
||||
{{ _('Match Type:') }}
|
||||
</label>
|
||||
<select id="match-type-select" class="form-control form-control col-sm-6">
|
||||
<option value=""></option>
|
||||
<option value="">{% trans %}Default{% endtrans %}</option>
|
||||
<option value="prefix">{% trans %}Prefix{% endtrans %}</option>
|
||||
<option value="host">{% trans %}Host{% endtrans %}</option>
|
||||
<option value="domain">{% trans %}Domain{% endtrans %}</option>
|
||||
@ -77,57 +85,43 @@
|
||||
</div>
|
||||
<p style="cursor: help;">
|
||||
<span data-toggle="tooltip" data-placement="right"
|
||||
title="Restricts the results to the given date/time range (inclusive)">
|
||||
title="{{ _('Restricts the results to the given date/time range (inclusive)') }}">
|
||||
{{ _('Date/Time Range') }}
|
||||
</span>
|
||||
</p>
|
||||
<div class="form-row">
|
||||
<div class="col-6">
|
||||
<label class="sr-only" for="dt-from" aria-label="Date/Time Range From">{% trans %}From:{% endtrans %}</label>
|
||||
<label class="sr-only" for="dt-from" aria-label="{{ _('Date/Time Range From') }}">{% trans %}From:{% endtrans %}</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">{% trans %}From:{% endtrans %}</div>
|
||||
</div>
|
||||
<input id="dt-from" type="number" name="date-range-from" class="form-control"
|
||||
pattern="^\d{4,14}$">
|
||||
<div class="invalid-feedback" id="dt-from-bad">
|
||||
{% trans %}Please enter a valid <b>From</b> timestamp. Timestamps may be 4 <= ts <=14 digits{% endtrans %}
|
||||
</div>
|
||||
<input id="dt-from" type="date" placeholder="yyyy-mm-dd" name="date-range-from" class="form-control">
|
||||
<input id="ts-from" type="time" placeholder="hh:mm:ss" name="date-range-from-ts" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="sr-only" for="dt-to" aria-label="Date/Time Range To">{% trans %}To:{% endtrans %}</label>
|
||||
<label class="sr-only" for="dt-to" aria-label="{{ _('Date/Time Range To') }}">{% trans %}To:{% endtrans %}</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-text">{% trans %}To:{% endtrans %}</div>
|
||||
</div>
|
||||
<input id="dt-to" type="number" name="date-range-to" class="form-control" pattern="^\d{4,14}$">
|
||||
<div class="invalid-feedback" id="dt-to-bad">
|
||||
{% trans %}Please enter a valid <b>To</b> timestamp. Timestamps may be 4 <= ts <=14 digits{% endtrans %}
|
||||
</div>
|
||||
<input id="dt-to" type="date" placeholder="yyyy-mm-dd" name="date-range-to" class="form-control">
|
||||
<input id="ts-to" type="time" placeholder="hh:mm:ss" name="date-range-to-ts" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group mt-3">
|
||||
<div class="form-row">
|
||||
<div class="col-6">
|
||||
<div class="col-12">
|
||||
<p>{% trans %}Filtering{% endtrans %}</p>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button id="clear-filters" class="btn btn-outline-warning float-right" type="button">
|
||||
{% trans %}Clear Filters{% endtrans %}
|
||||
</button>
|
||||
<button id="add-filter" class="btn btn-outline-secondary float-right mr-2" type="button">
|
||||
{% trans %}Add Filter{% endtrans %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="col-6">
|
||||
<div class="row pb-1">
|
||||
<label for="filter-by" class="col-form-label col-3">{% trans %}By:{% endtrans %}</label>
|
||||
<select id="filter-by" class="form-control col-7">
|
||||
<option value="" selected></option>
|
||||
<option value="mime">{% trans %}Mime Type{% endtrans %}</option>
|
||||
<option value="status">{% trans %}Status{% endtrans %}</option>
|
||||
<option value="url">{% trans %}URL{% endtrans %}</option>
|
||||
@ -144,17 +138,24 @@
|
||||
<option value="=!~">{% trans %}Does Not Begin With{% endtrans %}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row pb-1">
|
||||
<label for="filter-expression" class="col-form-label col-3">{% trans %}Expr:{% endtrans %}</label>
|
||||
<input type="text" id="filter-expression" class="form-control col-7"
|
||||
placeholder="{% trans %}Enter an expression to filter by{% endtrans %}"
|
||||
>
|
||||
</div>
|
||||
<button id="add-filter" class="btn btn-outline-secondary mt-2" type="button">
|
||||
{% trans %}Add Filter{% endtrans %}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ul id="filter-list" class="filter-list">
|
||||
<li id="filtering-nothing">{% trans %}No Filter{% endtrans %}</li>
|
||||
</ul>
|
||||
<button id="clear-filters" class="btn btn-outline-warning float-right mr-2" type="button">
|
||||
{% trans %}Clear Filters{% endtrans %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -192,4 +193,5 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% include "instructions.html" %}
|
||||
{% endblock %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user