Create project and epic done

main
emile 2 years ago
parent e27b6588b2
commit a905b3bc8b

BIN
.DS_Store vendored

Binary file not shown.

Binary file not shown.

@ -0,0 +1,23 @@
# Generated by Django 4.2.5 on 2023-09-12 18:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0016_rename_projectcredentials_projectcredential'),
]
operations = [
migrations.AlterField(
model_name='project',
name='end_date',
field=models.CharField(max_length=200),
),
migrations.AlterField(
model_name='project',
name='start_date',
field=models.CharField(max_length=200),
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2023-09-12 19:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0017_alter_project_end_date_alter_project_start_date'),
]
operations = [
migrations.AddField(
model_name='epic',
name='status',
field=models.CharField(choices=[('Open', 'Open'), ('Closed', 'Closed')], max_length=200, null=True),
),
]

@ -0,0 +1,23 @@
# Generated by Django 4.2.5 on 2023-09-12 19:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osinacore', '0018_epic_status'),
]
operations = [
migrations.AlterField(
model_name='epic',
name='end_date',
field=models.CharField(max_length=200),
),
migrations.AlterField(
model_name='epic',
name='start_date',
field=models.CharField(max_length=200),
),
]

@ -100,8 +100,8 @@ class Project(models.Model):
('Cancelled', 'Cancelled'),
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES)
start_date = models.DateField()
end_date = models.DateField()
start_date = models.CharField(max_length=200)
end_date = models.CharField(max_length=200)
project_id = models.CharField(max_length=20, null=True, blank=True) # Allow null and blank for initial creation
def save(self, *args, **kwargs):
if not self.project_id:
@ -114,8 +114,6 @@ class Project(models.Model):
super(Project, self).save(*args, **kwargs)
class Milestone(models.Model):
title = models.CharField(max_length=150)
description = models.TextField()
@ -126,10 +124,15 @@ class Milestone(models.Model):
class Epic(models.Model):
title = models.CharField(max_length=150)
STATUS_CHOICES = (
('Open', 'Open'),
('Closed', 'Closed')
)
status = models.CharField(max_length=200, choices=STATUS_CHOICES, null=True)
description = models.TextField()
project = models.ForeignKey(Project, on_delete=models.CASCADE, null=True)
start_date = models.DateField()
end_date = models.DateField()
start_date = models.CharField(max_length=200)
end_date = models.CharField(max_length=200)
class ProjectRequirement(models.Model):

