27 Commits

Author SHA1 Message Date
842649ef8d Update README.md 2024-01-26 17:49:47 +00:00
709c19f6e8 Merge pull request 'jones-dev' (#19) from jones-dev into master
Reviewed-on: https://gitea.corbz.dev/corbz/ticket-website/pulls/19
2024-01-26 17:39:03 +00:00
4890d7a4c3 Merge branch 'jones-dev' of https://gitea.corbz.dev/corbz/ticket-website into jones-dev 2024-01-26 17:37:43 +00:00
c35428792e example images 2024-01-26 17:37:42 +00:00
c94775d93c Update apps/home/models.py 2024-01-24 13:24:32 +00:00
2691380f81 Update & create scripts for linux & windows 2024-01-23 12:11:43 +00:00
950676a9fe Cleaned up fixture filenames & removed old fixtures 2024-01-23 12:11:18 +00:00
7c00552714 Commenting & segmenting into functions 2024-01-23 12:10:42 +00:00
6effc6799e tooltip on ticket item department & priority 2024-01-23 11:34:38 +00:00
3446c3b760 Upgrade to javascript bootstrap 5.3 2024-01-23 11:33:14 +00:00
1c5282e6c9 Removed the ticket item complex details change 2024-01-23 10:32:39 +00:00
dfef67642f Fix js error when author had no deparment 2024-01-23 09:54:50 +00:00
6f6a0f8632 Persistent state for complex ticket info 2024-01-23 09:41:33 +00:00
e342680351 User Theme saved to local storage
The theme will no longer reset to the default on page change or reload.
2024-01-23 09:18:31 +00:00
4d7f2ba3ea working on department/priority item badge 2024-01-23 08:04:27 +00:00
bf6a004d64 Merge branch 'jones-dev' of https://gitea.corbz.dev/corbz/ticket-website into origin/jones-dev 2024-01-22 16:34:43 +00:00
a482be8883 Strict tags option & css changes 2024-01-22 16:32:48 +00:00
2364277c1a Department colours and order 2024-01-22 16:31:59 +00:00
2fb6ea6c64 Updated none-found and ticket item priority badge 2024-01-22 14:14:44 +00:00
f6568230b1 Filter spam prevention #7 2024-01-22 14:14:08 +00:00
97141dec4d TicketTag/Priority order field 2024-01-22 14:13:23 +00:00
62bd7de0be Scrollbar updater 2024-01-22 11:51:10 +00:00
c32eb91d03 Reset Ticket Items Scrollbar on State Change #17
I've added a line in the updateItemsState function to reset the scrollbar to the top when the state changes.

This fixes #17
2024-01-22 11:33:15 +00:00
3f04f3561d Merge pull request 'origin/jones-dev' (#18) from origin/jones-dev into jones-dev
Reviewed-on: https://gitea.corbz.dev/corbz/ticket-website/pulls/18
2024-01-22 11:22:49 +00:00
863f5cf6ec Quick & Hacky Theme Toggler
Just to add the base functionality, will improve upon this later.
2024-01-22 11:15:57 +00:00
4761db6541 Updated & Isolated PerfectScrollbar JS/CSS 2024-01-22 11:14:53 +00:00
8f54ed2974 Update README.md
Corrected HTTPS protocol to HTTP under

# Running

2. Accessing the website
2024-01-14 01:59:22 +00:00
34 changed files with 12044 additions and 8936 deletions

View File

@ -1,3 +1,10 @@
# Ticket Website
A simple ticketing system and issue tracker written with Django, Django Rest Framework and Bootstrap 5.
<img src="https://gitea.corbz.dev/corbz/ticket-website/raw/branch/master/examples/light.png" alt="screenshot (light mode)">
<img src="https://gitea.corbz.dev/corbz/ticket-website/raw/branch/master/examples/dark.webp" alt="screenshot (dark mode)">
# Contributing # Contributing
This guide explains how to contribute. This guide explains how to contribute.
@ -62,4 +69,4 @@ You can import a fixture using the following command (remember to replace `<OPTI
2. Access the website 2. Access the website
`https://localhost:8000` `http://localhost:8000`

View File

@ -111,7 +111,7 @@ class DepartmentSerializer(DynamicModelSerializer):
class Meta: class Meta:
model = Department model = Department
fields = [ fields = [
"uuid", "title", "icon" "uuid", "title", "colour", "backgroundcolour", "order"
] ]
@ -130,7 +130,7 @@ class TicketPrioritySerializer(DynamicModelSerializer):
class Meta: class Meta:
model = TicketPriority model = TicketPriority
fields = [ fields = [
"uuid", "title", "colour", "backgroundcolour" "uuid", "title", "colour", "backgroundcolour", "order"
] ]
@ -138,7 +138,7 @@ class TicketTagSerializer(DynamicModelSerializer):
class Meta: class Meta:
model = TicketTag model = TicketTag
fields = [ fields = [
"uuid", "title", "colour", "backgroundcolour" "uuid", "title", "colour", "backgroundcolour", "order"
] ]
@ -151,6 +151,6 @@ class TicketSerializer(DynamicModelSerializer):
model = Ticket model = Ticket
fields = ( fields = (
"uuid", "title", "description", "author", "create_timestamp", "uuid", "title", "description", "author", "create_timestamp",
"edit_timestamp", "is_edited", "was_yesterday", "is_older_than_day", "edit_timestamp", "is_edited", "timestamp", "priority", "tags",
"timestamp", "priority", "tags", "short_description", "string_datetime" "short_description", "display_datetime"
) )

View File

@ -55,6 +55,10 @@ class TicketListApiView(generics.ListAPIView):
ordering_fields = ["create_timestamp", "edit_timestamp"] ordering_fields = ["create_timestamp", "edit_timestamp"]
def get_queryset(self): def get_queryset(self):
strict_tags = self.request.query_params.get("strict-tags")
if not strict_tags:
return self.queryset
tag_uuids = self.request.query_params.getlist("tags", []) tag_uuids = self.request.query_params.getlist("tags", [])
queryset = self.queryset queryset = self.queryset

View File

@ -18,7 +18,7 @@ class UserAdmin(admin.ModelAdmin):
class DepartmentAdmin(admin.ModelAdmin): class DepartmentAdmin(admin.ModelAdmin):
list_display = ["uuid", "title", "icon", "get_user_count"] list_display = ["uuid", "title", "colour", "backgroundcolour", "order", "get_user_count"]
@admin.display(description="Users") @admin.display(description="Users")
def get_user_count(self, obj): def get_user_count(self, obj):

View File

@ -4,7 +4,9 @@
"pk": "4e245769-6b67-4a6e-b804-54a3ceb3b8c0", "pk": "4e245769-6b67-4a6e-b804-54a3ceb3b8c0",
"fields": { "fields": {
"title": "Development", "title": "Development",
"icon": null "colour": "#1976d2",
"backgroundcolour": "#bbdefb",
"order": 4
} }
}, },
{ {
@ -12,7 +14,9 @@
"pk": "85b46ae8-0a19-48b7-8a21-a01abd78a470", "pk": "85b46ae8-0a19-48b7-8a21-a01abd78a470",
"fields": { "fields": {
"title": "Marketing", "title": "Marketing",
"icon": null "colour": "#7b1fa2",
"backgroundcolour": "#e1bee7",
"order": 1
} }
}, },
{ {
@ -20,7 +24,9 @@
"pk": "a6517555-0bcc-4baa-8e2f-798916562b1c", "pk": "a6517555-0bcc-4baa-8e2f-798916562b1c",
"fields": { "fields": {
"title": "Management", "title": "Management",
"icon": null "colour": "#689f38",
"backgroundcolour": "#dcedc8",
"order": 0
} }
}, },
{ {
@ -28,7 +34,9 @@
"pk": "bae35c7a-a929-4465-b70f-03254b0774e0", "pk": "bae35c7a-a929-4465-b70f-03254b0774e0",
"fields": { "fields": {
"title": "Sales", "title": "Sales",
"icon": null "colour": "#e64a19",
"backgroundcolour": "#ffccbc",
"order": 2
} }
}, },
{ {
@ -36,7 +44,9 @@
"pk": "c2bbabd7-05ac-4bc8-97a3-15bafdb478d9", "pk": "c2bbabd7-05ac-4bc8-97a3-15bafdb478d9",
"fields": { "fields": {
"title": "Business Strategy", "title": "Business Strategy",
"icon": null "colour": "#c2185b",
"backgroundcolour": "#f8bbd0",
"order": 3
} }
} }
] ]

