diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index 9e949f45..63641231 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/osinacore/__pycache__/admin.cpython-313.pyc b/osinaweb/osinacore/__pycache__/admin.cpython-313.pyc index 2ba642e9..099b611f 100644 Binary files a/osinaweb/osinacore/__pycache__/admin.cpython-313.pyc and b/osinaweb/osinacore/__pycache__/admin.cpython-313.pyc differ diff --git a/osinaweb/osinacore/__pycache__/models.cpython-313.pyc b/osinaweb/osinacore/__pycache__/models.cpython-313.pyc index 593d04e9..c4e68049 100644 Binary files a/osinaweb/osinacore/__pycache__/models.cpython-313.pyc and b/osinaweb/osinacore/__pycache__/models.cpython-313.pyc differ diff --git a/osinaweb/osinacore/__pycache__/urls.cpython-313.pyc b/osinaweb/osinacore/__pycache__/urls.cpython-313.pyc index 30db936f..173ec6e1 100644 Binary files a/osinaweb/osinacore/__pycache__/urls.cpython-313.pyc and b/osinaweb/osinacore/__pycache__/urls.cpython-313.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-313.pyc b/osinaweb/osinacore/__pycache__/views.cpython-313.pyc index 00ab0a35..8e14e41b 100644 Binary files a/osinaweb/osinacore/__pycache__/views.cpython-313.pyc and b/osinaweb/osinacore/__pycache__/views.cpython-313.pyc differ diff --git a/osinaweb/osinacore/add/__pycache__/urls.cpython-313.pyc b/osinaweb/osinacore/add/__pycache__/urls.cpython-313.pyc index 3d703510..d4afa8f6 100644 Binary files a/osinaweb/osinacore/add/__pycache__/urls.cpython-313.pyc and b/osinaweb/osinacore/add/__pycache__/urls.cpython-313.pyc differ diff --git a/osinaweb/osinacore/add/__pycache__/views.cpython-313.pyc b/osinaweb/osinacore/add/__pycache__/views.cpython-313.pyc index dde20c36..b534df11 100644 Binary files a/osinaweb/osinacore/add/__pycache__/views.cpython-313.pyc and b/osinaweb/osinacore/add/__pycache__/views.cpython-313.pyc differ diff --git a/osinaweb/osinacore/add/urls.py b/osinaweb/osinacore/add/urls.py index 079d3850..26388d3d 100644 --- a/osinaweb/osinacore/add/urls.py +++ b/osinaweb/osinacore/add/urls.py @@ -11,6 +11,8 @@ urlpatterns = [ path('project/', views.add_project, name='addproject'), + path('milestone//', views.add_milestone, name='addmilestone'), + path('milestone-story//', views.add_user_story_modal, name='addmilestoneuserstorymodal'), path('project-member//', views.add_project_member_modal, name='addprojectmembermodal'), path('project-story//', views.add_user_story_modal, name='adduserstorymodal'), path('project-file//', views.add_file_modal, name='addfilemodal'), diff --git a/osinaweb/osinacore/add/views.py b/osinaweb/osinacore/add/views.py index 39017f9a..d8617627 100644 --- a/osinaweb/osinacore/add/views.py +++ b/osinaweb/osinacore/add/views.py @@ -213,7 +213,8 @@ def add_project(request): details = request.POST.get('details') membersids = request.POST.getlist('members') start_date = request.POST.get('start_date') - end_date = request.POST.get('end_date') + end_date = request.POST.get('end_date') if request.POST.get('end_date') else None + project = Project( name=name, @@ -228,13 +229,11 @@ def add_project(request): project.project_type.set(project_type) project.members.set(membersids) - requirements = request.POST.getlist('requirements') - for requirement_content in requirements: - if requirement_content: - requirement = ProjectRequirement( - content=requirement_content, project=project, added_by=request.user) - requirement.save() - + ProjectStatus.objects.create( + status = "In Progress", + project = project, + date = datetime.now() + ) return redirect('my-projects') context = { @@ -246,6 +245,34 @@ def add_project(request): return render(request, 'add_templates/add-project.html', context) + +@staff_login_required +def add_milestone(request, project_id): + project = get_object_or_404(Project, project_id=project_id) + if request.method == 'POST': + name = request.POST.get('name') + description = request.POST.get('description') + start_date = request.POST.get('start_date') + end_date = request.POST.get('end_date') + + milestone = Milestone( + project=project, + name=name, + description=description, + start_date=start_date, + end_date=end_date + ) + + milestone.save() + + redirect_url = reverse('detailed-project', args=[project.project_id]) + return redirect(redirect_url) + context = { + 'project': project, + } + return render(request, 'add_templates/add-milestone.html', context) + + @staff_login_required def add_project_member_modal(request, project_id): project = get_object_or_404(Project, id=project_id) @@ -268,26 +295,38 @@ def add_project_member_modal(request, project_id): return render(request, 'add_templates/add-project-member-modal.html', context) + @staff_login_required -def add_user_story_modal(request, project_id): - project = get_object_or_404(Project, project_id=project_id) +def add_user_story_modal(request, milestone_id=None, project_id=None): + if project_id: + project = get_object_or_404(Project, project_id=project_id) + milestone = None + elif milestone_id: + milestone = get_object_or_404(Milestone, id=milestone_id) + project = milestone.project + milestones = Milestone.objects.filter(project=project).order_by('-id') if request.method == 'POST': content = request.POST.get('content') - - story = ProjectRequirement( - content=content, + completed = True if request.POST.get('completed') else False + confirmed = True if request.POST.get('confirmed') else False + if not milestone: + milestone = Milestone.objects.get(id=request.POST.get('milestone')) + story = UserStory( project=project, + content=content, + milestone = milestone, + completed = completed, + confirmed = confirmed, added_by=request.user, ) story.save() - # Reload the parent page using JavaScript response = HttpResponse( '') return response - context = { - 'project': project, + 'milestone': milestone, + 'milestones': milestones } @@ -350,7 +389,7 @@ def add_task(request, project_id=None, requirement_id=None): epics_of_my_project = Epic.objects.filter(project=project) if requirement_id: requirement = get_object_or_404( - ProjectRequirement, id=requirement_id) + UserStory, id=requirement_id) # Case where user wants to add task from tasks page(No project specified) else: @@ -386,7 +425,7 @@ def add_task(request, project_id=None, requirement_id=None): start_date=start_date, end_date=end_date, assigned_to=assigned_to, - requirement=requirement, + userstory=requirement, ) @@ -459,10 +498,6 @@ def add_epic(request, project_id): title = request.POST.get('title') status = request.POST.get('status') description = request.POST.get('description') - - project_id = request.POST.get('project') - project = get_object_or_404(Project, id=project_id) - start_date = request.POST.get('start_date') end_date = request.POST.get('end_date') diff --git a/osinaweb/osinacore/admin.py b/osinaweb/osinacore/admin.py index ffcbd2ab..8bff995b 100644 --- a/osinaweb/osinacore/admin.py +++ b/osinaweb/osinacore/admin.py @@ -3,20 +3,12 @@ from .models import * # Register your models here. - -class RequirementInline(admin.TabularInline): - model = ProjectRequirement - extra = 1 - - - - class CredentialInline(admin.TabularInline): model = ProjectCredential extra = 1 class ProjectAdmin(admin.ModelAdmin): - inlines=[RequirementInline, CredentialInline] + inlines=[CredentialInline] @@ -34,6 +26,8 @@ admin.site.register(Department) admin.site.register(StaffProfile) admin.site.register(ProjectType) admin.site.register(Project, ProjectAdmin) +admin.site.register(Milestone) +admin.site.register(UserStory) admin.site.register(ProjectStatus) admin.site.register(PinnedProject) admin.site.register(Epic) diff --git a/osinaweb/osinacore/edit/__pycache__/urls.cpython-313.pyc b/osinaweb/osinacore/edit/__pycache__/urls.cpython-313.pyc index b2ada5ed..024800ed 100644 Binary files a/osinaweb/osinacore/edit/__pycache__/urls.cpython-313.pyc and b/osinaweb/osinacore/edit/__pycache__/urls.cpython-313.pyc differ diff --git a/osinaweb/osinacore/edit/__pycache__/views.cpython-313.pyc b/osinaweb/osinacore/edit/__pycache__/views.cpython-313.pyc index deb7c0b1..3f21abca 100644 Binary files a/osinaweb/osinacore/edit/__pycache__/views.cpython-313.pyc and b/osinaweb/osinacore/edit/__pycache__/views.cpython-313.pyc differ diff --git a/osinaweb/osinacore/edit/urls.py b/osinaweb/osinacore/edit/urls.py index 0ddd9542..90b5fba9 100644 --- a/osinaweb/osinacore/edit/urls.py +++ b/osinaweb/osinacore/edit/urls.py @@ -11,6 +11,7 @@ urlpatterns = [ path('project//', views.edit_project, name='editproject'), path('project//toggle_pin/', views.toggle_pin_project, name='toggle_pin_project'), path('projectstatus//', views.edit_project_status_modal, name='editprojectstatusmodal'), + path('story//', views.edit_user_story_modal, name='edituserstorymodal'), path('task//', views.edit_task, name='edittask'), path('task-status//', views.edit_task_status_modal, name='edittaskstatusmodal'), path('epic/', views.edit_epic, name='editepic'), diff --git a/osinaweb/osinacore/edit/views.py b/osinaweb/osinacore/edit/views.py index c1bdbf73..4b0cd6a7 100644 --- a/osinaweb/osinacore/edit/views.py +++ b/osinaweb/osinacore/edit/views.py @@ -233,7 +233,25 @@ def toggle_pin_project(request, project_id): return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) +@staff_login_required +def edit_user_story_modal(request, story_id): + story = get_object_or_404(UserStory, id=story_id) + milestones = Milestone.objects.filter(project=story.project) + if request.method == 'POST': + story.milestone = get_object_or_404(Milestone, id=request.POST.get('milestone')) + story.content = request.POST.get('content') + story.completed = True if request.POST.get('completed') else False + story.confirmed = True if request.POST.get('confirmed') else False + story.save() + response = HttpResponse( + '') + return response + context = { + 'milestones': milestones, + 'story': story, + } + return render(request, 'edit_templates/edit-userstory-modal.html', context) @staff_login_required @@ -260,7 +278,7 @@ def edit_task(request, task_id): epic = get_object_or_404(Epic, id=epic_id) task.epic = epic - task.requirement = request.POST.get('requirement') + task.userstory = request.POST.get('requirement') task.status = request.POST.get('status') # Convert assigned_to ID to a StaffProfile instance diff --git a/osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py b/osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py new file mode 100644 index 00000000..88c21e4c --- /dev/null +++ b/osinaweb/osinacore/migrations/0110_projectrequirement_milestone.py @@ -0,0 +1,19 @@ +# Generated by Django 5.1.7 on 2025-04-05 13:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0109_remove_status_task'), + ] + + operations = [ + migrations.AddField( + model_name='projectrequirement', + name='milestone', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='osinacore.milestone'), + ), + ] diff --git a/osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py b/osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py new file mode 100644 index 00000000..ee7bb020 --- /dev/null +++ b/osinaweb/osinacore/migrations/0111_rename_projectrequirement_userstory_and_more.py @@ -0,0 +1,24 @@ +# Generated by Django 5.1.7 on 2025-04-05 13:40 + +from django.conf import settings +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0110_projectrequirement_milestone'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RenameModel( + old_name='ProjectRequirement', + new_name='UserStory', + ), + migrations.RenameField( + model_name='task', + old_name='requirement', + new_name='userstory', + ), + ] diff --git a/osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py b/osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py new file mode 100644 index 00000000..eb9e245e --- /dev/null +++ b/osinaweb/osinacore/migrations/0112_rename_title_milestone_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-05 14:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0111_rename_projectrequirement_userstory_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='milestone', + old_name='title', + new_name='name', + ), + ] diff --git a/osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py b/osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py new file mode 100644 index 00000000..f32283e4 --- /dev/null +++ b/osinaweb/osinacore/migrations/0113_userstory_completed_userstory_confirmed.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.7 on 2025-04-05 14:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0112_rename_title_milestone_name'), + ] + + operations = [ + migrations.AddField( + model_name='userstory', + name='completed', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='userstory', + name='confirmed', + field=models.BooleanField(default=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0114_alter_project_end_date.py b/osinaweb/osinacore/migrations/0114_alter_project_end_date.py new file mode 100644 index 00000000..02a23dce --- /dev/null +++ b/osinaweb/osinacore/migrations/0114_alter_project_end_date.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-05 15:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0113_userstory_completed_userstory_confirmed'), + ] + + operations = [ + migrations.AlterField( + model_name='project', + name='end_date', + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/osinaweb/osinacore/migrations/0115_projectstatus_default_created.py b/osinaweb/osinacore/migrations/0115_projectstatus_default_created.py new file mode 100644 index 00000000..661fea38 --- /dev/null +++ b/osinaweb/osinacore/migrations/0115_projectstatus_default_created.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.7 on 2025-04-05 15:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0114_alter_project_end_date'), + ] + + operations = [ + migrations.AddField( + model_name='projectstatus', + name='default_created', + field=models.BooleanField(default=False), + ), + ] diff --git a/osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py b/osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py new file mode 100644 index 00000000..34e8d9b1 --- /dev/null +++ b/osinaweb/osinacore/migrations/0116_remove_projectstatus_default_created.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.7 on 2025-04-05 15:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('osinacore', '0115_projectstatus_default_created'), + ] + + operations = [ + migrations.RemoveField( + model_name='projectstatus', + name='default_created', + ), + ] diff --git a/osinaweb/osinacore/migrations/__pycache__/0110_projectrequirement_milestone.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0110_projectrequirement_milestone.cpython-313.pyc new file mode 100644 index 00000000..ef0ff7eb Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0110_projectrequirement_milestone.cpython-313.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0111_rename_projectrequirement_userstory_and_more.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0111_rename_projectrequirement_userstory_and_more.cpython-313.pyc new file mode 100644 index 00000000..c7761adf Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0111_rename_projectrequirement_userstory_and_more.cpython-313.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0112_rename_title_milestone_name.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0112_rename_title_milestone_name.cpython-313.pyc new file mode 100644 index 00000000..ad8632b1 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0112_rename_title_milestone_name.cpython-313.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0113_userstory_completed_userstory_confirmed.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0113_userstory_completed_userstory_confirmed.cpython-313.pyc new file mode 100644 index 00000000..c0782624 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0113_userstory_completed_userstory_confirmed.cpython-313.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0114_alter_project_end_date.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0114_alter_project_end_date.cpython-313.pyc new file mode 100644 index 00000000..f7579ffd Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0114_alter_project_end_date.cpython-313.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0115_projectstatus_default_created.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0115_projectstatus_default_created.cpython-313.pyc new file mode 100644 index 00000000..d32124ad Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0115_projectstatus_default_created.cpython-313.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0116_remove_projectstatus_default_created.cpython-313.pyc b/osinaweb/osinacore/migrations/__pycache__/0116_remove_projectstatus_default_created.cpython-313.pyc new file mode 100644 index 00000000..ed8a8756 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0116_remove_projectstatus_default_created.cpython-313.pyc differ diff --git a/osinaweb/osinacore/models.py b/osinaweb/osinacore/models.py index 25be9240..eb5e8e29 100644 --- a/osinaweb/osinacore/models.py +++ b/osinaweb/osinacore/models.py @@ -172,8 +172,6 @@ class StaffProfile(models.Model): - - class StaffPosition(models.Model): staff = models.ForeignKey(StaffProfile, on_delete=models.CASCADE) position = models.ForeignKey(JobPosition, null=True, on_delete=models.SET_NULL) @@ -198,7 +196,7 @@ class Project(models.Model): details = models.TextField() members = models.ManyToManyField('StaffProfile', default='', related_name='members_project') start_date = models.DateField() - end_date = models.DateField() + end_date = models.DateField(null=True, blank=True) active = models.BooleanField(default=True, null=True) project_id = models.CharField(max_length=20, null=True, blank=True) def __str__(self): @@ -259,17 +257,6 @@ class PinnedProject(models.Model): - -class Milestone(models.Model): - title = models.CharField(max_length=150) - description = models.TextField() - project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True) - start_date = models.DateField() - end_date = models.DateField() - def __str__(self): - return self.title - - class Epic(models.Model): title = models.CharField(max_length=150) STATUS_CHOICES = ( @@ -285,11 +272,26 @@ class Epic(models.Model): return self.title -class ProjectRequirement(models.Model): + +class Milestone(models.Model): + name = models.CharField(max_length=150) + description = models.TextField() + project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True) + start_date = models.DateField() + end_date = models.DateField() + def __str__(self): + return self.name + + + +class UserStory(models.Model): + milestone = models.ForeignKey(Milestone, on_delete=models.SET_NULL, null=True) content = models.CharField(max_length=350) project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True) date = models.DateField(null=True, auto_now=True) added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) + confirmed = models.BooleanField(default=True) + completed = models.BooleanField(default=False) def __str__(self): return self.content @@ -339,7 +341,7 @@ class Task(models.Model): start_date = models.DateField(null=True) end_date = models.DateField(null=True) assigned_to = models.ForeignKey(StaffProfile, on_delete=models.CASCADE, null=True) - requirement = models.ForeignKey(ProjectRequirement, on_delete=models.SET_NULL, null=True, blank=True) + userstory = models.ForeignKey(UserStory, on_delete=models.SET_NULL, null=True, blank=True) task_id = models.CharField(max_length=20, null=True, blank=True) def save(self, *args, **kwargs): if not self.task_id: diff --git a/osinaweb/osinacore/templates/add_templates/add-epic.html b/osinaweb/osinacore/templates/add_templates/add-epic.html index 176939e4..04a21be5 100644 --- a/osinaweb/osinacore/templates/add_templates/add-epic.html +++ b/osinaweb/osinacore/templates/add_templates/add-epic.html @@ -11,18 +11,13 @@ action="{% url 'addepic' project.project_id %}"> {% csrf_token %}
- +
- -
- +
diff --git a/osinaweb/osinacore/templates/add_templates/add-milestone.html b/osinaweb/osinacore/templates/add_templates/add-milestone.html new file mode 100644 index 00000000..9eeb8210 --- /dev/null +++ b/osinaweb/osinacore/templates/add_templates/add-milestone.html @@ -0,0 +1,45 @@ +{% extends "add-edit-main.html" %} +{%load static%} +{% block content %} + +
+
+

+ Create Milestone For {{project.name}} +

+
+ {% csrf_token %} +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+
+
+
+ +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/osinacore/templates/add_templates/add-project.html b/osinaweb/osinacore/templates/add_templates/add-project.html index 311e7c76..9c1a7622 100644 --- a/osinaweb/osinacore/templates/add_templates/add-project.html +++ b/osinaweb/osinacore/templates/add_templates/add-project.html @@ -70,35 +70,6 @@ class="w-full py-3 px-3 border border-gray-300 outline-none rounded-md resize-none mt-1"> -
- -
-
- -
- - - - - -
-
-
-
@@ -118,7 +89,5 @@
- - {% endblock content %} \ No newline at end of file diff --git a/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html b/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html index 64f067f8..ccc7cdee 100644 --- a/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html +++ b/osinaweb/osinacore/templates/add_templates/add-userstory-modal.html @@ -13,15 +13,40 @@ -
+ {% csrf_token %}

Add User Story

+ + {% if not milestone %} +
+ + +
+ {% endif %}
+ + +
+ +

Completed

+
+ +
+ +

Confirmed

+
+ +
+
+ + + + + + + + + + + + + + + + {% if stories %} + {% for story in stories %} + + + + + + + + + + + + {% endfor %} + {% else %} + + + + {% endif %} + +
+ Story + + Confirmed + + Completed + + Related Task + + Actions +
+

{{story.content}}

+
+

{{story.confirmed}}

+
+

{{story.completed}}

+
+ {% if story.task_set.all %} + {% for task in story.task_set.all %} + + + {% endfor %} + {% else %} +
+

Add Task

+ +
+ + + +
+
+
+ {% endif %} +
+
+ + + + + +
+ + + +
+
+
+ No Stories at the moment +
+ + + + + + + +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/osinacore/templates/details_templates/project-details.html b/osinaweb/osinacore/templates/details_templates/project-details.html index 54d87740..7f82a236 100644 --- a/osinaweb/osinacore/templates/details_templates/project-details.html +++ b/osinaweb/osinacore/templates/details_templates/project-details.html @@ -72,23 +72,27 @@ @@ -396,10 +400,22 @@ + + Milestone + Story + + Confirmed + + + Completed + Related Task @@ -417,10 +433,33 @@ {% if stories %} {% for story in stories %} + + {% if story.milestone %} + {{story.milestone.name}} + + + + + {% else %} +

{{story.milestone.name}}

+ {% endif %} + +

{{story.content}}

+ +

{{story.confirmed}}

+ + + +

{{story.completed}}

+ + {% if story.task_set.all %} {% for task in story.task_set.all %} @@ -466,7 +505,7 @@
- + diff --git a/osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html b/osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html new file mode 100644 index 00000000..c1f41e78 --- /dev/null +++ b/osinaweb/osinacore/templates/edit_templates/edit-userstory-modal.html @@ -0,0 +1,57 @@ +{% load static %} + + + + + + + Osina + + + + + + + + + {% csrf_token %} +

Edit User Story

+ + {% if not milestone %} +
+ + +
+ {% endif %} + +
+ +
+ + +
+ +

Completed

+
+ +
+ +

Confirmed

+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/osinaweb/osinacore/urls.py b/osinaweb/osinacore/urls.py index 8d5530a2..1277e629 100644 --- a/osinaweb/osinacore/urls.py +++ b/osinaweb/osinacore/urls.py @@ -63,7 +63,8 @@ urlpatterns = [ path('customers//', views.customerdetails, name='customerdetails'), path('businesses//', views.businessdetails, name='businessdetails'), path('staffs//', views.staffdetails, name='userdetails'), - path('projectdetails//', views.projectdetails, name='detailed-project'), + path('projects//', views.projectdetails, name='detailed-project'), + path('milestones//', views.milestonedetails, name='detailed-milestone'), path('tasks//', views.taskdetails, name='detailed-task'), path('show-points//', views.show_points_modal, name='showpoints'), path('timeline//', views.timeline_modal, name='timeline'), diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index 052b63c0..637c2557 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -606,7 +606,7 @@ 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') + stories = UserStory.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') @@ -653,6 +653,18 @@ def projectdetails(request, project_id): return render(request, 'details_templates/project-details.html', context) +@staff_login_required +def milestonedetails(request, milestone_id): + milestone = get_object_or_404(Milestone, id=milestone_id) + stories = UserStory.objects.filter(milestone=milestone).order_by('-id') + context = { + 'milestone': milestone, + 'stories' : stories, + + } + + return render(request, 'details_templates/milestone-details.html', context) + def chat_room(request, chat_id): diff --git a/osinaweb/static/js/pop-modals.js b/osinaweb/static/js/pop-modals.js index caeae880..bcc7d110 100644 --- a/osinaweb/static/js/pop-modals.js +++ b/osinaweb/static/js/pop-modals.js @@ -70,7 +70,7 @@ function initializeModalButtons() { addButtonClickListener("addStaffPositionButton", "fit-content", "260px"); addButtonClickListener("addStatusButtonMobile", "500px", "80px"); addButtonClickListener("userRecentActivitiesButton", "400px", "600px"); - addButtonClickListener("addUserStoryButton", "400px", "160px"); + addButtonClickListener("addUserStoryButton", "400px", "330px"); addButtonClickListener("reactionDetailsButton", "400px", "300px"); addButtonClickListener("addPaymentCommentButton", "500px", "250px"); diff --git a/osinaweb/static/js/projects/add-project.js b/osinaweb/static/js/projects/add-project.js deleted file mode 100644 index 5a42ce41..00000000 --- a/osinaweb/static/js/projects/add-project.js +++ /dev/null @@ -1,18 +0,0 @@ -const addReqButton = document.getElementById("addReqButton"); -const addReqContainerTemplate = document.getElementById("addReqContainerTemplate"); -const addReqContainer = document.getElementById("addReqContainer"); - -addReqButton.addEventListener("click", function () { - // Clone the template and remove the "hidden" class - const newContainer = addReqContainerTemplate.cloneNode(true); - newContainer.classList.remove("hidden"); - - // Add an event listener to the new container's remove button - const removeReqButton = newContainer.querySelector("#removeReqButton"); - removeReqButton.addEventListener("click", function () { - // Remove the clicked container when the remove button is clicked - newContainer.remove(); - }); - - addReqContainer.appendChild(newContainer); -}); \ No newline at end of file