Skip to content

Commit

Permalink
78 project search functionality (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
uittenbroekrobbert authored Aug 15, 2024
2 parents 0ab57e4 + f770b95 commit 7614a1f
Show file tree
Hide file tree
Showing 23 changed files with 191 additions and 43 deletions.
2 changes: 1 addition & 1 deletion alembic.ini
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ keys = console
keys = generic

[logger_root]
level = WARN
level = INFO
handlers = console
qualname =

Expand Down
9 changes: 6 additions & 3 deletions amt/api/routes/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ async def get_root(
projects_service: Annotated[ProjectsService, Depends(ProjectsService)],
skip: int = Query(0, ge=0),
limit: int = Query(100, ge=1),
search: str = Query(""),
) -> HTMLResponse:
projects = projects_service.paginate(skip=skip, limit=limit)
projects = projects_service.paginate(skip=skip, limit=limit, search=search)
next = skip + limit

if request.state.htmx:
return templates.TemplateResponse(request, "projects/_list.html.j2", {"projects": projects, "next": next})
return templates.TemplateResponse(
request, "projects/_list.html.j2", {"projects": projects, "next": next, "search": search}
)

return templates.TemplateResponse(
request, "projects/index.html.j2", {"projects": projects, "next": next, "limit": limit}
request, "projects/index.html.j2", {"projects": projects, "next": next, "limit": limit, "search": search}
)


Expand Down
2 changes: 0 additions & 2 deletions amt/clients/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ def get_content(self, url: str) -> bytes:
"""
This method should implement getting the content of an instrument from given URL.
"""
...

@abstractmethod
def list_content(self, url: str = "") -> RepositoryContent:
"""
This method should implement getting list of instruments from given URL.
"""
...

def _get(self, url: str) -> httpx.Response:
"""
Expand Down
8 changes: 6 additions & 2 deletions amt/locale/base.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-07-26 13:53+0200\n"
"POT-Creation-Date: 2024-08-15 15:18+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.15.0\n"
"Generated-By: Babel 2.16.0\n"

#: amt/site/templates/header.html.j2:4
msgid "Algorithm Management Toolkit"
Expand Down Expand Up @@ -66,6 +66,10 @@ msgstr ""
msgid "Unknown"
msgstr ""

#: amt/site/templates/projects/index.html.j2:11
msgid "Find projects..."
msgstr ""

#: amt/site/templates/projects/new.html.j2:4
msgid "New Project"
msgstr ""
Expand Down
Binary file modified amt/locale/en_US/LC_MESSAGES/messages.mo
Binary file not shown.
8 changes: 6 additions & 2 deletions amt/locale/en_US/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-07-26 13:53+0200\n"
"POT-Creation-Date: 2024-08-15 15:18+0200\n"
"PO-Revision-Date: 2024-07-25 21:01+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en_US\n"
Expand All @@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.15.0\n"
"Generated-By: Babel 2.16.0\n"

#: amt/site/templates/header.html.j2:4
msgid "Algorithm Management Toolkit"
Expand Down Expand Up @@ -67,6 +67,10 @@ msgstr ""
msgid "Unknown"
msgstr ""

#: amt/site/templates/projects/index.html.j2:11
msgid "Find project..."
msgstr ""

#: amt/site/templates/projects/new.html.j2:4
msgid "New Project"
msgstr ""
Expand Down
Binary file modified amt/locale/nl_FY/LC_MESSAGES/messages.mo
Binary file not shown.
8 changes: 6 additions & 2 deletions amt/locale/nl_FY/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-07-26 13:53+0200\n"
"POT-Creation-Date: 2024-08-15 15:18+0200\n"
"PO-Revision-Date: 2024-07-25 21:01+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: nl_FY\n"
Expand All @@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.15.0\n"
"Generated-By: Babel 2.16.0\n"

#: amt/site/templates/header.html.j2:4
msgid "Algorithm Management Toolkit"
Expand Down Expand Up @@ -67,6 +67,10 @@ msgstr "Dien"
msgid "Unknown"
msgstr ""

#: amt/site/templates/projects/index.html.j2:11
msgid "Find project..."
msgstr "Fine projekt..."

#: amt/site/templates/projects/new.html.j2:4
msgid "New Project"
msgstr ""
Expand Down
Binary file modified amt/locale/nl_NL/LC_MESSAGES/messages.mo
Binary file not shown.
8 changes: 6 additions & 2 deletions amt/locale/nl_NL/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-07-26 13:53+0200\n"
"POT-Creation-Date: 2024-08-15 15:18+0200\n"
"PO-Revision-Date: 2024-07-25 21:01+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: nl_NL\n"
Expand All @@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.15.0\n"
"Generated-By: Babel 2.16.0\n"

#: amt/site/templates/header.html.j2:4
msgid "Algorithm Management Toolkit"
Expand Down Expand Up @@ -67,6 +67,10 @@ msgstr "Afgerond"
msgid "Unknown"
msgstr "Onbekend"

#: amt/site/templates/projects/index.html.j2:11
msgid "Find project..."
msgstr "Zoek project..."

#: amt/site/templates/projects/new.html.j2:4
msgid "New Project"
msgstr "Nieuw project"
Expand Down
12 changes: 8 additions & 4 deletions amt/repositories/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from sqlalchemy import func, select
from sqlalchemy.exc import NoResultFound, SQLAlchemyError
from sqlalchemy.orm import Session
from sqlalchemy_utils import escape_like # pyright: ignore[reportMissingTypeStubs, reportUnknownVariableType]

from amt.core.exceptions import RepositoryError, RepositoryNoResultFound
from amt.core.exceptions import RepositoryError
from amt.models import Project
from amt.repositories.deps import get_session

Expand Down Expand Up @@ -52,9 +53,12 @@ def find_by_id(self, project_id: int) -> Project:
except NoResultFound as e:
raise RepositoryError from e

def paginate(self, skip: int, limit: int) -> list[Project]:
def paginate(self, skip: int, limit: int, search: str) -> list[Project]:
try:
statement = select(Project).order_by(func.lower(Project.name)).offset(skip).limit(limit)
statement = select(Project)
if search != "":
statement = statement.filter(Project.name.ilike(f"%{escape_like(search)}%"))
statement = statement.order_by(func.lower(Project.name)).offset(skip).limit(limit)
return list(self.session.execute(statement).scalars())
except Exception as e:
raise RepositoryNoResultFound from e
raise RepositoryError from e
1 change: 0 additions & 1 deletion amt/services/instruments.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ def fetch_github_content(self, url: str) -> Instrument:
return Instrument(**data)

def fetch_instruments(self, urns: Sequence[str] | None = None) -> list[Instrument]:
# todo (Robbert): we 'type ignore' Task.sort_order because it works correctly, but pyright does not agree
content_list = self.fetch_github_content_list()

instruments: list[Instrument] = []
Expand Down
4 changes: 2 additions & 2 deletions amt/services/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ def create(self, project_new: ProjectNew) -> Project:

return project

def paginate(self, skip: int, limit: int) -> list[Project]:
return self.repository.paginate(skip=skip, limit=limit)
def paginate(self, skip: int, limit: int, search: str) -> list[Project]:
return self.repository.paginate(skip=skip, limit=limit, search=search)

def update(self, project: Project) -> Project:
return self.repository.save(project)
2 changes: 1 addition & 1 deletion amt/site/templates/projects/_list.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
<li><a href="/project/{{ project.id }}">{{ project.name }}</a></li>
{% endfor %}
{% if projects|length > 0 %}
<li hx-get="/projects/?skip={{next}}" hx-swap="outerHTML" hx-trigger="revealed">More</li>
<li hx-get="/projects/?skip={{ next }}&search={{ search }}" hx-swap="outerHTML" hx-trigger="revealed">More</li>
{% endif %}
22 changes: 21 additions & 1 deletion amt/site/templates/projects/index.html.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,27 @@

{% block content %}
<h1 class="margin-bottom--large">{% trans %}Projects{% endtrans %}</h1>
<ul class="project-list">

<form>
<label>
<input
size="100"
type="search"
placeholder="{% trans %}Find project...{% endtrans %}"
name="search"
hx-get="/projects/?skip=0"
hx-trigger="input changed delay:500ms, search"
hx-target="#project-search-results"
hx-indicator=".htmx-indicator"
hx-swap="innerHTML"
autocomplete="false"
id="project-search-input"
/>
</label>
<input type="reset" value="X" style="position: relative; margin-left: -30px" />
</form>

<ul class="project-list" id="project-search-results">
{% include 'projects/_list.html.j2' %}
</ul>

Expand Down
2 changes: 2 additions & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ services:
- PGDATA=/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "amt", "-U", "amt"]
ports:
- 5432:5432

db-admin:
image: dpage/pgadmin4:8.6
Expand Down
36 changes: 32 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ click = "^8.1.7"
python-ulid = "^2.7.0"
fastapi-csrf-protect = "^0.3.4"
sqlalchemy = "^2.0.32"
sqlalchemy-utils = "^0.41.2"


[tool.poetry.group.test.dependencies]
Expand Down
6 changes: 3 additions & 3 deletions tests/api/routes/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ def test_projects_get_root(client: TestClient) -> None:
response = client.get("/projects/")

assert response.status_code == 200
assert b'<ul class="project-list">' in response.content
assert b'<ul class="project-list" id="project-search-results">' in response.content


def test_projects_get_root_missing_slash(client: TestClient) -> None:
response = client.get("/projects")

assert response.status_code == 200
assert b'<ul class="project-list">' in response.content
assert b'<ul class="project-list" id="project-search-results">' in response.content


def test_projects_get_root_htmx(client: TestClient) -> None:
response = client.get("/projects/", headers={"HX-Request": "true"})

assert response.status_code == 200
assert b'<ul class="project-list">' not in response.content
assert b'<ul class="project-list" id="project-search-results">' not in response.content


def test_get_new_projects(client: TestClient, init_instruments: Generator[None, None, None]) -> None:
Expand Down
4 changes: 2 additions & 2 deletions tests/database_e2e_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def setup_database_e2e(session: Session) -> None:
db_e2e.given([task1, task2, task3])

projects: list[Project] = []
for _ in range(120):
projects.append(default_project())
for idx in range(120):
projects.append(default_project(name=f"Project {idx}"))

db_e2e.given([*projects])
8 changes: 4 additions & 4 deletions tests/e2e/test_scroll_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
def test_e2e_scroll_projects(page: Page) -> None:
page.goto("/projects/")

project_links = page.locator(".project-list > li", has_text="default project").count()
project_links = page.locator(".project-list > li").count()

assert 90 <= project_links <= 100
assert 90 <= project_links <= 101

with page.expect_response("/projects/?skip=100", timeout=3000) as response_info:
with page.expect_response("/projects/?skip=100&search=", timeout=3000) as response_info:
page.get_by_text("More").scroll_into_view_if_needed()

response = response_info.value
assert response.status == 200

project_links = page.locator(".project-list > li", has_text="default project").count()
project_links = page.locator(".project-list > li").count()
assert project_links > 100
Loading

0 comments on commit 7614a1f

Please sign in to comment.