View File

@ -1,4 +1,4 @@
# Generated by Django 3.2.16 on 2024-01-20 19:15 # Generated by Django 3.2.16 on 2024-01-22 14:39
import apps.authentication.models import apps.authentication.models
from django.db import migrations, models from django.db import migrations, models
@ -21,7 +21,9 @@ class Migration(migrations.Migration):
fields=[ fields=[
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('title', models.CharField(max_length=150)), ('title', models.CharField(max_length=150)),
('icon', models.CharField(blank=True, max_length=32, null=True)), ('colour', models.CharField(max_length=7)),
('backgroundcolour', models.CharField(max_length=7)),
('order', models.PositiveIntegerField(default=0)),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(

View File

@ -31,7 +31,9 @@ class Department(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid4, editable=False) uuid = models.UUIDField(primary_key=True, default=uuid4, editable=False)
title = models.CharField(max_length=150) title = models.CharField(max_length=150)
icon = models.CharField(max_length=32, null=True, blank=True) colour = models.CharField(max_length=7)
backgroundcolour = models.CharField(max_length=7)
order = models.PositiveIntegerField(default=0, blank=False, null=False)
def __str__(self): def __str__(self):
return self.title return self.title

View File

@ -26,7 +26,7 @@ class TicketAdmin(admin.ModelAdmin):
class TicketPriorityAdmin(admin.ModelAdmin): class TicketPriorityAdmin(admin.ModelAdmin):
list_display = ["uuid", "title", "colour", "backgroundcolour", "get_used_count"] list_display = ["uuid", "title", "colour", "backgroundcolour", "order", "get_used_count"]
@admin.display(description="Used by") @admin.display(description="Used by")
def get_used_count(self, obj): def get_used_count(self, obj):
@ -35,7 +35,7 @@ class TicketPriorityAdmin(admin.ModelAdmin):
class TicketTagAdmin(admin.ModelAdmin): class TicketTagAdmin(admin.ModelAdmin):
list_display = ["uuid", "title", "colour", "backgroundcolour", "get_used_count"] list_display = ["uuid", "title", "colour", "backgroundcolour", "order", "get_used_count"]
@admin.display(description="Used by") @admin.display(description="Used by")
def get_used_count(self, obj): def get_used_count(self, obj):

View File

@ -1,204 +0,0 @@
[
{
"model": "home.ticket",
"pk": "0725deef-d48c-4e38-814a-ae35fcbad152",
"fields": {
"title": "Software Compatibility Challenge",
"description": "Attempting to integrate a new software tool into our existing workflow, but facing compatibility challenges with other applications. Providing a detailed overview of the software stack and the specific issues encountered during integration attempts. Seeking expert guidance to resolve compatibility issues and ensure smooth workflow integration.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "a680328f-0680-456c-8e26-f594e05989ad",
"create_timestamp": "2024-01-09T00:11:40Z",
"edit_timestamp": "2024-01-09T00:11:40Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540",
"cc473838-acaf-43f9-a601-dc4ab1f9026c"
]
}
},
{
"model": "home.ticket",
"pk": "1e648e67-ddf6-4007-bb68-4a863961a827",
"fields": {
"title": "Security Patch Installation",
"description": "There's a critical security patch that needs to be installed on all workstations to address recent vulnerabilities. Attempted to deploy the patch, but facing challenges on certain machines. Need high-priority assistance to ensure all systems are promptly updated for enhanced security measures.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "a680328f-0680-456c-8e26-f594e05989ad",
"create_timestamp": "2024-01-09T00:09:20Z",
"edit_timestamp": "2024-01-09T00:09:20Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540",
"cc473838-acaf-43f9-a601-dc4ab1f9026c"
]
}
},
{
"model": "home.ticket",
"pk": "433200a2-3a62-4e81-86cc-cd5e31fecd8b",
"fields": {
"title": "Network Connectivity Issue",
"description": "Experiencing intermittent connection drops in the office. Several users affected. Need urgent assistance to resolve the issue.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "d140a5be-cf24-4250-8b38-31338e69dffd",
"create_timestamp": "2024-01-09T00:05:54Z",
"edit_timestamp": "2024-01-09T00:05:54Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"28b160b5-5c8b-43a5-84d1-4179bde87e6f",
"72fb255c-132f-4124-802d-f4c051620540"
]
}
},
{
"model": "home.ticket",
"pk": "4b893b70-8fce-49a1-b546-d1960ef97f9c",
"fields": {
"title": "New Software Request",
"description": "Requesting the installation of a new software tool for project management. Providing specific details on the software requirements and its relevance to project workflows. Seeking guidance on the installation process and any potential compatibility issues. Your assistance in this matter is highly appreciated.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "0ebc194c-b856-4e4f-9def-cd190d1e8d43",
"create_timestamp": "2024-01-09T00:09:59Z",
"edit_timestamp": "2024-01-09T17:38:15Z",
"tags": [
"72fb255c-132f-4124-802d-f4c051620540",
"cc473838-acaf-43f9-a601-dc4ab1f9026c",
"dc4dc2d5-2784-4726-8a4e-99df35a143d2"
]
}
},
{
"model": "home.ticket",
"pk": "587b35a3-1b47-4716-99bf-ebe22da283a1",
"fields": {
"title": "Database Query Performance",
"description": "Users are reporting slow response times when querying the database. This issue is impacting productivity across multiple teams. Detailed logs and steps taken to troubleshoot are provided within the description. Urgently seeking assistance to optimize database performance and resolve the slowdown.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "d140a5be-cf24-4250-8b38-31338e69dffd",
"create_timestamp": "2024-01-09T00:08:32Z",
"edit_timestamp": "2024-01-09T00:08:32Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"28b160b5-5c8b-43a5-84d1-4179bde87e6f",
"72fb255c-132f-4124-802d-f4c051620540",
"cc473838-acaf-43f9-a601-dc4ab1f9026c",
"e8c7e801-57c3-4699-a4f4-4308fb489f60"
]
}
},
{
"model": "home.ticket",
"pk": "5f39644f-0356-4818-aa07-ee6f07f36553",
"fields": {
"title": "Hardware Malfunction",
"description": "The printer on the third floor is not responding. Checked cables and power source, but issue persists. Need assistance to fix the hardware problem.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "e79687c6-9054-4706-b9a2-34afccfaa7c8",
"create_timestamp": "2024-01-09T00:06:58Z",
"edit_timestamp": "2024-01-09T00:44:49Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540",
"e8c7e801-57c3-4699-a4f4-4308fb489f60"
]
}
},
{
"model": "home.ticket",
"pk": "68fa33a7-9ac0-4612-8d92-71201c1dd5d5",
"fields": {
"title": "Printer Configuration Error",
"description": "Encountering issues with configuring a new printer for the design team. Detailed steps taken to set up the printer and the specific error messages received are provided. Urgently seeking assistance to ensure the printer is operational and meets the team's printing requirements.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "d140a5be-cf24-4250-8b38-31338e69dffd",
"create_timestamp": "2024-01-09T00:10:25Z",
"edit_timestamp": "2024-01-09T00:10:25Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540",
"e8c7e801-57c3-4699-a4f4-4308fb489f60"
]
}
},
{
"model": "home.ticket",
"pk": "9f72bd78-2d1f-4fd6-89fc-d9ecf8c69b3c",
"fields": {
"title": "VPN Connection Issue",
"description": "Remote team members are encountering difficulties establishing a VPN connection. This is hindering their ability to access essential resources. Providing detailed information on the error messages received and troubleshooting steps taken so far. Requesting immediate attention to restore seamless VPN functionality.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "e79687c6-9054-4706-b9a2-34afccfaa7c8",
"create_timestamp": "2024-01-09T00:09:39Z",
"edit_timestamp": "2024-01-09T00:13:27Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"28b160b5-5c8b-43a5-84d1-4179bde87e6f",
"72fb255c-132f-4124-802d-f4c051620540"
]
}
},
{
"model": "home.ticket",
"pk": "b0142315-b5c4-46a9-b02e-bdfdd6dffc37",
"fields": {
"title": "IT Training Request",
"description": "Requesting IT training sessions for the marketing team to enhance their proficiency in utilizing specific software tools. Providing a detailed outline of the desired training topics and the anticipated benefits for the team. Seeking assistance in scheduling and conducting the training sessions.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "0ebc194c-b856-4e4f-9def-cd190d1e8d43",
"create_timestamp": "2024-01-09T00:12:17Z",
"edit_timestamp": "2024-01-09T00:12:17Z",
"tags": [
"72fb255c-132f-4124-802d-f4c051620540",
"cc473838-acaf-43f9-a601-dc4ab1f9026c"
]
}
},
{
"model": "home.ticket",
"pk": "c470a8b3-ca54-4324-abdf-1cfa4cdf70d6",
"fields": {
"title": "Email Configuration Assistance",
"description": "Need assistance in configuring email settings for a new team member. Providing the email client details and steps taken so far. Urgently seeking guidance to ensure the seamless setup of email accounts and communication channels for the new team member.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "e79687c6-9054-4706-b9a2-34afccfaa7c8",
"create_timestamp": "2024-01-09T00:11:57Z",
"edit_timestamp": "2024-01-09T00:12:57Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540"
]
}
},
{
"model": "home.ticket",
"pk": "dd5764ad-e765-4f9b-9a9b-a3a27e60c6dd",
"fields": {
"title": "General Inquiry",
"description": "Have a question regarding the new IT policies. Need clarification on specific guidelines. Please provide assistance at your earliest convenience.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "0ebc194c-b856-4e4f-9def-cd190d1e8d43",
"create_timestamp": "2024-01-09T00:07:26Z",
"edit_timestamp": "2024-01-09T00:07:26Z",
"tags": [
"dc4dc2d5-2784-4726-8a4e-99df35a143d2"
]
}
},
{
"model": "home.ticket",
"pk": "fd8a4ad9-04fb-4a0c-beac-e60e0739e881",
"fields": {
"title": "Software Update Problem",
"description": "Unable to install the latest software update on my workstation. Getting error code XYZ. Detailed steps attempted are listed in the description.",
"author": "4965745e-b82a-4496-80e1-055217a780b0",
"priority": "a680328f-0680-456c-8e26-f594e05989ad",
"create_timestamp": "2024-01-09T00:06:32Z",
"edit_timestamp": "2024-01-09T00:06:32Z",
"tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540",
"cc473838-acaf-43f9-a601-dc4ab1f9026c"
]
}
}
]

View File

@ -8,7 +8,7 @@
"author": "21b457a1-b64a-4499-8c53-0e2f3b42fe3c", "author": "21b457a1-b64a-4499-8c53-0e2f3b42fe3c",
"priority": "0ebc194c-b856-4e4f-9def-cd190d1e8d43", "priority": "0ebc194c-b856-4e4f-9def-cd190d1e8d43",
"create_timestamp": "2024-01-09T00:11:40Z", "create_timestamp": "2024-01-09T00:11:40Z",
"edit_timestamp": "2024-01-16T15:53:48.787Z", "edit_timestamp": "2024-01-03T15:53:48.787Z",
"tags": [ "tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b", "0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540", "72fb255c-132f-4124-802d-f4c051620540",
@ -25,7 +25,7 @@
"author": "248bc1ef-df52-445e-847c-e370dccf436a", "author": "248bc1ef-df52-445e-847c-e370dccf436a",
"priority": "d140a5be-cf24-4250-8b38-31338e69dffd", "priority": "d140a5be-cf24-4250-8b38-31338e69dffd",
"create_timestamp": "2024-01-09T00:09:20Z", "create_timestamp": "2024-01-09T00:09:20Z",
"edit_timestamp": "2024-01-16T15:53:31.535Z", "edit_timestamp": "2023-06-29T15:53:31.535Z",
"tags": [ "tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b", "0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"72fb255c-132f-4124-802d-f4c051620540", "72fb255c-132f-4124-802d-f4c051620540",
@ -42,7 +42,7 @@
"author": "9f469a37-4d8d-4bd0-ba4e-16b07549f42a", "author": "9f469a37-4d8d-4bd0-ba4e-16b07549f42a",
"priority": "d140a5be-cf24-4250-8b38-31338e69dffd", "priority": "d140a5be-cf24-4250-8b38-31338e69dffd",
"create_timestamp": "2024-01-09T00:05:54Z", "create_timestamp": "2024-01-09T00:05:54Z",
"edit_timestamp": "2024-01-16T15:53:18.994Z", "edit_timestamp": "2024-01-13T15:53:18.994Z",
"tags": [ "tags": [
"0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b", "0ac68e5d-9000-4fcb-bb44-40b1b0faaa2b",
"28b160b5-5c8b-43a5-84d1-4179bde87e6f", "28b160b5-5c8b-43a5-84d1-4179bde87e6f",

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.16 on 2024-01-22 13:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0002_auto_20240112_1604'),
]
operations = [
migrations.AddField(
model_name='ticketpriority',
name='order',
field=models.PositiveIntegerField(default=0),
),
migrations.AddField(
model_name='tickettag',
name='order',
field=models.PositiveIntegerField(default=0),
),
]

View File

@ -19,6 +19,7 @@ class TicketPriority(models.Model):
title = models.CharField(max_length=32) title = models.CharField(max_length=32)
colour = models.CharField(max_length=7) colour = models.CharField(max_length=7)
backgroundcolour = models.CharField(max_length=7) backgroundcolour = models.CharField(max_length=7)
order = models.PositiveIntegerField(default=0, blank=False, null=False)
def __str__(self): def __str__(self):
return self.title return self.title
@ -30,6 +31,7 @@ class TicketTag(models.Model):
title = models.CharField(max_length=32) title = models.CharField(max_length=32)
colour = models.CharField(max_length=7) colour = models.CharField(max_length=7)
backgroundcolour = models.CharField(max_length=7) backgroundcolour = models.CharField(max_length=7)
order = models.PositiveIntegerField(default=0, blank=False, null=False)
def __str__(self): def __str__(self):
return self.title return self.title
@ -53,8 +55,6 @@ class Ticket(models.Model):
max_length=650, max_length=650,
) )
# Dirty Foreigers
author = models.ForeignKey( author = models.ForeignKey(
settings.AUTH_USER_MODEL, settings.AUTH_USER_MODEL,
verbose_name=_("author"), verbose_name=_("author"),
@ -141,35 +141,7 @@ class Ticket(models.Model):
return self.create_timestamp != self.edit_timestamp return self.create_timestamp != self.edit_timestamp
@property @property
def is_older_than_day(self) -> bool: def display_datetime(self) -> str:
"""Returns boolean dependent on if `self.timestamp` is older than 24 hours.
Returns
-------
bool
True if `self.timestamp` is older than 24 hours, False otherwise.
"""
dayago = timezone.now() - timedelta(hours=24)
return self.timestamp <= dayago
@property
def was_yesterday(self) -> bool:
"""Returns a boolean dependent on if `self.timestamp` is from before midnight yesterday.
Returns
-------
bool
_description_
"""
now = timezone.now()
midnight_today = now - timedelta(hours=now.hour, minutes=now.minute, seconds=now.second, microseconds=now.microsecond)
return self.timestamp < midnight_today
@property
def string_datetime(self) -> str:
"""Provides a human readable string representation of `self.timestamp` that should be displayed """Provides a human readable string representation of `self.timestamp` that should be displayed
to represent the ticket's age. to represent the ticket's age.

View File

@ -29,15 +29,14 @@ class TicketView(TemplateView):
@method_decorator(login_required) @method_decorator(login_required)
def get(self, request): def get(self, request):
priorities = TicketPriority.objects.all() priorities = TicketPriority.objects.all().order_by("order")
tags = TicketTag.objects.all() tags = TicketTag.objects.all().order_by("order")
departments = Department.objects.all() departments = Department.objects.all().order_by("order")
context = { context = {
"priorities": priorities, "priorities": priorities,
"tags": tags, "tags": tags,
"departments": departments, "departments": departments
"dayago": datetime.now() - timedelta(hours=24)
} }
return render(request, "home/tickets.html", context) return render(request, "home/tickets.html", context)

File diff suppressed because one or more lines are too long

View File

@ -130,6 +130,10 @@ body {
width: 0 !important; width: 0 !important;
} }
.ticket-item .ticket-item-complex .badge {
min-width: 1.8rem;
}
.ticket-item .ticket-item-icon { .ticket-item .ticket-item-icon {
width: 2rem; width: 2rem;
height: 2rem; height: 2rem;

View File

@ -1,7 +1,7 @@
* /*
* Container style * Container style
*/ */
.ps { .ps {
overflow: hidden !important; overflow: hidden !important;
overflow-anchor: none; overflow-anchor: none;
-ms-overflow-style: none; -ms-overflow-style: none;
@ -15,8 +15,8 @@
.ps__rail-x { .ps__rail-x {
display: none; display: none;
opacity: 0; opacity: 0;
transition: background-color 0.2s linear, opacity 0.2s linear; transition: background-color .2s linear, opacity .2s linear;
-webkit-transition: background-color 0.2s linear, opacity 0.2s linear; -webkit-transition: background-color .2s linear, opacity .2s linear;
height: 15px; height: 15px;
/* there must be 'bottom' or 'top' for ps__rail-x */ /* there must be 'bottom' or 'top' for ps__rail-x */
bottom: 0px; bottom: 0px;
@ -27,8 +27,8 @@
.ps__rail-y { .ps__rail-y {
display: none; display: none;
opacity: 0; opacity: 0;
transition: background-color 0.2s linear, opacity 0.2s linear; transition: background-color .2s linear, opacity .2s linear;
-webkit-transition: background-color 0.2s linear, opacity 0.2s linear; -webkit-transition: background-color .2s linear, opacity .2s linear;
width: 15px; width: 15px;
/* there must be 'right' or 'left' for ps__rail-y */ /* there must be 'right' or 'left' for ps__rail-y */
right: 0; right: 0;
@ -57,8 +57,7 @@
.ps .ps__rail-y:focus, .ps .ps__rail-y:focus,
.ps .ps__rail-x.ps--clicking, .ps .ps__rail-x.ps--clicking,
.ps .ps__rail-y.ps--clicking { .ps .ps__rail-y.ps--clicking {
/* background-color: #eee; */ background-color: #eee;
background-color: var(--bs-tertiary-bg); /* Custom Change */
opacity: 0.9; opacity: 0.9;
} }
@ -68,8 +67,8 @@
.ps__thumb-x { .ps__thumb-x {
background-color: #aaa; background-color: #aaa;
border-radius: 6px; border-radius: 6px;
transition: background-color 0.2s linear, height 0.2s ease-in-out; transition: background-color .2s linear, height .2s ease-in-out;
-webkit-transition: background-color 0.2s linear, height 0.2s ease-in-out; -webkit-transition: background-color .2s linear, height .2s ease-in-out;
height: 6px; height: 6px;
/* there must be 'bottom' for ps__thumb-x */ /* there must be 'bottom' for ps__thumb-x */
bottom: 2px; bottom: 2px;
@ -80,8 +79,8 @@
.ps__thumb-y { .ps__thumb-y {
background-color: #aaa; background-color: #aaa;
border-radius: 6px; border-radius: 6px;
transition: background-color 0.2s linear, width 0.2s ease-in-out; transition: background-color .2s linear, width .2s ease-in-out;
-webkit-transition: background-color 0.2s linear, width 0.2s ease-in-out; -webkit-transition: background-color .2s linear, width .2s ease-in-out;
width: 6px; width: 6px;
/* there must be 'right' for ps__thumb-y */ /* there must be 'right' for ps__thumb-y */
right: 2px; right: 2px;
@ -100,7 +99,6 @@
.ps__rail-y:focus > .ps__thumb-y, .ps__rail-y:focus > .ps__thumb-y,
.ps__rail-y.ps--clicking .ps__thumb-y { .ps__rail-y.ps--clicking .ps__thumb-y {
background-color: #999; background-color: #999;
/* background-color: var(--bs-body); */
width: 11px; width: 11px;
} }
@ -110,6 +108,7 @@
overflow: auto !important; overflow: auto !important;
} }
} }
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
.ps { .ps {
overflow: auto !important; overflow: auto !important;

22
apps/static/js/base.js Normal file
View File

@ -0,0 +1,22 @@
$(document).ready(function() {
// Activate all tooltips
$('[data-bs-toggle="tooltip"]').tooltip();
// Apply the user preferred theme
const theme = localStorage.getItem("theme");
if (theme == "light" || theme == "dark") {
$("body").attr("data-bs-theme", theme);
}
else {
$("body").attr("data-bs-theme", "light");
}
});
$("#themeToggle").on("click", function() {
var theme = $("body").attr("data-bs-theme");
theme = theme == "light" ? "dark" : "light";
localStorage.setItem("theme", theme)
$("body").attr("data-bs-theme", theme);
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
var filters = {"ordering": "-edit_timestamp"}; var filters = {"ordering": "-edit_timestamp", "strict-tags": true};
global_loadingTickets = false; global_loadingTickets = false;
searchTimeout = null; searchTimeout = null;
pagination = {}; pagination = {};
@ -6,6 +6,7 @@ var filters = {"ordering": "-edit_timestamp"};
$(document).ready(function() { $(document).ready(function() {
initSearchBar(); initSearchBar();
toggleComplexItems(localStorage.getItem("hideComplexTickets") === "true");
setupFilter("#filterSidebar .filter-department", "author__department"); setupFilter("#filterSidebar .filter-department", "author__department");
setupFilter("#filterSidebar .filter-tags", "tags"); setupFilter("#filterSidebar .filter-tags", "tags");
@ -17,20 +18,26 @@ $(document).ready(function() {
function updateItemsState(state) { function updateItemsState(state) {
console.debug(`updating items state to '${state}'`); console.debug(`updating items state to '${state}'`);
$("#ticketsContainer").scrollTop(0);
$("#ticketsContainer").trigger("updateScrollbar");
switch (state) { switch (state) {
case "content": case "content":
$("#ticketsContainer .none-found").hide(); $("#ticketsContainer .none-found").hide();
$("#ticketsContainer .loading").hide(); $("#ticketsContainer .loading").hide();
$("#filterSidebar input").prop("disabled", false);
break; break;
case "loading": case "loading":
$("#ticketsContainer .content").empty(); $("#ticketsContainer .content").empty();
$("#ticketsContainer .none-found").hide(); $("#ticketsContainer .none-found").hide();
$("#ticketsContainer .loading").show(); $("#ticketsContainer .loading").show();
$("#filterSidebar input").prop("disabled", true);
break; break;
case "no-content": case "no-content":
$("#ticketsContainer .content").empty(); $("#ticketsContainer .content").empty();
$("#ticketsContainer .none-found").show(); $("#ticketsContainer .none-found").show();
$("#ticketsContainer .loading").hide(); $("#ticketsContainer .loading").hide();
$("#filterSidebar input").prop("disabled", false);
break; break;
default: default:
throw new Error(`Invalid Items State '${state}'`); throw new Error(`Invalid Items State '${state}'`);
@ -216,12 +223,34 @@ function changeItemsPage(next) {
loadTicketItems(page); loadTicketItems(page);
} }
$("#strictTags").on("change", function() {
const strictTags = $(this).prop("checked");
if (strictTags) filters["strict-tags"] = strictTags;
else delete filters["strict-tags"];
loadTicketItems();
});
/**
* Loads the list of ticket items using the current filters.
*
* @function loadTicketItems
* @param {Number} page For pagination, an invalid page will result in an error.
*/
function loadTicketItems(page=1) { function loadTicketItems(page=1) {
if (global_loadingTickets) {
alert("Spam prevention\nStopped loadTicketItems because already loading.");
return;
}
global_loadingTickets = true;
updateItemsState("loading"); updateItemsState("loading");
filters["page"] = page; filters["page"] = page;
var fetchFilters = { ...filters }; var fetchFilters = { ...filters };
fetchFilters["only_fields"] = "uuid,title,short_description,author,priority,tags,timestamp,is_edited,author__forename,author__surname,author__department,author__icon,string_datetime"; fetchFilters["only_fields"] = "uuid,title,short_description,author,priority,tags,timestamp,is_edited,author__forename,author__surname,author__department,author__icon,display_datetime";
fetchTicketsPromise(fetchFilters).then((response) => { fetchTicketsPromise(fetchFilters).then((response) => {
// Update the counts to show how many tickets were found // Update the counts to show how many tickets were found
@ -256,11 +285,30 @@ function loadTicketItems(page=1) {
// Iterate over and handle each ticket // Iterate over and handle each ticket
response.results.forEach(function(ticket) { response.results.forEach(function(ticket) {
$("#ticketsContainer .content").append(createTicketItem(ticket));
});
// Make tickets clickable
applyTicketClickFunction();
updateItemsState("content");
global_loadingTickets = false;
});
}
/**
* Returns a jquery object representing an element for a ticket item, constructed using the passed
* ticket and a predefined template.
*
* @function createTicketItem
* @param {Object} ticket An object representing a ticket.
* @return {jQuery} ticketElement to be appeneded as content.
*/
function createTicketItem(ticket) {
// Create a copy of the template using the ticket data // Create a copy of the template using the ticket data
var template = $($("#ticketItemTemplate").html()); var template = $($("#ticketItemTemplate").html());
template.find(".ticket-item-author").text(`${ticket.author.forename} ${ticket.author.surname}`); template.find(".ticket-item-author").text(`${ticket.author.forename} ${ticket.author.surname}`);
template.find(".ticket-item-datetime").text(ticket.string_datetime); template.find(".ticket-item-datetime").text(ticket.display_datetime);
template.find(".ticket-item-title").text(ticket.title); template.find(".ticket-item-title").text(ticket.title);
template.find(".ticket-item-desc").html(ticket.short_description); template.find(".ticket-item-desc").html(ticket.short_description);
template.find(".ticket-item-icon").attr("src", ticket.author.icon); template.find(".ticket-item-icon").attr("src", ticket.author.icon);
@ -274,32 +322,36 @@ function loadTicketItems(page=1) {
template.find(".ticket-item-tags").append(tagTemplate); template.find(".ticket-item-tags").append(tagTemplate);
}); });
const priority = ticket.priority;
var priorityElem = template.find(".ticket-item-priority"); var priorityElem = template.find(".ticket-item-priority");
// priorityElem.text(ticket.priority.title); priorityElem.css("color", priority.colour);
priorityElem.css("color", ticket.priority.colour); priorityElem.css("background-color", priority.backgroundcolour);
priorityElem.css("background-color", ticket.priority.backgroundcolour); priorityElem.attr("data-bs-title", priority.title + " Priority");
priorityElem.tooltip();
const department = ticket.author.department;
var departmentElem = template.find(".ticket-item-department"); var departmentElem = template.find(".ticket-item-department");
departmentElem.addClass("bgc-orange-100 c-orange-700") if (department === null) {
departmentElem.hide();
}
else {
departmentElem.css("color", ticket.author.department.colour);
departmentElem.css("background-color", ticket.author.department.backgroundcolour);
departmentElem.attr("data-bs-title", ticket.author.department.title + " Department");
departmentElem.tooltip();
}
// // Add the priority using the badge template return template;
// var priorityTemplate = $($("#ticketContentBadgeTemplate").html());
// priorityTemplate.find(".ticket-content-badge-text").text(ticket.priority.title + " Priority");
// priorityTemplate.css({ "color": ticket.priority.colour, "background-color": ticket.priority.backgroundcolour });
// priorityTemplate.removeClass("rounded-pill").addClass("rounded-1");
// template.find(".ticket-item-priority").append(priorityTemplate);
// Add the content to the interface
$("#ticketsContainer .content").append(template);
});
// Make tickets clickable
applyTicketClickFunction();
updateItemsState("content");
});
} }
/**
* Load the content of a selected ticket.
*
* @function loadTicketContent
* @param {String} uuid A string representation of the ticket's UUID.
*/
function loadTicketContent(uuid) { function loadTicketContent(uuid) {
updateContentState("loading"); updateContentState("loading");
@ -307,16 +359,31 @@ function loadTicketContent(uuid) {
console.debug("Spam prevention\nStopped loadTicketContent because already loading."); console.debug("Spam prevention\nStopped loadTicketContent because already loading.");
return; return;
} }
global_loadingTickets = true;
$("#ticketContent .content").empty(); $("#ticketContent .content").empty();
fetchTicketsPromise({uuid: uuid}).then((response) => { fetchTicketsPromise({uuid: uuid}).then((response) => {
ticket = response.results[0]; ticket = response.results[0];
$("#ticketContent .content").append(createTicketContent(ticket));
updateContentState("content");
global_loadingTickets = false;
});
}
/**
* Returns a jquery object representing an element for a ticket content, constructed using the
* passed ticket and a predefined template.
*
* @function createTicketItem
* @param {Object} ticket An object representing a ticket.
* @return {jQuery} ticketElement to be shown as content.
*/
function createTicketContent(ticket) {
// Create a copy of the template using the ticket data // Create a copy of the template using the ticket data
var template = $($("#ticketContentTemplate").html()); var template = $($("#ticketContentTemplate").html());
template.find(".ticket-content-author").text(`${ticket.author.forename} ${ticket.author.surname}`); template.find(".ticket-content-author").text(`${ticket.author.forename} ${ticket.author.surname}`);
template.find(".ticket-content-datetime").text(ticket.string_datetime); template.find(".ticket-content-datetime").text(ticket.display_datetime);
template.find(".ticket-content-title").text(ticket.title); template.find(".ticket-content-title").text(ticket.title);
template.find(".ticket-content-desc").html(ticket.description); template.find(".ticket-content-desc").html(ticket.description);
template.find(".ticket-content-icon").attr("src", ticket.author.icon); template.find(".ticket-content-icon").attr("src", ticket.author.icon);
@ -329,14 +396,7 @@ function loadTicketContent(uuid) {
template.find(".ticket-content-badges").append(tagTemplate); template.find(".ticket-content-badges").append(tagTemplate);
}); });
$("#ticketContent .content").append(template); return template;
updateContentState("content");
});
// $("#ticketContent").empty();
// updateInterfaceState("showing-content");
} }
function fetchTicketsPromise(queryFilters) { function fetchTicketsPromise(queryFilters) {
@ -370,13 +430,13 @@ $(".dropdown-menu.prevent-click-close").on("click", function(e) {
e.stopPropagation(); e.stopPropagation();
}); });
function toggleComplexItems() { function toggleComplexItems(hideComplex=null) {
complexItems = !complexItems; if (hideComplex === null) {
hideComplex = !(localStorage.getItem("hideComplexTickets") === "true");
}
if (complexItems) { if (hideComplex) $("#ticketsContainer").removeClass("complex-items");
$("#ticketsContainer").addClass("complex-items"); else $("#ticketsContainer").addClass("complex-items");
}
else { localStorage.setItem("hideComplexTickets", hideComplex);
$("#ticketsContainer").removeClass("complex-items");
}
} }

View File

@ -130,7 +130,7 @@
<span>{{ department.title }}</span> <span>{{ department.title }}</span>
</div> </div>
<div class="peer"> <div class="peer">
<span class="badge rounded-pill bg-secondary-subtle text-secondary-emphasis">0</span> <!-- bgc-green-50 c-green-700 --> <span class="badge rounded-pill" style="color: {{ department.colour }}; background-color: {{ department.backgroundcolour }};">0</span>
</div> </div>
</div> </div>
</label> </label>
@ -198,15 +198,13 @@
<div id="ticketsContainer" class="layer w-100 fxg-1 scrollable pos-r ov-h"> <div id="ticketsContainer" class="layer w-100 fxg-1 scrollable pos-r ov-h">
<div class="content"></div> <div class="content"></div>
<div class="none-found pos-a top-50 start-50 translate-middle" style="display: none;"> <div class="none-found p-20" style="display: none;">
<h6 class="fw-bold">No Tickets Found</h6> <div class="pos-a top-50 start-50 translate-middle text-center">
<ul class="text-body-tertiary small"> <div class="fs-1 fw-bolder">404</div>
<li>Try clearing your search</li> <div class="fs-4 fw-bold text-body-tertiary">No Tickets Found</div>
<li>Try removing your filters</li>
<li>Try using the refresh button</li>
</ul>
</div> </div>
<div class="loading bg-body-secondary h-100" style="display: none;"> </div>
<div class="loading bg-body-tertiary h-100" style="display: none;">
{% for i in "x"|rjust:"3" %} {% for i in "x"|rjust:"3" %}
<div class="email-list-item peers fxw-nw p-20 bdB placeholder-glow" > <div class="email-list-item peers fxw-nw p-20 bdB placeholder-glow" >
<div class="peer mR-10"> <div class="peer mR-10">
@ -407,15 +405,17 @@
<!-- Ticket Item Template --> <!-- Ticket Item Template -->
<script id="ticketItemTemplate" type="text/template"> <script id="ticketItemTemplate" type="text/template">
<div class="ticket-item fxw-nw bdB peers fxw-nw p-20 w-100" data-uuid="-1"> <div class="ticket-item fxw-nw bdB peers fxw-nw p-20 w-100" data-uuid="-1">
<div class="ticket-item-complex peer mR-20 d-flex flex-column align-self-stretch"> <div class="ticket-item-complex peer mR-20 d-flex flex-column align-items-center align-self-stretch pos-r">
<img src="" alt="" class="ticket-item-icon"> <img src="" alt="" class="ticket-item-icon">
<div class="ticket-item-department badge rounded mt-auto mx-auto"> <div class="mt-auto">
<div class="ticket-item-department badge rounded mb-2" data-bs-toggle="tooltip">
<i class="fa fa-users"></i> <i class="fa fa-users"></i>
</div> </div>
<div class="ticket-item-priority badge rounded mt-2 mx-auto"> <div class="ticket-item-priority badge rounded" data-bs-toggle="tooltip">
<i class="fa fa-folder"></i> <i class="fa fa-folder"></i>
</div> </div>
</div> </div>
</div>
<div class="peer peer-greed ov-h"> <div class="peer peer-greed ov-h">
<div class="peers ai-c mb-2"> <div class="peers ai-c mb-2">
<div class="peer peer-greed"> <div class="peer peer-greed">
@ -428,7 +428,7 @@
<h5 class="ticket-item-title mb-0"></h5> <h5 class="ticket-item-title mb-0"></h5>
<div class="ticket-item-desc mt-2"></div> <div class="ticket-item-desc mt-2"></div>
<div class="peers"> <div class="peers">
<div class="ticket-item-tags peer d-flex flex-wrap mw-100" data-bs-toggle="tooltip"></div> <div class="ticket-item-tags peer d-flex flex-wrap mw-100"></div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -17,6 +17,11 @@
</li> </li>
</ul> </ul>
<ul class="nav-right"> <ul class="nav-right">
<li>
<a href="" id="themeToggle" data-bs-toggle="dropdown">
<i class="ti-shine"></i>
</a>
</li>
<li class="notifications dropdown"> <li class="notifications dropdown">
<!-- <span class="counter bgc-red">3</span> --> <!-- <span class="counter bgc-red">3</span> -->
<a href="" class="dropdown-toggle no-after" data-bs-toggle="dropdown"> <a href="" class="dropdown-toggle no-after" data-bs-toggle="dropdown">

View File

@ -8,4 +8,10 @@
<script src="{% static '/js/select2.min.js' %}"></script> <script src="{% static '/js/select2.min.js' %}"></script>
<script src="{% static '/js/perfectscrollbar.js' %}"></script>
<script src="{% static '/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static '/js/index.js' %}"></script> <script src="{% static '/js/index.js' %}"></script>
<script src="{% static '/js/base.js' %}"></script>

View File

@ -14,7 +14,7 @@
<link type="text/css" rel="stylesheet" href="{% static '/css/datepicker.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/datepicker.css' %}" />
<link type="text/css" rel="stylesheet" href="{% static '/css/fontawesome.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/fontawesome.css' %}" />
<link type="text/css" rel="stylesheet" href="{% static '/css/themify-icons.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/themify-icons.css' %}" />
<link type="text/css" rel="stylesheet" href="{% static '/css/scrollbar.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/perfectscrollbar.css' %}" />
<link type="text/css" rel="stylesheet" href="{% static '/css/adminator.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/adminator.css' %}" />
<link type="text/css" rel="stylesheet" href="{% static '/css/jquery.dataTables.min.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/jquery.dataTables.min.css' %}" />
<link type="text/css" rel="stylesheet" href="{% static '/css/select2.min.css' %}" /> <link type="text/css" rel="stylesheet" href="{% static '/css/select2.min.css' %}" />

BIN
examples/dark.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
examples/light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

11671
logs/debug.log.2024-01-18 Normal file

File diff suppressed because it is too large Load Diff

21
scripts/fixtures.bat Normal file
View File

@ -0,0 +1,21 @@
@echo off
echo migrating
python manage.py migrate
echo installing authentication fixtures
python manage.py loaddata apps\authentication\fixtures\department.json
echo installing default users
python manage.py loaddata apps\authentication\fixtures\user.json
echo installing ticket priorities
python manage.py loaddata apps\home\fixtures\ticketpriority.json
echo installing ticket tags
python manage.py loaddata apps\home\fixtures\tickettag.json
echo installing default tickets
python manage.py loaddata apps\home\fixtures\ticket.json
echo all done!

19
scripts/fixtures.ps1 Normal file
View File

@ -0,0 +1,19 @@
Write-Host "migrating"
python manage.py migrate
Write-Host "installing authentication fixtures"
python manage.py loaddata apps\authentication\fixtures\department.json
Write-Host "installing default users"
python manage.py loaddata apps\authentication\fixtures\user.json
Write-Host "installing ticket priorities"
python manage.py loaddata apps\home\fixtures\ticketpriority.json
Write-Host "installing ticket tags"
python manage.py loaddata apps\home\fixtures\tickettag.json
Write-Host "installing default tickets"
python manage.py loaddata apps\home\fixtures\ticket.json
Write-Host "all done!"

View File

@ -5,7 +5,7 @@ echo installing authentication fixtures
python manage.py loaddata apps/authentication/fixtures/department.json python manage.py loaddata apps/authentication/fixtures/department.json
echo installing default users echo installing default users
python manage.py loaddata apps/authentication/fixtures/defaultuser.json python manage.py loaddata apps/authentication/fixtures/user.json
echo installing ticket priorities echo installing ticket priorities
python manage.py loaddata apps/home/fixtures/ticketpriority.json python manage.py loaddata apps/home/fixtures/ticketpriority.json
@ -14,6 +14,6 @@ echo installing ticket tags
python manage.py loaddata apps/home/fixtures/tickettag.json python manage.py loaddata apps/home/fixtures/tickettag.json
echo installing default tickets echo installing default tickets
python manage.py loaddata apps/home/fixtures/newtickets.json python manage.py loaddata apps/home/fixtures/ticket.json
echo all done! echo all done!

7
scripts/runserver.bat Normal file
View File

@ -0,0 +1,7 @@
@echo off
echo Migrating database...
python manage.py migrate
echo Running without reload...
python manage.py runserver 0.0.0.0:8000 --noreload

5
scripts/runserver.ps1 Normal file
View File

@ -0,0 +1,5 @@
Write-Host "Migrating database..."
python manage.py migrate
Write-Host "Running without reload..."
python manage.py runserver 0.0.0.0:8000 --noreload