@ -5,9 +5,11 @@ from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import *
from django.utils import timezone
from django.urls import reverse
# Create your views here.
# Pages views
def signin(request):
if request.user.is_authenticated:
@ -84,9 +86,12 @@ def my_tasks(request, *args, **kwargs):
@login_required
def detailed_project(request, project_id):
project = get_object_or_404(Project, project_id=project_id)
epics = Epic.objects.filter(project=project)
context = {
'project' : project,
'epics' : epics
}
@ -106,14 +111,24 @@ def createtask_project(request, project_id):
@login_required
def create_project(request):
staffs = StaffProfile.objects.all().order_by('-first_name')
project_types = ProjectType.objects.all()
customers = CustomerProfile.objects.all().order_by('-first_name')
context = {
'staffs' : staffs,
'project_types' : project_types,
'customers' : customers,
}
return render(request, 'create-project.html', context)
@login_required
def create_epic(request):
def create_epic(request, project_id):
project = get_object_or_404(Project, project_id=project_id)
context = {
'project' : project,
}
return render(request, 'create-epic.html', context)
@ -134,6 +149,11 @@ def createtask_epic(request):
return render(request, 'createtask-epic.html', context)
# Modals views
def add_note_modal(request, *args, **kwargs):
context = {
@ -141,7 +161,6 @@ def add_note_modal(request, *args, **kwargs):
return render(request, 'addnote-modal.html', context)
def add_status_modal(request, *args, **kwargs):
context = {
@ -198,6 +217,15 @@ def update_status_modal(request, *args, **kwargs):
return render(request, 'update-status-modal.html', context)
#Save Functions
@login_required
def save_note(request):
if request.method == 'POST':
@ -215,6 +243,85 @@ def save_note(request):
note.save()
# return redirect('home') # Redirect to a success page or another view
return render(request, 'addnote-modal.html')
@login_required
def save_project(request):
if request.method == 'POST':
name = request.POST.get('name')
customer_username = request.POST.get('customer')
manager_username = request.POST.get('manager')
project_type = request.POST.getlist('project_type') # Use getlist for multi-select fields
details = request.POST.get('details')
members_usernames = request.POST.getlist('members') # Use getlist for multi-select fields
status = request.POST.get('status')
start_date = request.POST.get('start_date')
end_date = request.POST.get('end_date')
# Fetch the associated profiles
try:
customer_profile = CustomerProfile.objects.get(user__username=customer_username)
manager_profile = StaffProfile.objects.get(user__username=manager_username)
members_profiles = StaffProfile.objects.filter(user__username__in=members_usernames)
except (CustomerProfile.DoesNotExist, StaffProfile.DoesNotExist):
pass
# Create and save the project
project = Project(
name=name,
customer=customer_profile,
manager=manager_profile,
details=details,
status=status,
start_date=start_date,
end_date=end_date,
)
project.save()
project.project_type.set(project_type)
project.members.set(members_profiles)
return redirect('my-projects')
return render(request, 'createproject.html')
@login_required
def save_epic(request):
if request.method == 'POST':
title = request.POST.get('title')
status = request.POST.get('status')
description = request.POST.get('description')
project_id = request.POST.get('project') # Get project ID as a string
# Retrieve the Project instance
try:
project = Project.objects.get(id=project_id)
except Project.DoesNotExist:
# Handle the case where the project with the provided ID doesn't exist
# You might want to display an error message or redirect to an appropriate page.
pass
start_date = request.POST.get('start_date')
end_date = request.POST.get('end_date')
# Create the Epic object with the Project instance
epic = Epic(
title=title,
status=status,
project=project, # Assign the Project instance
description=description,
start_date=start_date,
end_date=end_date
)
# Save the Epic object to the database
epic.save()
# Redirect to the detailed project page
redirect_url = reverse('detailed-project', args=[project.project_id])
return redirect(redirect_url)

@ -19,6 +19,8 @@ from osinacore import views
from django.contrib.auth.decorators import login_required
urlpatterns = [
# Pages urls
path('admin/', admin.site.urls),
path('login', views.signin, name='signin'),
path('logout/', views.signout, name='signout'),
@ -27,21 +29,26 @@ urlpatterns = [
path('my-tasks/', login_required(views.my_tasks), name='my-tasks'),
path('detailedproject/<str:project_id>/', views.detailed_project, name='detailed-project'),
path('createproject/', views.create_project, name='createproject'),
path('createepic/', views.create_epic, name='createepic'),
path('createepic/<str:project_id>/', views.create_epic, name='createepic'),
path('createtask/', views.create_task, name='createtask'),
path('createtask/<str:project_id>/', views.createtask_project, name='createtaskproject'),
path('createtaskepic/', views.createtask_epic, name='createtaskepic'),
# Modals urls
path('addstatus/', views.add_status_modal, name='addstatus'),
path('addnote/', views.add_note_modal, name='addnote'),
path('addfile/', views.add_file_modal, name='addfile'),
path('addcredentials/', views.add_credentials_modal, name='addcredentials'),
path('updatestatus/', views.update_status_modal, name='updatestatus'),
path('save_note/', views.save_note, name='save_note'),
path('addpoint/', views.add_point_modal, name='addpoint'),
path('showpoints/', views.show_points_modal, name='showpoints'),
path('addtime/', views.add_time_modal, name='addtime'),
path('timeline/', views.timeline_modal, name='timeline'),
path('deletetask/', views.delete_task_modal, name='deletetask'),
# Save Urls
path('save_note/', views.save_note, name='save_note'),
path('save_project/', views.save_project, name='save_project'),
path('save_epic/', views.save_epic, name='save_epic'),
]

@ -5,40 +5,47 @@
<div class="w-full px-10 mb-4">
<div class="w-full bg-white h-fit shadow-md rounded-md p-5">
<h1 class="text-3xl text-slate-800 text-center font-semibold">
Create Epic
Create Epic for {{project.name}}
</h1>
<div class="mx-auto w-full flex flex-col gap-3 justify-center items-center mt-5">
<input type="text" placeholder="Epic Name"
<form class="mx-auto w-full flex flex-col gap-3 justify-center items-center mt-5" method="POST" action="{% url 'save_epic' %}">
{% csrf_token %}
<input required name="title" type="text" placeholder="Epic Name"
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md">
<textarea type="text" placeholder="Epic Description" rows="5" cols="5"
<select required name="project" id="project" class="hidden w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500">
<option value="{{ project.id }}" selected>{{ project.name }}</option>
</select>
<textarea required name="description" type="text" placeholder="Epic Description" rows="5" cols="5"
class="w-full py-3 px-3 border border-gray-300 outline-none rounded-md resize-none"></textarea>
<select id=""
<select required name="status" id=""
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500">
<option value="" selected disabled>Select Status</option>
<option value="">Open</option>
<option value="">Closed</option>
<option value="Open">Open</option>
<option value="Closed">Closed</option>
</select>
<div class="w-full">
<label class="text-gray-500">Start Date:</label>
<input type="date" id="date" name="date"
<input required name="start_date" type="date" id="date" name="date"
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-1">
</div>
<div class="w-full">
<label class="text-gray-500">End Date:</label>
<input type="date" id="date" name="date"
<input required name="end_date" type="date" id="date" name="date"
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-1">
</div>
<div class="w-full flex justify-center items-center mt-3">
<button
<button type="submit"
class="w-fit py-1 px-3 bg-blue-500 rounded-md outline-none text-white border border-blue-500 text-xl cursor-pointer hover:bg-white hover:text-blue-500">Add
Epic</button>
</div>
</div>
</form>
</div>
</div>
</div>

@ -10,48 +10,53 @@
Create Project
</h1>
<div class="w-full flex flex-col gap-3 justify-center items-center mt-5">
<input type="text" placeholder="Project Name"
<form class="w-full flex flex-col gap-3 justify-center items-center mt-5" method="POST" action="{% url 'save_project' %}">
{% csrf_token %}
<input required name="name" type="text" placeholder="Project Name"
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md">
<input type="text" placeholder="Client"
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md">
<select id=""
<select required name="customer" id=""
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500">
<option value="" selected disabled>Project Manager</option>
<option value="">Emile</option>
<option value="">Salim</option>
<option value="" selected disabled>Clients</option>
{% for customer in customers %}
<option value="{{customer.user.username}}">{{customer.first_name}} {{customer.last_name}}</option>
{% endfor %}
</select>
<select id=""
<select required name="manager" id=""
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500">
<option value="" selected disabled>Developer(s)</option>
<option value="">Emile</option>
<option value="">Salim</option>
<option value="">Nataly</option>
<option value="" selected disabled>Project Manager</option>
{% for staff in staffs %}
<option value="{{staff.user.username}}">{{staff.first_name}} {{staff.last_name}}</option>
{% endfor %}
</select>
<select id=""
<select required name="members" id=""
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500" >
<option value="" selected disabled>Designer(s)</option>
<option value="">Emile</option>
<option value="">Salim</option>
<option value="">Nataly</option>
<option value="" selected disabled>Member(s)</option>
{% for staff in staffs %}
<option value="{{staff.user.username}}">{{staff.first_name}} {{staff.last_name}}</option>
{% endfor %}
</select>
<select id=""
<select required name="status" id=""
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500">
<option value="" selected disabled>Status</option>
<option value="">Active</option>
<option value="">Pending</option>
<option value="">Completed</option>
<option value="Pending">Pending</option>
<option value="Active">Active</option>
<option value="Completed">Completed</option>
<option value="Cancelled">Cancelled</option>
</select>
<input type="text" placeholder="Project Type"
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md">
<select required name="project_type" id=""
class="w-full h-[50px] py-1 px-3 border border-gray-300 outline-none rounded-md text-gray-500">
<option value="" selected disabled>Project Type</option>
{%for type in project_types %}
<option value="{{type.id}}">{{type.name}}</option>
{% endfor %}
</select>
<textarea type="text" placeholder="Project Details" rows="5" cols="5"
<textarea required name="details" type="text" placeholder="Project Details" rows="5" cols="5"
class="w-full py-3 px-3 border border-gray-300 outline-none rounded-md resize-none"></textarea>
<div class="w-full flex justify-between items-center gap-3">
@ -69,13 +74,13 @@
<div class="w-full">
<label class="text-gray-500">Start Date:</label>
<input type="date" id="date" name="date"
<input required name="start_date" type="date" id="date" name="date"
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-1">
</div>
<div class="w-full">
<label class="text-gray-500">End Date:</label>
<input type="date" id="date" name="date"
<input required name="end_date" type="date" id="date" name="date"
class="w-full p-3 border border-gray-300 rounded-md bg-transparent outline-none mt-1">
</div>
@ -107,11 +112,11 @@
</script> -->
<div class="w-full flex justify-center items-center mt-3">
<button
<button type="submit"
class="w-fit py-1 px-3 bg-blue-500 rounded-md outline-none text-white border border-blue-500 text-xl cursor-pointer hover:bg-white hover:text-blue-500">Add
Task</button>
</div>
Project</button>
</div>
</form>
</div>
</div>

@ -90,7 +90,7 @@
{% endif %}
<div class="w-full h-[70px] flex justify-between items-center bg-gray-100 shadow-md rounded-md px-3 py-1 mt-4">
<div class="flex justify-start items-center gap-3">
<a href="{% url 'createepic' %}">
<a href="{% url 'createepic' project.project_id %}">
<button
class="w-fit text-base px-3 py-2 bg-transparent text-blue-500 outline-none border border-blue-500 rounded-md cursor-pointer hover:bg-white">Create
Epic</button>
@ -181,12 +181,7 @@
<p class="text-gray-500 text-xl">Project Details:</p>
<div class="w-full px-8">
<p class="text-gray-500">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Deserunt repellendus temporibus et
voluptas! Mollitia error suscipit sint voluptatum perferendis earum nesciunt fuga
laudantium, sapiente ex deleniti velit, quod odio corporis?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Exercitationem perspiciatis
molestias inventore delectus atque praesentium voluptatem itaque, aspernatur et nesciunt
dolorum omnis dolor. Aliquid natus ab laudantium pariatur porro. Consectetur!
{{project.details}}
</p>
</div>
</div>
@ -206,7 +201,6 @@
</div>
<!-- RELATED FILES -->
{% if project.projectfile_set.all %}
<div>
<p class="text-gray-500 text-xl">Related Files:</p>
<div class="w-full px-4">
@ -248,10 +242,8 @@
</div>
</div>
</div>
{%endif%}
<!-- CREDENTIALS -->
{% if project.projectcredential_set.all %}
<div>
<p class="text-gray-500 text-xl">Credentials:</p>
<div class="w-full px-4">
@ -296,7 +288,6 @@
</div>
</div>
</div>
{%endif%}
<!-- TAGS -->
<div>
@ -323,21 +314,20 @@
<select id="epicSelect"
class="w-[250px] rounded-md border border-gray-300 p-3 outline-none text-gray-500 cursor-pointer">
<option selected disabled>EPICS</option>
<option>Epic 1</option>
<option>Epic 2</option>
<option>Epic 3</option>
<option>Epic 4</option>
{% for epic in epics %}
<option data-start-date="{{ epic.start_date }}" data-end-date="{{ epic.end_date }}">{{epic.title}}</option>
{% endfor %}
</select>
</div>
<div class="w-full flex justify-end gap-[3%] pl-5">
<div class="w-[50%] justify-start items-center gap-2 hidden" id="epicDetails">
<p class="text-gray-500 font-light">Start Date: <span class="text-slate-800">1/2/2023</span>
<p class="text-gray-500 font-light">Start Date: <span id="startDate" class="text-slate-800"></span>
</p>
<p class="text-gray-500 font-light">End Date: <span class="text-slate-800">1/3/2023</span>
<p class="text-gray-500 font-light">End Date: <span id="endDate" class="text-slate-800"></span>
</p>
</div>
<div class="w-[50%] flex justify-end items-center gap-2">
<a href="{% url 'createepic' %}">
<a href="{% url 'createepic' project.project_id %}">
<button
class="w-fit bg-blue-500 border border-blue-500 text-white text-base py-2 px-3 rounded-md hover:bg-transparent hover:text-blue-500 duration-300">Create
Epic</button>
@ -355,6 +345,25 @@
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function () {
$('#epicSelect').change(function () {
var selectedEpic = $(this).find(':selected');
var startDate = selectedEpic.data('start-date');
var endDate = selectedEpic.data('end-date');
if (startDate && endDate) {
$('#epicDetails').removeClass('hidden');
$('#epicDetails span#startDate').text(startDate);
$('#epicDetails span#endDate').text(endDate);
} else {
$('#epicDetails').addClass('hidden');
}
});
});
</script>
</div>
<div class="w-full px-4 hidden" id="epicRelatedTasks">

Loading…
Cancel
Save