From 23bbb041ec0a72c2514c0acda0633ac0f3dc88b7 Mon Sep 17 00:00:00 2001 From: jedi Date: Wed, 6 Nov 2024 21:11:18 +0100 Subject: [PATCH] add frontend to edit event details --- core/inventory/serializers.py | 34 ++++++- core/inventory/tests/v2/test_events.py | 13 ++- web/src/components/ExpandableTable.vue | 124 +++++++++++++++++++++++++ web/src/store.js | 7 ++ web/src/views/admin/Events.vue | 106 +++++++++++++++------ 5 files changed, 251 insertions(+), 33 deletions(-) create mode 100644 web/src/components/ExpandableTable.vue diff --git a/core/inventory/serializers.py b/core/inventory/serializers.py index 5a26623..18686e1 100644 --- a/core/inventory/serializers.py +++ b/core/inventory/serializers.py @@ -1,25 +1,49 @@ from django.utils import timezone from rest_framework import serializers +from rest_framework.relations import SlugRelatedField from files.models import File from inventory.models import Event, Container, Item from mail.models import EventAddress -class EventAdressSerializer(serializers.ModelSerializer): - class Meta: - model = EventAddress - fields = ['address'] +#class EventAdressSerializer(serializers.ModelSerializer): +# class Meta: +# model = EventAddress +# fields = ['address'] + +# def to_internal_value(self, data): +# if not isinstance(data, str): +# raise serializers.ValidationError('This field must be a string.') +# +# def create(self, validated_data): +# return EventAddress.objects.create(**validated_data) +# +# def validate(self, data): +# return isinstance(data, str) + class EventSerializer(serializers.ModelSerializer): - addresses = EventAdressSerializer(many=True, required=False) + #addresses = EventAdressSerializer(many=True, required=False) + addresses = SlugRelatedField(many=True, slug_field='address', queryset=EventAddress.objects.all()) class Meta: model = Event fields = ['eid', 'slug', 'name', 'start', 'end', 'pre_start', 'post_end', 'addresses'] read_only_fields = ['eid'] +# def update(self, instance, validated_data): +# addresses = validated_data.pop('addresses', None) +# instance.save(validated_data) +# if addresses: +# for address in addresses: +# nested_instance, created = EventAddress.objects.get_or_create(address=address) +# instance.addresses.add(nested_instance) +# +# return instance + + class ContainerSerializer(serializers.ModelSerializer): itemCount = serializers.SerializerMethodField() diff --git a/core/inventory/tests/v2/test_events.py b/core/inventory/tests/v2/test_events.py index affbd0e..6bbc701 100644 --- a/core/inventory/tests/v2/test_events.py +++ b/core/inventory/tests/v2/test_events.py @@ -47,6 +47,18 @@ class EventTestCase(TestCase): self.assertEqual(Event.objects.all()[0].slug, 'EVENT2') self.assertEqual(Event.objects.all()[0].name, 'Event 2 new') + def test_update_event(self): + from rest_framework.test import APIClient + event = Event.objects.create(slug='EVENT1', name='Event 1') + response = APIClient().patch(f'/api/2/events/{event.eid}/', {'addresses': ['foo@bar.baz', 'foo1@bar.baz']}) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json()['slug'], 'EVENT1') + self.assertEqual(response.json()['name'], 'Event 1') + self.assertEqual(len(Event.objects.all()), 1) + self.assertEqual(Event.objects.all()[0].slug, 'EVENT1') + self.assertEqual(Event.objects.all()[0].name, 'Event 1') + self.assertEqual(1, len(response.json()[0]['addresses'])) + def test_remove_event(self): event = Event.objects.create(slug='EVENT1', name='Event 1') Event.objects.create(slug='EVENT2', name='Event 2') @@ -65,4 +77,3 @@ class EventTestCase(TestCase): self.assertEqual('TEST1', response.json()[0]['slug']) self.assertEqual('Event', response.json()[0]['name']) self.assertEqual(1, len(response.json()[0]['addresses'])) - diff --git a/web/src/components/ExpandableTable.vue b/web/src/components/ExpandableTable.vue new file mode 100644 index 0000000..6bd5175 --- /dev/null +++ b/web/src/components/ExpandableTable.vue @@ -0,0 +1,124 @@ + + + + + \ No newline at end of file diff --git a/web/src/store.js b/web/src/store.js index 53d01b6..9a5a515 100644 --- a/web/src/store.js +++ b/web/src/store.js @@ -320,6 +320,13 @@ const store = createStore({ commit('replaceEvents', [...state.events.filter(e => e.eid !== event_id)]) } }, + async updateEvent({commit, dispatch, state}, {id, partial_event}){ + console.log(id, partial_event); + const {data, success} = await http.patch(`/2/events/${id}/`, partial_event, state.user.token); + if (success) { + commit('replaceEvents', [...state.events.filter(e => e.eid !== id), data]) + } + }, async fetchTicketStates({commit, state}) { if (!state.user.token) return; if (state.fetchedData.states > Date.now() - 1000 * 60 * 60 * 24) return; diff --git a/web/src/views/admin/Events.vue b/web/src/views/admin/Events.vue index 1aab608..e2ff952 100644 --- a/web/src/views/admin/Events.vue +++ b/web/src/views/admin/Events.vue @@ -1,50 +1,102 @@ \ No newline at end of file