Skip to content
Snippets Groups Projects
Commit dc46e48e authored by Martin Mareš's avatar Martin Mareš
Browse files

Místa: Vyhledávání

Na každé stránce místa je vyhledávací formulář, kterým lze hledat
jak místo podle kódu, tak mezi podřízenými místy podle názvu.

Closes #299.
parent 51cace33
No related branches found
No related tags found
1 merge request!128Místa: hledání a další drobná vylepšení
......@@ -2,6 +2,7 @@ from flask import render_template, g, redirect, url_for, flash, request
from flask_wtf import FlaskForm
import locale
from markupsafe import Markup
from sqlalchemy import func, and_
from sqlalchemy.orm import joinedload
from typing import List, Optional
import werkzeug.exceptions
......@@ -17,7 +18,12 @@ import mo.web.fields as mo_fields
import wtforms.validators as validators
@app.route('/org/place/<int:id>/')
class PlaceSearchForm(FlaskForm):
query = mo_fields.String(render_kw={'autofocus': True, 'placeholder': 'Kód nebo začátek názvu'})
submit = wtforms.SubmitField('Hledat')
@app.route('/org/place/<int:id>/', methods=('GET', 'POST'))
def org_place(id: int):
sess = db.get_session()
......@@ -25,6 +31,38 @@ def org_place(id: int):
if not place:
raise werkzeug.exceptions.NotFound()
search_form = PlaceSearchForm()
found_places = None
search_failed = False
search_limited = False
if search_form.validate_on_submit() and search_form.query.data:
query = search_form.query.data
found = db.get_place_by_code(query)
if found is not None:
return redirect(url_for('org_place', id=found.place_id))
max_places = 100
if '%' in query:
found_places = []
else:
found_places_q = (sess.query(db.Place)
.filter(func.lower(db.f_unaccent(db.Place.name)).like(func.lower(db.f_unaccent(query + '%'))))
.filter(db.Place.place_id != place.place_id))
if place.level > 0:
found_places_q = found_places_q.join(db.RegionDescendant, and_(db.RegionDescendant.region == place.place_id,
db.RegionDescendant.descendant == db.Place.place_id))
found_places = (found_places_q
.options(joinedload(db.Place.parent_place))
.order_by(db.Place.level, db.Place.name, db.Place.place_id)
.limit(max_places)
.all())
if not found_places:
search_failed = True
if len(found_places) == 1:
return redirect(url_for('org_place', id=found_places[0].place_id))
else:
search_limited = len(found_places) >= max_places
if place.type == db.PlaceType.school:
school = sess.query(db.School).get(place.place_id)
else:
......@@ -38,6 +76,8 @@ def org_place(id: int):
can_edit=rr.can_edit_place(place),
can_add_child=rr.can_add_place_child(place),
children=children,
search_form=search_form,
found_places=found_places, search_failed=search_failed, search_limited=search_limited,
)
......
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}{{ place.type_name().title() }}: {{ place.name }}{% endblock %}
{% block breadcrumbs %}
{{ place_breadcrumbs(place) }}
......@@ -35,6 +36,41 @@
{% endif %}
</div>
<h3>Vyhledávání</h3>
{% if search_failed %}
<div class='alert alert-danger' role='alert'>
Žádné vyhovující místo nenalezeno.
</div>
{% endif %}
{% if search_limited %}
<div class='alert alert-warning' role='alert'>
Nalezeno příliš mnoho míst, zobrazeno jen prvních {{ found_places|length }}.
</div>
{% endif %}
{{ wtf.quick_form(search_form, form_type='inline', button_map={'submit': 'primary'}) }}
{% if found_places %}
<table class=data>
<thead><tr>
<th>Kód
<th>Typ
<th>Název
</thead>
{% for p in found_places %}
<tr>
<td>{{ p.get_code() }}
<td>{{ p.type_name() }}
<td><a href='{{ url_for('org_place', id=p.place_id) }}'>{{ p.name_or_id() }}</a>
{% if p.parent_place.level > 0 %}
({{ p.parent_place.type_name() }} {{ p.parent_place.name_or_id() }})
{% endif %}
{% endfor %}
</table>
{% endif %}
{% if place.can_have_child() %}
<h3>Podřízená místa</h3>
{% if children %}
......@@ -42,14 +78,14 @@
<table class=data>
<thead><tr>
<th>Kód
<th>Název
<th>Typ
<th>Název
</thead>
{% for child in children %}
<tr>
<td>{{ child.get_code() }}
<td><a href='{{ url_for('org_place', id=child.place_id) }}'>{{ child.name or "#" + child.place_id|string }}</a>
<td>{{ child.type_name() }}
<td><a href='{{ url_for('org_place', id=child.place_id) }}'>{{ child.name_or_id() }}</a>
{% endfor %}
</table>
{% endif %}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment