emile 9 months ago
parent a4acc678a4
commit 3a1a6aad3d

BIN
.DS_Store vendored

Binary file not shown.

BIN
osinaweb/.DS_Store vendored

Binary file not shown.

Binary file not shown.

@ -124,6 +124,7 @@ class Osichat(WebsocketConsumer):
if hasattr(chat_room, 'chatroomguest') and chat_room.chatroomguest.visitor:
visitor = chat_room.chatroomguest.visitor
room_data['visitor'] = {
'id': visitor.id,
'session_id': visitor.session_id,
'ip': visitor.ip_address,
'country': visitor.country,

@ -13,8 +13,8 @@ urlpatterns = [
path('project/', views.add_project, name='addproject'),
path('project-member/<str:project_id>/', views.add_project_member_modal, name='addprojectmembermodal'),
path('project-story/<str:project_id>/', views.add_user_story_modal, name='adduserstorymodal'),
path('project-file/', views.add_file_modal, name='addfilemodal'),
path('project-credential/', views.add_credential_modal, name='addcredentialmodal'),
path('project-file/<str:project_id>/', views.add_file_modal, name='addfilemodal'),
path('project-credential/<str:project_id>/', views.add_credential_modal, name='addcredentialmodal'),
path('project-note/<str:project_id>/', views.add_note_modal, name='addprojectnotemodal'),

@ -296,19 +296,43 @@ def add_user_story_modal(request, project_id):
@staff_login_required
def add_file_modal(request, *args, **kwargs):
def add_file_modal(request, project_id):
project = get_object_or_404(Project, project_id=project_id)
if request.method == 'POST':
project_file_album = ProjectFileAlbum.objects.create(
project = project,
name = request.POST.get('name'),
)
for file in request.FILES.getlist('files'):
ProjectFile.objects.create(
album=project_file_album,
file = file,
date_added= datetime.now()
)
return HttpResponse('<script>window.top.location.reload();</script>')
context = {
'project': project
}
return render(request, 'add_templates/add-file-modal.html', context)
def add_credential_modal(request, *args, **kwargs):
def add_credential_modal(request, project_id):
project = get_object_or_404(Project, project_id=project_id)
if request.method == 'POST':
ProjectCredential.objects.create(
identifier = request.POST.get('identifier'),
password = request.POST.get('password'),
description = request.POST.get('description'),
date_added = datetime.now(),
project = project
)
return HttpResponse('<script>window.top.location.reload();</script>')
context = {
'project': project,
}
return render(request, 'add_templates/add-credentials-modal.html', context)
return render(request, 'add_templates/add-credential-modal.html', context)

@ -9,16 +9,14 @@ class RequirementInline(admin.TabularInline):
extra = 1
class FileInline(admin.TabularInline):
model = ProjectFile
extra = 1
class CredentialInline(admin.TabularInline):
model = ProjectCredential
extra = 1
class ProjectAdmin(admin.ModelAdmin):
inlines=[RequirementInline, FileInline, CredentialInline]
inlines=[RequirementInline, CredentialInline]

@ -3,6 +3,6 @@ from . import views
urlpatterns = [
path('login/', views.login_user)
path('login/', views.login_user),
path('register-device/', views.register_device)
]

@ -6,7 +6,7 @@ import calendar
from django.contrib.auth.hashers import check_password
from datetime import datetime
import datetime as datetime2
from fcm_django.models import FCMDevice
@api_view(['POST'])
def login_user(request):
@ -33,3 +33,20 @@ def login_user(request):
except Exception as e:
print(e)
return errorRes(msg=str(e))
@api_view(['POST'])
def register_device(request):
try:
registration_token = request.data.get('registration_token')
device_type = request.data.get('device_type')
# Check if the device already exists
existing_device = FCMDevice.objects.get(registration_id=registration_token)
return errorRes(msg='Device already registered')
except FCMDevice.DoesNotExist:
# Create a new device
device = FCMDevice(registration_id=registration_token, type=device_type)
device.save()
return successRes(msg="Device registered successfully.")
except Exception as e:
return errorRes(str(e))

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-08-14 06:26
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0097_remove_status_date_remove_status_time'),
]
operations = [
migrations.RenameField(
model_name='projectcredential',
old_name='emailorusername',
new_name='identifier',
),
]

@ -0,0 +1,22 @@
# Generated by Django 4.2.5 on 2024-08-14 06:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0098_rename_emailorusername_projectcredential_identifier'),
]
operations = [
migrations.RemoveField(
model_name='projectcredential',
name='usedfor',
),
migrations.AddField(
model_name='projectcredential',
name='description',
field=models.TextField(blank=True, null=True),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-08-14 06:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0099_remove_projectcredential_usedfor_and_more'),
]
operations = [
migrations.AddField(
model_name='projectcredential',
name='date_added',
field=models.DateTimeField(null=True),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-08-14 07:02
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0100_projectcredential_date_added'),
]
operations = [
migrations.RenameField(
model_name='projectfile',
old_name='date',
new_name='date_added',
),
]

@ -0,0 +1,30 @@
# Generated by Django 4.2.5 on 2024-08-14 07:06
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0101_rename_date_projectfile_date_added'),
]
operations = [
migrations.RemoveField(
model_name='projectfile',
name='date_added',
),
migrations.RemoveField(
model_name='projectfile',
name='file',
),
migrations.CreateModel(
name='ProjectFileAlbum',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date_added', models.DateField()),
('projectfile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='osinacore.projectfile')),
],
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-08-14 07:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0102_remove_projectfile_date_added_and_more'),
]
operations = [
migrations.AlterField(
model_name='projectfilealbum',
name='date_added',
field=models.DateTimeField(),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-08-14 07:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0103_alter_projectfilealbum_date_added'),
]
operations = [
migrations.AddField(
model_name='projectfilealbum',
name='file',
field=models.FileField(null=True, upload_to=''),
),
]

@ -0,0 +1,59 @@
# Generated by Django 4.2.5 on 2024-08-14 07:17
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0104_projectfilealbum_file'),
]
operations = [
migrations.RemoveField(
model_name='projectfile',
name='name',
),
migrations.RemoveField(
model_name='projectfile',
name='project',
),
migrations.RemoveField(
model_name='projectfilealbum',
name='date_added',
),
migrations.RemoveField(
model_name='projectfilealbum',
name='file',
),
migrations.RemoveField(
model_name='projectfilealbum',
name='projectfile',
),
migrations.AddField(
model_name='projectfile',
name='album',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.projectfilealbum'),
),
migrations.AddField(
model_name='projectfile',
name='date_added',
field=models.DateTimeField(null=True),
),
migrations.AddField(
model_name='projectfile',
name='file',
field=models.FileField(null=True, upload_to=''),
),
migrations.AddField(
model_name='projectfilealbum',
name='name',
field=models.CharField(max_length=350, null=True),
),
migrations.AddField(
model_name='projectfilealbum',
name='project',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='osinacore.project'),
),
]

@ -291,17 +291,25 @@ class ProjectRequirement(models.Model):
return self.content
class ProjectFile(models.Model):
name = models.CharField(max_length=350)
file = models.FileField(upload_to='uploaded_images', blank=True)
date = models.DateField()
class ProjectFileAlbum(models.Model):
name = models.CharField(max_length=350, null=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
class ProjectFile(models.Model):
album = models.ForeignKey(ProjectFileAlbum, on_delete=models.CASCADE, null=True)
file = models.FileField(null=True)
date_added = models.DateTimeField(null=True)
class ProjectCredential(models.Model):
emailorusername = models.CharField(max_length=350)
identifier = models.CharField(max_length=350)
password = models.CharField(max_length=350)
usedfor = models.CharField(max_length=350)
description = models.TextField(null=True, blank=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
date_added = models.DateTimeField(null=True)
class Note(models.Model):

@ -14,26 +14,27 @@
</head>
<body class="font-poppinsLight">
<div>
<form method="POST" action="{% url 'addcredentialmodal' project.project_id %}">
{% csrf_token %}
<h1 class="text-secondosiblue text-2xl font-semibold text-center">Add Credential</h1>
<div class="w-full flex justify-center items-center">
<input type="text" placeholder="Account" class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4">
<input type="text" name="identifier" placeholder="Identifier" class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4">
</div>
<div class="w-full flex justify-center items-center">
<input type="text" placeholder="Password" class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4">
<input type="text" name="password" placeholder="Password" class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4">
</div>
<div class="w-full flex justify-center items-center">
<input type="text" placeholder="Used for" class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4">
<input type="text" name="description" placeholder="Description" class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4">
</div>
<div class="w-full flex justify-center items-center mt-6">
<button type="submit"
class="w-fit bg-osiblue border border-osiblue rounded-md text-white text-xl px-5 py-1 hover:bg-white hover:text-osiblue duration-300">Save</button>
</div>
</div>
</form>
</body>
</html>

@ -17,19 +17,16 @@
<div>
<h1 class="text-secondosiblue text-2xl font-semibold text-center">Add File</h1>
<form>
<form method="POST" action="{% url 'addfilemodal' project.project_id %}" enctype="multipart/form-data">
{% csrf_token %}
<div class="w-full flex justify-center items-center">
<input type="text" placeholder="File Name"
<input name="name" type="text" placeholder="File Name"
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4" required>
</div>
<input type="date" id="date" name="date"
class="w-full md:w-[300px] p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-4"
required>
<div class="inbox-box border border-gray-300 py-1 px-3 w-full rounded-md mt-3">
<div class="flex items-center justify-between">
<input required name="cv" type="file" id="actual-btn" accept=".pdf,.docx" hidden required />
<input required name="files" type="file" id="actual-btn" accept=".pdf,.docx" hidden multiple />
<span id="file-name" class="text-gray-500 text-base focus:outline-none outline-none">Upload
Document(s)</span>
<label for="actual-btn"

@ -411,16 +411,16 @@
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<!-- 1st row -->
{% if project.projectrequirement_set.all %}
{% for requirement in project.projectrequirement_set.all %}
{% if stories %}
{% for story in stories %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{requirement.content}}</p>
<p class="text-secondosiblue">{{story.content}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
{% if requirement.task_set.all %}
{% for task in requirement.task_set.all %}
{% if story.task_set.all %}
{% for task in story.task_set.all %}
<div class="w-full flex flex-col justify-center items-center gap-2">
<a class="text-gray-500 underline flex justify-center items-center gap-1 hover:text-secondosiblue duration-300 cursor-pointer"
href="{% url 'detailed-task' task.task_id %}">{{task.name}}
@ -430,7 +430,7 @@
d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
</svg>
</a>
<a href="{% url 'adduserstorytask' project.project_id requirement.id %}">
<a href="{% url 'adduserstorytask' project.project_id story.id %}">
<div
class="w-[30px] h-[30px] rounded-full shadow-md bg-gray-50 text-secondosiblue border border-gray-100 flex justify-center items-center hover:bg-secondosiblue hover:text-gray-50 duration-300">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
@ -446,7 +446,7 @@
{% else %}
<div class="w-full flex flex-col justify-center items-center gap-2">
<p class="text-secondosiblue">Add Task</p>
<a href="{% url 'adduserstorytask' project.project_id requirement.id %}">
<a href="{% url 'adduserstorytask' project.project_id story.id %}">
<div
class="w-[30px] h-[30px] rounded-full shadow-md bg-gray-50 text-secondosiblue border border-gray-100 flex justify-center items-center hover:bg-secondosiblue hover:text-gray-50 duration-300">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
@ -486,7 +486,7 @@
{% else %}
<tr>
<td colspan="3" class="px-6 py-4 text-center text-sm text-secondosiblue">
No Requirements at the moment
No Stories at the moment
</td>
</tr>
{% endif %}
@ -506,7 +506,7 @@
<button
class="h-full rounded-tr-md px-4 bg-secondosiblue text-gray-200 text-[18px] outline-none border-none cursor-pointer flex justify-center items-center addCredentialsButton"
data-modal-url="{% url 'addcredentialmodal' %}">
data-modal-url="{% url 'addcredentialmodal' project.project_id %}">
<i class="fa fa-plus"></i>
</button>
</div>
@ -534,11 +534,11 @@
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<!-- 1st row -->
{% if project.projectcredential_set.all %}
{% for credential in project.projectcredential_set.all %}
{% if credentials %}
{% for credential in credentials %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{credential.emailorusername}}</p>
<p class="text-secondosiblue">{{credential.identifier}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
@ -546,7 +546,7 @@
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a class="text-secondosiblue">{{credential.usedfor}}</a>
<a class="text-secondosiblue">{{credential.description}}</a>
</td>
</tr>
{% endfor %}
@ -568,12 +568,12 @@
<div
class=" bg-gray-200 rounded-t-md flex justify-between items-center text-white text-xl font-bold h-[50px]">
<div class="px-3">
<p class="text-secondosiblue uppercase font-bold">Related files</p>
<p class="text-secondosiblue uppercase font-bold">Files</p>
</div>
<button
class="h-full rounded-tr-md px-4 bg-secondosiblue text-gray-200 text-[18px] outline-none border-none cursor-pointer flex justify-center items-center addFileButton"
data-modal-url="{% url 'addfilemodal' %}">
data-modal-url="{% url 'addfilemodal' project.project_id %}">
<i class="fa fa-plus"></i>
</button>
</div>
@ -585,36 +585,33 @@
<tr>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
File Name
File Album Name
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
File
</th>
<th scope="col"
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
Date Entered
Files
</th>
</tr>
</thead>
<!-- TABLE BODY -->
<tbody class="bg-white divide-y divide-gray-200">
<!-- 1st row -->
{% if project.projectfile_set.all %}
{% for file in project.projectfile_set.all %}
{% if albums %}
{% for album in albums %}
<tr>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<p class="text-secondosiblue">{{file.name}}</p>
<p class="text-secondosiblue">{{album.name}}</p>
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a class="text-secondosiblue">{{file.file}}</a>
{% for file in album.projectfile_set.all %}
<a class="text-secondosiblue" href="{{file.file.url}}">{{file.file}}</a>
{% endfor %}
</td>
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
<a class="text-secondosiblue">{{file.date}}</a>
</td>
</tr>
{% endfor %}
{% else %}

@ -590,6 +590,9 @@ def projectdetails(request, project_id):
project_notes = Note.objects.filter(project=project).order_by('-id')
statuses = ProjectStatus.objects.filter(project=project).order_by('-id')
stories = ProjectRequirement.objects.filter(project=project).order_by('-id')
credentials = ProjectCredential.objects.filter(project=project).order_by('-id')
albums = ProjectFileAlbum.objects.filter(project=project).order_by('-id')
all_tickets = Ticket.objects.filter(project=project)
all_tickets_with_update_date = all_tickets.annotate(
@ -623,6 +626,9 @@ def projectdetails(request, project_id):
'epics': epics,
'project_notes' : project_notes,
'members': members,
'stories': stories,
'credentials': credentials,
'albums': albums,
'statuses' : statuses,
'all_tickets_ordered': all_tickets_ordered,
'is_pinned': is_pinned,

Loading…
Cancel
Save