This commit is contained in:
j3d1 2024-07-18 21:11:53 +02:00
parent af00daca51
commit 1c9afb6bad
5 changed files with 54 additions and 24 deletions

View file

@ -1,4 +1,4 @@
from django.urls import path from django.urls import re_path
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from rest_framework import routers, viewsets from rest_framework import routers, viewsets
from rest_framework.decorators import api_view, permission_classes from rest_framework.decorators import api_view, permission_classes
@ -109,8 +109,12 @@ router.register(r'boxes', ContainerViewSet, basename='boxes')
router.register(r'box', ContainerViewSet, basename='boxes') router.register(r'box', ContainerViewSet, basename='boxes')
urlpatterns = router.urls + [ urlpatterns = router.urls + [
path('<event_slug>/items/', item), # path('<event_slug>/items/', item),
path('<event_slug>/items/<query>/', search_items), # path('<event_slug>/items/<query>/', search_items),
path('<event_slug>/item/', item), # path('<event_slug>/item/', item),
path('<event_slug>/item/<id>/', item_by_id), # path('<event_slug>/item/<id>/', item_by_id),
re_path(r'^(?P<event_slug>[\w-]+)/items/$', item, name='item'),
re_path(r'^(?P<event_slug>[\w-]+)/items/(?P<query>[-A-Za-z0-9+/]*={0,3})/$', search_items, name='search_items'),
re_path(r'^(?P<event_slug>[\w-]+)/item/$', item, name='item'),
re_path(r'^(?P<event_slug>[\w-]+)/item/(?P<id>\d+)/$', item_by_id, name='item_by_id'),
] ]

View file

@ -152,10 +152,13 @@ router.register(r'tickets', IssueViewSet, basename='issues')
# router.register(r'comments', CommentViewSet, basename='comments') # router.register(r'comments', CommentViewSet, basename='comments')
router.register(r'shipping_vouchers', ShippingVoucherViewSet, basename='shipping_vouchers') router.register(r'shipping_vouchers', ShippingVoucherViewSet, basename='shipping_vouchers')
# [-A-Za-z0-9+/]*={0,3}
urlpatterns = ([ urlpatterns = ([
re_path(r'tickets/states/$', get_available_states, name='get_available_states'), re_path(r'tickets/states/$', get_available_states, name='get_available_states'),
re_path(r'^tickets/(?P<pk>\d+)/reply/$', reply, name='reply'), re_path(r'^tickets/(?P<pk>\d+)/reply/$', reply, name='reply'),
re_path(r'^tickets/(?P<pk>\d+)/comment/$', add_comment, name='add_comment'), re_path(r'^tickets/(?P<pk>\d+)/comment/$', add_comment, name='add_comment'),
re_path(r'^(?P<event_slug>[\w-]+)/tickets/manual/$', manual_ticket, name='manual_ticket'), re_path(r'^(?P<event_slug>[\w-]+)/tickets/manual/$', manual_ticket, name='manual_ticket'),
re_path(r'^(?P<event_slug>[\w-]+)/tickets/(?P<query>.+)/$', search_issues, name='search_issues'), re_path(r'^(?P<event_slug>[\w-]+)/tickets/(?P<query>[-A-Za-z0-9+/]*={0,3})/$', search_issues,
name='search_issues'),
] + router.urls) ] + router.urls)

View file

@ -3,6 +3,7 @@ from datetime import datetime, timedelta
from django.test import TestCase, Client from django.test import TestCase, Client
from authentication.models import ExtendedUser from authentication.models import ExtendedUser
from inventory.models import Event
from mail.models import Email, EmailAttachment from mail.models import Email, EmailAttachment
from tickets.models import IssueThread, StateChange, Comment from tickets.models import IssueThread, StateChange, Comment
from django.contrib.auth.models import Permission from django.contrib.auth.models import Permission
@ -323,6 +324,7 @@ class IssueSearchTest(TestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.event = Event.objects.create(slug='EVENT', name='Event')
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test') self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
self.user.user_permissions.add(*Permission.objects.all()) self.user.user_permissions.add(*Permission.objects.all())
self.user.save() self.user.save()
@ -331,6 +333,6 @@ class IssueSearchTest(TestCase):
def test_search(self): def test_search(self):
search_query = b64encode(b'abc').decode('utf-8') search_query = b64encode(b'abc').decode('utf-8')
response = self.client.get(f'/api/2/evt/tickets/{search_query}/') response = self.client.get(f'/api/2/{self.event.slug}/tickets/{search_query}/')
self.assertEqual(200, response.status_code) self.assertEqual(200, response.status_code)
self.assertEqual([], response.json()) self.assertEqual([], response.json())

View file

@ -1,19 +1,17 @@
<template> <template>
<form class="form-inline">
<input <input
class="form-control w-100" class="form-control w-100"
type="search" type="search"
placeholder="Search" placeholder="Search"
aria-label="Search" aria-label="Search"
v-model="search_query" v-model="search_query"
@input="searchEventItems(search_query)" @keyup.enter="dispatchSearch"
> >
</form>
</template> </template>
<script> <script>
import {mapActions} from "vuex"; import {mapActions, mapGetters} from "vuex";
export default { export default {
name: 'SearchBox', name: 'SearchBox',
@ -22,8 +20,24 @@ export default {
search_query: '' search_query: ''
} }
}, },
computed: {
...mapGetters(['getActiveView'])
},
methods: { methods: {
...mapActions(['searchEventItems']), ...mapActions(['searchEventItems', 'searchEventTickets']),
isItemView() {
return this.getActiveView === 'items' || this.getActiveView === 'item';
},
isTicketView() {
return this.getActiveView === 'tickets' || this.getActiveView === 'ticket';
},
dispatchSearch() {
if (this.isItemView()) {
this.searchEventItems(this.search_query);
} else if (this.isTicketView()) {
this.searchEventTickets(this.search_query);
}
}
} }
}; };
</script> </script>

View file

@ -26,6 +26,7 @@ const store = createStore({
lastEvent: '37C3', lastEvent: '37C3',
lastUsed: {}, lastUsed: {},
searchQuery: '',
remember: false, remember: false,
user: { user: {
username: null, username: null,
@ -375,10 +376,9 @@ const store = createStore({
} }
}, },
async searchEventItems({commit, getters, state}, query) { async searchEventItems({commit, getters, state}, query) {
const foo = utf8.encode(query); const encoded_query = base64.encode(utf8.encode(query));
const bar = base64.encode(foo);
const {data, success} = await http.get(`/2/${getters.getEventSlug}/items/${bar}/`, state.user.token); const {data, success} = await http.get(`/2/${getters.getEventSlug}/items/${encoded_query}/`, state.user.token);
if (data && success) if (data && success)
commit('replaceLoadedItems', data); commit('replaceLoadedItems', data);
}, },
@ -427,6 +427,13 @@ const store = createStore({
if (data && success) if (data && success)
commit('replaceTickets', data); commit('replaceTickets', data);
}, },
async searchEventTickets({commit, getters, state}, query) {
const encoded_query = base64.encode(utf8.encode(query));
const {data, success} = await http.get(`/2/${getters.getEventSlug}/tickets/${encoded_query}/`, state.user.token);
if (data && success)
commit('replaceTickets', data);
},
async sendMail({commit, dispatch, state}, {id, message}) { async sendMail({commit, dispatch, state}, {id, message}) {
const {data, success} = await http.post(`/2/tickets/${id}/reply/`, {message}, state.user.token); const {data, success} = await http.post(`/2/tickets/${id}/reply/`, {message}, state.user.token);
if (data && success) { if (data && success) {