mirror of
https://github.com/boostorg/website-v2.git
synced 2026-01-19 04:42:17 +00:00
🚜 WIP working search
* Bootstrapped API viewset to search libraries * Updated templates * Added htmx for search * Search results template to display results Issue: #88
This commit is contained in:
@@ -21,6 +21,7 @@ from libraries.views import (
|
||||
LibraryByCategory,
|
||||
LibraryDetail,
|
||||
)
|
||||
from libraries.api import LibrarySearchView
|
||||
from support.views import SupportView, ContactView
|
||||
from versions.api import VersionViewSet
|
||||
from versions.views import VersionList, VersionDetail
|
||||
@@ -29,6 +30,7 @@ router = routers.SimpleRouter()
|
||||
|
||||
router.register(r"users", UserViewSet, basename="users")
|
||||
router.register(r"versions", VersionViewSet, basename="versions")
|
||||
router.register(r"libraries", LibrarySearchView, basename="libraries")
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
|
||||
50
libraries/api.py
Normal file
50
libraries/api.py
Normal file
@@ -0,0 +1,50 @@
|
||||
from django.db.models import Q
|
||||
|
||||
from rest_framework import permissions
|
||||
from rest_framework import viewsets
|
||||
from rest_framework import serializers
|
||||
from rest_framework import renderers
|
||||
from rest_framework.response import Response
|
||||
|
||||
from .models import Library
|
||||
|
||||
|
||||
class LibrarySearchSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Library
|
||||
fields = (
|
||||
"name",
|
||||
"description",
|
||||
)
|
||||
|
||||
|
||||
class LibrarySearchView(viewsets.ModelViewSet):
|
||||
model = Library
|
||||
serializer_class = LibrarySearchSerializer
|
||||
permission_classes = [permissions.AllowAny]
|
||||
queryset = Library.objects.all()
|
||||
renderer_classes = (renderers.TemplateHTMLRenderer, )
|
||||
|
||||
def filter_queryset(self, queryset):
|
||||
"""
|
||||
This view should return a list of all the libraries that
|
||||
match the search params limited to 5 results
|
||||
"""
|
||||
value = self.request.query_params.get("q")
|
||||
f = (
|
||||
Q(name__icontains=value)
|
||||
| Q(description__icontains=value)
|
||||
| Q(categories__name__icontains=value)
|
||||
| Q(authors__first_name__icontains=value)
|
||||
| Q(authors__last_name__icontains=value)
|
||||
)
|
||||
return Library.objects.filter(f)[:5]
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(
|
||||
{"libraries": serializer.data},
|
||||
template_name="libraries/includes/search_results.html"
|
||||
)
|
||||
@@ -15,6 +15,7 @@
|
||||
"alpinejs": "^3.10.2",
|
||||
"autoprefixer": "^10.4.12",
|
||||
"cssnano": "^5.1.14",
|
||||
"htmx": "^0.0.2",
|
||||
"tailwindcss": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css" />
|
||||
<script defer src="https://unpkg.com/alpinejs@3.10.5/dist/cdn.min.js"></script>
|
||||
<script src="https://unpkg.com/htmx.org@1.8.5" integrity="sha384-7aHh9lqPYGYZ7sTHvzP1t3BAfLhYSTy9ArHdP3Xsr9/3TlGurYgcPBoFmXX2TX/w" crossorigin="anonymous"></script>
|
||||
{% block extra_head %}{% endblock %}
|
||||
|
||||
<style>
|
||||
|
||||
@@ -9,29 +9,28 @@
|
||||
<div class="fixed inset-0 bg-black bg-opacity-70 transition-opacity"></div>
|
||||
|
||||
<div class="fixed inset-0 overflow-y-auto p-4 sm:p-6 md:p-20">
|
||||
<div class="mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-20 overflow-hidden rounded-xl bg-charcoal shadow-2xl transition-all" x-on:click.away="showSearch = false">
|
||||
<div class="mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-20 overflow-hidden rounded-xl bg-charcoal shadow-2xl transition-all"
|
||||
x-on:click.away="showSearch = false"
|
||||
>
|
||||
<div class="relative">
|
||||
<!-- Heroicon name: outline/magnifying-glass -->
|
||||
<svg class="pointer-events-none absolute top-3.5 left-4 h-5 w-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
|
||||
</svg>
|
||||
<input type="text" id="librarySearch" class="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-white placeholder-gray-500 focus:ring-0 sm:text-sm" placeholder="Search...">
|
||||
<input type="text"
|
||||
id="q"
|
||||
name="q"
|
||||
class="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-white placeholder-gray-500 focus:ring-0 sm:text-sm"
|
||||
placeholder="Search..."
|
||||
hx-get="/api/v1/libraries/"
|
||||
hx-trigger="keyup changed delay:500ms, search"
|
||||
hx-target="#search_results"
|
||||
hx-indicator=".htmx-indicator"
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- Results, show/hide based on command palette state. -->
|
||||
<ul class="max-h-96 overflow-y-auto p-2 text-sm text-gray-400">
|
||||
<!-- Active: "bg-gray-800 text-white" -->
|
||||
<li class="group flex cursor-default select-none items-center rounded-md px-3 py-2">
|
||||
<!-- Active: "text-white", Not Active: "text-gray-500" -->
|
||||
<!-- Heroicon name: outline/folder -->
|
||||
<svg class="h-6 w-6 flex-none text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
|
||||
</svg>
|
||||
<span class="ml-3 flex-auto truncate">Dev Note: Results display here</span>
|
||||
<!-- Not Active: "hidden" -->
|
||||
<span class="ml-3 hidden flex-none text-gray-400">Jump to...</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="max-h-96 overflow-y-auto p-2 text-sm text-gray-400" id="search_results"></ul>
|
||||
|
||||
<!-- Empty state, show/hide based on command palette state. -->
|
||||
<div class="py-14 px-6 text-center sm:px-14">
|
||||
|
||||
14
templates/libraries/includes/search_results.html
Normal file
14
templates/libraries/includes/search_results.html
Normal file
@@ -0,0 +1,14 @@
|
||||
{% for library in libraries %}
|
||||
<li class="group flex cursor-default select-none items-center rounded-md px-3 py-2">
|
||||
<!-- Active: "text-white", Not Active: "text-gray-500" -->
|
||||
<!-- Heroicon name: outline/folder -->
|
||||
<svg class="h-6 w-6 flex-none text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 12.75V12A2.25 2.25 0 014.5 9.75h15A2.25 2.25 0 0121.75 12v.75m-8.69-6.44l-2.12-2.12a1.5 1.5 0 00-1.061-.44H4.5A2.25 2.25 0 002.25 6v12a2.25 2.25 0 002.25 2.25h15A2.25 2.25 0 0021.75 18V9a2.25 2.25 0 00-2.25-2.25h-5.379a1.5 1.5 0 01-1.06-.44z" />
|
||||
</svg>
|
||||
<span class="ml-3 flex-auto truncate" id="search_results">
|
||||
{{ library.name }}
|
||||
</span>
|
||||
<!-- Not Active: "hidden" -->
|
||||
<span class="ml-3 hidden flex-none text-gray-400">Jump to...</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
@@ -20,7 +20,7 @@
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-4 h-4"><path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
|
||||
</button>
|
||||
</span>
|
||||
<input @click="showSearch = true; $nextTick(() => { setTimeout(() => { document.getElementById('librarySearch').focus(); }, 300);});"
|
||||
<input @click="showSearch = true; $nextTick(() => { setTimeout(() => { document.getElementById('q').focus(); }, 300);});"
|
||||
type="search" name="q" class="w-full md:w-1/3 text-sm text-white bg-charcoal focus:text-charcoal text-orange px-3 py-2 rounded-md" type="text" value="" placeholder="Search Library" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -428,6 +428,11 @@ has@^1.0.3:
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
htmx@^0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/htmx/-/htmx-0.0.2.tgz#790b3cd816b74f9f2648326e5f4f8a9b320f9fb0"
|
||||
integrity sha512-FfUo3ynRYr6Ra4vqmS4Nq9g47607FSmvHYCOuU8bvbW8s4kPMhAmCbMBjuW2cEZI6DauaFNZKinfgV91cc9Feg==
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
|
||||
Reference in New Issue
Block a user