diff --git a/core/mail/tests/v2/test_mails.py b/core/mail/tests/v2/test_mails.py index b47ebc0..939365b 100644 --- a/core/mail/tests/v2/test_mails.py +++ b/core/mail/tests/v2/test_mails.py @@ -102,11 +102,12 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test self.assertTrue(Email.objects.all()[1].reference.endswith("@localhost>")) self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to) self.assertEqual('test', IssueThread.objects.all()[0].name) - #self.assertEqual('pending_new', IssueThread.objects.all()[0].state) + self.assertEqual('pending_new', IssueThread.objects.all()[0].state) self.assertEqual(None, IssueThread.objects.all()[0].assigned_to) states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0]) self.assertEqual(1, len(states)) self.assertEqual('pending_new', states[0].state) + def test_handle_quoted_printable(self): from aiosmtpd.smtp import Envelope from asgiref.sync import async_to_sync @@ -295,8 +296,8 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to) self.assertEqual('test', IssueThread.objects.all()[0].name) self.assertEqual(None, IssueThread.objects.all()[0].assigned_to) + self.assertEqual(1, len(IssueThread.objects.all())) + self.assertEqual('pending_new', IssueThread.objects.all()[0].state) states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0]) self.assertEqual(1, len(states)) self.assertEqual('pending_new', states[0].state) - - diff --git a/core/tickets/api_v2.py b/core/tickets/api_v2.py index c93ae68..ac958e6 100644 --- a/core/tickets/api_v2.py +++ b/core/tickets/api_v2.py @@ -35,6 +35,7 @@ class IssueSerializer(serializers.ModelSerializer): if attrs['state'] not in [x[0] for x in STATE_CHOICES]: raise serializers.ValidationError('invalid state') return attrs + @staticmethod def get_timeline(obj): timeline = [] diff --git a/core/tickets/migrations/0004_remove_issuethread_state_alter_statechange_state.py b/core/tickets/migrations/0004_remove_issuethread_state_alter_statechange_state.py new file mode 100644 index 0000000..7fda407 --- /dev/null +++ b/core/tickets/migrations/0004_remove_issuethread_state_alter_statechange_state.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.7 on 2023-12-29 22:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tickets', '0003_alter_issuethread_state'), + ] + + operations = [ + migrations.RemoveField( + model_name='issuethread', + name='state', + ), + migrations.AlterField( + model_name='statechange', + name='state', + field=models.CharField(choices=[('pending_new', 'New'), ('pending_open', 'Open'), ('pending_shipping', 'Needs to be shipped'), ('pending_physical_confirmation', 'Needs to be confirmed physically'), ('pending_return', 'Needs to be returned'), ('waiting_details', 'Waiting for details'), ('waiting_pre_shipping', 'Waiting for Address/Shipping Info'), ('closed_returned', 'Closed: Returned'), ('closed_shipped', 'Closed: Shipped'), ('closed_not_found', 'Closed: Not found'), ('closed_not_our_problem', 'Closed: Not our problem'), ('closed_duplicate', 'Closed: Duplicate'), ('closed_timeout', 'Closed: Timeout'), ('closed_spam', 'Closed: Spam')], default='pending_new', max_length=255), + ), + ] diff --git a/web/src/App.vue b/web/src/App.vue index 1025e1e..f249fde 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -74,7 +74,7 @@ export default { // message: JSON.stringify(e), // color: "success" //}); - console.log(e); + //console.log(e); }; this.notify_socket.onclose = (e) => { //if (this.socket_toast) { @@ -86,7 +86,7 @@ export default { // message: JSON.stringify(e), // color: "danger" //}); - console.log(e); + //console.log(e); setTimeout(() => { this.tryConnect(); }, 1000); @@ -101,7 +101,7 @@ export default { // message: JSON.stringify(e), // color: "danger" //}); - console.log(e); + //console.log(e); setTimeout(() => { this.tryConnect(); }, 1000); diff --git a/web/src/router.js b/web/src/router.js index 7021465..fde986d 100644 --- a/web/src/router.js +++ b/web/src/router.js @@ -20,7 +20,7 @@ import {default as BoxesAdmin} from "@/views/admin/Boxes.vue" Vue.use(VueRouter); const routes = [ - {path: '/', redirect: '/Camp23/items', meta: {requiresAuth: false}}, + {path: '/', redirect: '/37C3/items', meta: {requiresAuth: false}}, {path: '/login/', name: 'login', component: Login, meta: {requiresAuth: false}}, {path: '/register/', name: 'register', component: Register, meta: {requiresAuth: false}}, {path: '/howto/', name: 'howto', component: HowTo, meta: {requiresAuth: true}}, diff --git a/web/src/store/index.js b/web/src/store/index.js index 8516696..44a09c0 100644 --- a/web/src/store/index.js +++ b/web/src/store/index.js @@ -6,6 +6,7 @@ import router from '../router'; import * as base64 from 'base-64'; import * as utf8 from 'utf8'; +import {ticketStateColorLookup, ticketStateIconLookup} from "@/utils"; Vue.use(Vuex); const axios = AxiosBootstrap.create({ @@ -69,7 +70,7 @@ const store = new Vuex.Store({ tickets: [], users: [], groups: [], - lastEvent: localStorage.getItem('lf_lastEvent') || '36C3', + lastEvent: localStorage.getItem('lf_lastEvent') || '37C3', lastUsed: JSON.parse(localStorage.getItem('lf_lastUsed') || '{}'), remember: false, user: null, @@ -88,6 +89,25 @@ const store = new Vuex.Store({ getBoxes: state => state.loadedBoxes, checkPermission: state => (event, perm) => state.userPermissions.includes(`${event}:${perm}`) || state.userPermissions.includes(`*:${perm}`), hasPermissions: state => state.userPermissions.length > 0, + stateInfo: state => (slug) => { + const obj = state.state_options.filter((s) => s.value === slug)[0]; + if (obj) { + return { + color: ticketStateColorLookup(obj.value), + icon: ticketStateIconLookup(obj.value), + slug: obj.value, + text: obj.text, + } + } else { + return { + color: 'danger', + icon: 'exclamation', + slug: slug, + text: 'Unknown' + } + + } + }, isLoggedIn(state) { if (!state.local_loaded) { state.remember = localStorage.getItem('remember') === 'true' diff --git a/web/src/utils.js b/web/src/utils.js new file mode 100644 index 0000000..3464224 --- /dev/null +++ b/web/src/utils.js @@ -0,0 +1,27 @@ +function ticketStateColorLookup(ticket) { + if (ticket.startsWith('closed_')) { + return 'secondary'; + } + if (ticket.startsWith('pending_')) { + return 'warning'; + } + if (ticket.startsWith('waiting_')) { + return 'primary'; + } + return 'danger'; +} + +function ticketStateIconLookup(ticket) { + if (ticket.startsWith('closed_')) { + return 'check'; + } + if (ticket.startsWith('pending_')) { + return 'exclamation'; + } + if (ticket.startsWith('waiting_')) { + return 'hourglass'; + } + return 'exclamation'; +} + +export {ticketStateColorLookup, ticketStateIconLookup}; \ No newline at end of file