You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
822 lines
48 KiB
HTML
822 lines
48 KiB
HTML
{% extends "main.html" %}
|
|
{%load static%}
|
|
{% block content %}
|
|
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
|
|
|
|
<div class="w-full xxlg1:w-[74.5%] bg-white h-fit rounded-md shadow-md p-5">
|
|
|
|
<div class="w-full rounded-md flex flex-col justify-center items-center py-2 bg-gray-400 relative
|
|
{% if project.projectstatus_set.all.last.status == 'Completed' %}bg-green-700{% endif %}
|
|
{% if project.projectstatus_set.all.last.status == 'Cancelled' %}bg-red-500{% endif %}
|
|
{% if project.projectstatus_set.all.last.status == 'In Progress' %}bg-orange-500{% endif %}
|
|
{% if project.projectstatus_set.all.last.status == 'Pending' %}bg-yellow-500{% endif %} bg-opacity-70">
|
|
<h1 class="text-xl md:text-3xl text-white font-semibold text-center">{{project.name}}</h1>
|
|
<div class="w-full flex justify-center items-center gap-2 flex-wrap">
|
|
{% for type in project.project_type.all %}
|
|
<p class="text-white text-sm">
|
|
{{type.name}} {% if not forloop.last %} | {% endif %}
|
|
</p>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<a href="{% url 'toggle_pin_project' project.id %}">
|
|
{% if not is_pinned %}
|
|
<div class="absolute top-3 right-3 cursor-pointer" id="pinProject">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-6 s:w-7 h-6 s:h-7 text-white"
|
|
color="#000000" fill="none">
|
|
<path d="M3 21L8 16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
|
|
stroke-linejoin="round" />
|
|
<path
|
|
d="M13.2585 18.8714C9.51516 18.0215 5.97844 14.4848 5.12853 10.7415C4.99399 10.1489 4.92672 9.85266 5.12161 9.37197C5.3165 8.89129 5.55457 8.74255 6.03071 8.44509C7.10705 7.77265 8.27254 7.55888 9.48209 7.66586C11.1793 7.81598 12.0279 7.89104 12.4512 7.67048C12.8746 7.44991 13.1622 6.93417 13.7376 5.90269L14.4664 4.59604C14.9465 3.73528 15.1866 3.3049 15.7513 3.10202C16.316 2.89913 16.6558 3.02199 17.3355 3.26771C18.9249 3.84236 20.1576 5.07505 20.7323 6.66449C20.978 7.34417 21.1009 7.68401 20.898 8.2487C20.6951 8.8134 20.2647 9.05346 19.4039 9.53358L18.0672 10.2792C17.0376 10.8534 16.5229 11.1406 16.3024 11.568C16.0819 11.9955 16.162 12.8256 16.3221 14.4859C16.4399 15.7068 16.2369 16.88 15.5555 17.9697C15.2577 18.4458 15.1088 18.6839 14.6283 18.8786C14.1477 19.0733 13.8513 19.006 13.2585 18.8714Z"
|
|
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
</svg>
|
|
</div>
|
|
{% else %}
|
|
<div class="absolute top-3 right-3 cursor-pointer" id="unpinProject">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-6 s:w-7 h-6 s:h-7 text-white"
|
|
color="#000000" fill="none">
|
|
<path
|
|
d="M7.5 8C6.95863 8.1281 6.49932 8.14239 5.99268 8.45891C5.07234 9.03388 4.85108 9.71674 5.08821 10.7612C5.94028 14.5139 9.48599 18.0596 13.2388 18.9117C14.2834 19.1489 14.9661 18.928 15.5416 18.0077C15.8411 17.5288 15.8716 17.0081 16 16.5"
|
|
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
<path
|
|
d="M12 7.79915C12.1776 7.77794 12.3182 7.74034 12.4295 7.68235C13.3997 7.17686 13.9291 5.53361 14.4498 4.60009C14.9311 3.73715 15.1718 3.30567 15.7379 3.10227C16.3041 2.89888 16.6448 3.02205 17.3262 3.26839C18.9197 3.8445 20.1555 5.08032 20.7316 6.6738C20.9779 7.35521 21.1011 7.69591 20.8977 8.26204C20.6943 8.82817 20.2628 9.06884 19.3999 9.55018C18.4608 10.074 16.7954 10.6108 16.2905 11.5898C16.2345 11.6983 16.1978 11.8327 16.1769 12"
|
|
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
|
<path d="M3 21L8 16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
|
|
stroke-linejoin="round" />
|
|
<path d="M3 3L21 21" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
|
|
stroke-linejoin="round" />
|
|
</svg>
|
|
</div>
|
|
{% endif %}
|
|
</a>
|
|
</div>
|
|
|
|
|
|
<p id="projectId" class="hidden">{{project.id}}</p>
|
|
|
|
<!-- PROJECT PROGRESS BAR -->
|
|
<div class="flex flex-col gap-1 mt-3">
|
|
<div class="w-full h-[10px] bg-gray-100 shadow-md mainBar rounded-md">
|
|
<div class="h-full rounded-md progressBar">
|
|
</div>
|
|
</div>
|
|
<div class="w-full flex justify-between items-center gap-3 text-gray-500 font-light text-sm">
|
|
<p class="startDate">{{project.start_date}}</p>
|
|
<p class="endDate">{{project.end_date}}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full h-fit flex justify-between items-center bg-gray-100 shadow-md rounded-md px-3 py-3 mt-4">
|
|
<div class="w-full md:w-fit flex flex-col md:flex-row flex-wrap justify-start items-center gap-3">
|
|
<button data-modal-url="{% url 'editprojectstatusmodal' project.id %}"
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white editProjectStatusButton">
|
|
Add Status
|
|
</button>
|
|
<a href="{% url 'addmilestone' project.project_id %}" class="w-full md:w-fit">
|
|
<button
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white">Add
|
|
Milestone</button>
|
|
</a>
|
|
<button
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white">Add
|
|
Story</button>
|
|
|
|
<a href="{% url 'addepic' project.project_id %}" class="w-full md:w-fit">
|
|
<button
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white">Add
|
|
Epic</button>
|
|
</a>
|
|
<a href="{% url 'addprojecttask' project.project_id %}" class="w-full md:w-fit">
|
|
<button
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white">Add
|
|
Task</button>
|
|
</a>
|
|
<a href="" class="w-full md:w-fit">
|
|
<button
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white">Add
|
|
Ticket</button>
|
|
</a>
|
|
|
|
<a href="{% url 'editproject' project.project_id %}" class="w-full md:w-fit">
|
|
<button
|
|
class="w-full md:w-fit text-base px-3 py-2 bg-transparent text-osiblue outline-none border border-osiblue duration-300 rounded-md cursor-pointer hover:bg-osiblue hover:text-white">Edit
|
|
Project</button>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full flex flex-col gap-5 mt-5">
|
|
<div class="w-full grid grid-cols-1 xl:grid-cols-2 gap-3">
|
|
<div class="w-full p-5 bg-white border border-gray-100 shadow-md flex flex-col rounded-md">
|
|
<div class="w-full border-b border-gray-200 pb-3 flex justify-between items-center gap-2">
|
|
<p class="text-secondosiblue font-poppinsBold uppercase">Project {{project.project_id}}</p>
|
|
|
|
<div class="projectKnowledgeButton" data-modal-url="{% url 'project_knowledge' %}">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
|
class="w-7 h-7 text-secondosiblue cursor-pointer hover:scale-105 duration-500"
|
|
color="#000000" fill="none">
|
|
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="1.5" />
|
|
<path
|
|
d="M10 9C10 7.89543 10.8954 7 12 7C13.1046 7 14 7.89543 14 9C14 9.39815 13.8837 9.76913 13.6831 10.0808C13.0854 11.0097 12 11.8954 12 13V13.5"
|
|
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
<path d="M11.992 17H12.001" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
|
stroke-linejoin="round" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- PROJECT DETAILS -->
|
|
<div class="w-full flex flex-col gap-3 mt-3">
|
|
<div>
|
|
<p class="text-gray-500">Project Description:</p>
|
|
<p class="text-secondosiblue">
|
|
{{project.details}}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- CLIENT -->
|
|
<div>
|
|
<p class="text-gray-500">Client:</p>
|
|
<a href="{% url 'customerdetails' project.customer.customer_id %}">
|
|
<div
|
|
class="w-full flex justify-between items-center gap-1 px-3 py-3 bg-gray-100 rounded-md shadow-md cursor-pointer hover:scale-105 duration-500">
|
|
<p class="text-secondosiblue">
|
|
{{project.customer.user.first_name}} {{project.customer.user.last_name}}
|
|
</p>
|
|
|
|
|
|
<div
|
|
class="w-[30px] h-[30px] rounded-md shadow-md text-white bg-secondosiblue border border-osiblue flex justify-center items-center cursor-pointer hover:bg-transparent hover:text-secondosiblue duration-300">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- STATUSES -->
|
|
<div class="w-full p-5 bg-white border border-gray-100 shadow-md flex flex-col rounded-md">
|
|
<div class="w-full border-b border-gray-200 pb-3">
|
|
<p class="text-secondosiblue font-poppinsBold uppercase">Statuses</p>
|
|
</div>
|
|
|
|
|
|
<div class="w-full flex flex-col">
|
|
{% for status in statuses %}
|
|
<div
|
|
class="border-b border-gray-100 py-4 flex justify-between items-center px-3 {% if forloop.first %} bg-gray-100 {% endif %}">
|
|
<p class="text-secondosiblue text-sm s:text-base">{{status.status}}</p>
|
|
<p class="text-gray-500 text-sm">{{status.date}}</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- MEMBERS -->
|
|
<div class="w-full mt-5">
|
|
<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">Members</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 addProjectMemberModal"
|
|
data-modal-url="{% url 'addprojectmembermodal' project.id %}">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="w-full grid grid-cols-1 l:grid-cols-2 xl:grid-cols-3 gap-3 mt-3">
|
|
<!-- PROJECT MANAGER -->
|
|
{% for member in members %}
|
|
<a class="h-full" href="{% url 'userdetails' member.staff_id %}">
|
|
<div
|
|
class="w-full h-full flex flex-col gap-1 px-3 py-3 bg-gray-100 rounded-md shadow-md cursor-pointer hover:scale-105 duration-500">
|
|
<div class="w-full flex justify-between items-center gap-1">
|
|
<div class="flex justify-start items-center gap-2">
|
|
<div class="w-[45px] h-[45px] rounded-full bg-white">
|
|
{% if project.manager.image %}
|
|
<img src="{{member.image.url}}"
|
|
class="w-full h-full rounded-full object-cover">
|
|
{% else %}
|
|
<img src="{% static 'images/default-user.png' %}"
|
|
class="w-full h-full rounded-full object-cover">
|
|
{% endif %}
|
|
</div>
|
|
|
|
|
|
<div>
|
|
<p class="text-secondosiblue font-light">{{member.user.first_name}}
|
|
{{member.user.last_name}}</p>
|
|
{% if member.id == project.manager.id %}
|
|
<div class="text-xs bg-secondosiblue text-white shadow-md py-1 px-2 rounded-md">
|
|
<p>Project Manager</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="w-[30px] h-[30px] rounded-md shadow-md text-white bg-secondosiblue border border-osiblue flex justify-center items-center cursor-pointer hover:bg-transparent hover:text-secondosiblue duration-300">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
{% if request.user.is_superuser %}
|
|
<p class="text-secondosiblue text-sm">Working Hours:
|
|
{{member.total_time_worked_hours}}hr {{member.total_time_worked_minutes}}min
|
|
{{member.total_time_worked_seconds}}sec</p>
|
|
{% endif %}
|
|
</div>
|
|
</a>
|
|
{% endfor %}
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="successMessage"
|
|
class="fixed mx-auto top-10 opacity-0 w-[85%] s:w-fit px-9 s:px-14 py-3 rounded-md bg-osiblue bg-opacity-80 text-white text-center rounded-t-md shadow-md z-10 pointer-events-none">
|
|
</div>
|
|
|
|
|
|
<!-- TICKETS -->
|
|
<div class="w-full mt-5">
|
|
<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">Tickets</p>
|
|
</div>
|
|
|
|
<a href="{% url 'addprojectticket' project.id %}" class="h-full">
|
|
<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">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</a>
|
|
|
|
</div>
|
|
<div class="overflow-x-auto border border-gray-300 rounded-b-md tableContainer">
|
|
<table class="min-w-full divide-y">
|
|
<!-- TABLE HEADER -->
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Subject
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Ticket ID
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Last Updated
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Updated By
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
|
|
Actions
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<!-- TABLE BODY -->
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
{% if all_tickets_ordered %}
|
|
{% for ticket in all_tickets_ordered %}
|
|
<tr>
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{ticket.title}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{ticket.ticket_number}}</p>
|
|
</td>
|
|
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{ticket.ticketupdate_set.all.last.date_added}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{ticket.ticketupdate_set.all.last.added_by.first_name}}</p>
|
|
</td>
|
|
|
|
<!-- RESPONSE MESSGAE FOR SHARING A TICKET -->
|
|
|
|
<td class="px-6 py-4 text-center text-sm">
|
|
<div class="flex justify-center items-center gap-3">
|
|
<button class="copyButton">
|
|
<input type="text" class="hidden copyInput"
|
|
value="https://osina.ositcom.com/my-tickets/{{ticket.ticket_number}}/">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor"
|
|
class="w-[16px] text-fifthosiblue hover:scale-110 duration-500 transition-transform">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="M7.217 10.907a2.25 2.25 0 1 0 0 2.186m0-2.186c.18.324.283.696.283 1.093s-.103.77-.283 1.093m0-2.186 9.566-5.314m-9.566 7.5 9.566 5.314m0 0a2.25 2.25 0 1 0 3.935 2.186 2.25 2.25 0 0 0-3.935-2.186Zm0-12.814a2.25 2.25 0 1 0 3.933-2.185 2.25 2.25 0 0 0-3.933 2.185Z" />
|
|
</svg>
|
|
</button>
|
|
|
|
<a href="{% url 'ticketroom' ticket.ticket_number %}">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor"
|
|
class="w-[18px] text-fifthosiblue hover:scale-110 duration-500 transition-transform">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
|
</svg>
|
|
</a>
|
|
<a href="">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor"
|
|
class="w-[18px] text-fifthosiblue hover:scale-110 duration-500 transition-transform">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
|
</svg>
|
|
</a>
|
|
<div class="cursor-pointer deleteTicketButton"
|
|
data-modal-url="{% url 'deleteticketmodal' ticket.id %}">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor"
|
|
class="w-[18px] text-red-500 hover:scale-110 duration-500 transition-transform">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="6" class="px-6 py-4 text-center text-sm text-secondosiblue">
|
|
No Tickets at the moment
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- USER STORIES -->
|
|
<div class="w-full mt-5">
|
|
<div class="overflow-x-auto border border-gray-300 rounded-b-md mt-5 tableContainer">
|
|
<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">User Stories</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 addUserStoryButton"
|
|
data-modal-url="{% url 'adduserstorymodal' project_id=project.project_id %}">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
<table class="min-w-full divide-y">
|
|
<!-- TABLE HEADER -->
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Milestone
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Story
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Confirmed
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Completed
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Related Task
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
|
|
Actions
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<!-- TABLE BODY -->
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
<!-- 1st row -->
|
|
{% if stories %}
|
|
{% for story in stories %}
|
|
<tr>
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
{% if story.milestone %}
|
|
<a class="text-gray-500 underline flex justify-center items-center gap-1 hover:text-secondosiblue duration-300 cursor-pointer"
|
|
href="{% url 'detailed-milestone' story.milestone.id %}">{{story.milestone.name}}
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
|
|
</svg>
|
|
</a>
|
|
{% else %}
|
|
<p class="text-secondosiblue">{{story.milestone.name}}</p>
|
|
{% endif %}
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{story.content}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{story.confirmed}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<p class="text-secondosiblue">{{story.completed}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
{% 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}}
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
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 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"
|
|
stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="M12 4.5v15m7.5-7.5h-15" />
|
|
</svg>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
|
|
{% endfor %}
|
|
{% 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 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"
|
|
stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="M12 4.5v15m7.5-7.5h-15" />
|
|
</svg>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
{% endif %}
|
|
</td>
|
|
|
|
|
|
<td class="px-6 py-4 text-center text-sm">
|
|
<div class="w-full flex justify-center items-center gap-3">
|
|
<a data-modal-url="{% url 'edituserstorymodal' story.id %}" class="addUserStoryButton">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor"
|
|
class="w-[18px] text-fifthosiblue hover:scale-110 duration-500 transition-transform">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
|
</svg>
|
|
</a>
|
|
<div class="cursor-pointer" data-modal-url="">
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
|
stroke-width="1.5" stroke="currentColor"
|
|
class="w-[18px] text-red-500 hover:scale-110 duration-500 transition-transform">
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="3" class="px-6 py-4 text-center text-sm text-secondosiblue">
|
|
No Stories at the moment
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- CREDENTIALS -->
|
|
<div class="w-full mt-5">
|
|
<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">Credentials</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 addCredentialsButton"
|
|
data-modal-url="{% url 'addcredentialmodal' project.project_id %}">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="overflow-x-auto border border-gray-300 rounded-b-md tableContainer">
|
|
<table class="min-w-full divide-y">
|
|
<!-- TABLE HEADER -->
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Email or Username
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase border-r border-gray-300 whitespace-nowrap">
|
|
Password
|
|
</th>
|
|
<th scope="col"
|
|
class="px-6 py-3 text-sm font-medium text-gray-500 uppercase whitespace-nowrap">
|
|
Used For
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
|
|
<!-- TABLE BODY -->
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
<!-- 1st row -->
|
|
{% 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.identifier}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<a class="text-secondosiblue">{{credential.password}}</a>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
<a class="text-secondosiblue">{{credential.description}}</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="3" class="px-6 py-4 text-center text-sm text-secondosiblue">
|
|
No Available Credentials
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- RELATED FILES -->
|
|
<div class="w-full mt-5">
|
|
<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">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' project.project_id %}">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="overflow-x-auto border border-gray-300 rounded-b-md tableContainer">
|
|
<table class="min-w-full divide-y">
|
|
<!-- TABLE HEADER -->
|
|
<thead class="bg-gray-50">
|
|
<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 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">
|
|
Files
|
|
</th>
|
|
|
|
</tr>
|
|
</thead>
|
|
|
|
<!-- TABLE BODY -->
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
<!-- 1st row -->
|
|
{% 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">{{album.name}}</p>
|
|
</td>
|
|
|
|
<td class="px-6 py-4 text-center text-sm border-r border-gray-300">
|
|
{% for file in album.projectfile_set.all %}
|
|
<a class="text-secondosiblue" href="{{file.file.url}}">{{file.file}}</a>
|
|
{% endfor %}
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="3" class="px-6 py-4 text-center text-sm text-secondosiblue">
|
|
No Available Files
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- NOTES -->
|
|
<div class="w-full mt-5">
|
|
<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">Notes</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 addProjectNoteButton"
|
|
data-modal-url="{% url 'addprojectnotemodal' project.project_id %}">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
|
|
{% if project_notes %}
|
|
<div class="w-full h-fit mt-3 grid grid-cols-3 gap-5">
|
|
{% for note in project_notes %}
|
|
<div>
|
|
<div class="w-full rounded-t-md px-3 py-2 flex justify-between items-center border-b border-white border-opacity-30"
|
|
style="background-color: {{note.color}}">
|
|
<p class="text-sm text-gray-500">{{ note.date|date:"F j, Y" }}</p>
|
|
<button
|
|
class="w-[30px] h-[30px] bg-white shadow-md rounded-md p-2 flex justify-center items-center cursor-pointer hover:scale-105 duration-300 transition-transform deleteNoteButton"
|
|
data-modal-url="{% url 'deletenotemodal' note.id %}" style="color: {{note.color}};">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
<div class="h-[150px] shadow-md rounded-b-md p-5 cursor-pointer"
|
|
style="background-color: {{note.color}}"
|
|
onclick="showModal('{{ note.text }}', '{{ note.color }}')">
|
|
<p class="text-sm text-gray-500 overflow-hidden"
|
|
style="word-break: break-all; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical;">
|
|
{{ note.text }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="w-full flex justify-center items-center px-3 py-3 text-secondosiblue text-center">
|
|
<p>No Available Notes</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
|
|
<!-- TAGS -->
|
|
<div class="w-full mt-5">
|
|
<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">Tags</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 addTagButton"
|
|
data-modal-url="{% url 'addtagmodal' %}">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="w-full h-fit mt-3 grid grid-cols-1 s:grid-cols-2 md:grid-cols-3 xlg1:grid-cols-5 gap-3">
|
|
<a>
|
|
<div
|
|
class="bg-gray-50 border border-gray-100 text-sm text-secondosiblue px-3 py-3 rounded-md cursor-pointer hover:scale-105 duration-500">
|
|
<p>Media </p>
|
|
</div>
|
|
</a>
|
|
|
|
<a>
|
|
<div
|
|
class="bg-gray-50 border border-gray-100 text-sm text-secondosiblue px-3 py-3 rounded-md cursor-pointer hover:scale-105 duration-500">
|
|
<p>Media </p>
|
|
</div>
|
|
</a>
|
|
|
|
<a>
|
|
<div
|
|
class="bg-gray-50 border border-gray-100 text-sm text-secondosiblue px-3 py-3 rounded-md cursor-pointer hover:scale-105 duration-500">
|
|
<p>Media </p>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- RELATED TASK CONTAINER BASED ON THE CHOSEN EPIC -->
|
|
<div class="w-full mt-10">
|
|
<div class="w-full bg-gray-200 rounded-md shadow-md h-fit p-5 flex flex-col gap-3">
|
|
<p class="text-secondosiblue uppercase text-xl font-semibold">Filter Tasks by Epics</p>
|
|
<div class="w-full flex flex-wrap gap-3">
|
|
<div>
|
|
<a class="selectedEpic text-gray-500 font-semibold cursor-pointer openTasks"
|
|
data-project-id="{{project.id}}">All Open Tasks</a>
|
|
</div>
|
|
<p class="text-white opacity-30 font-extralight">|</p>
|
|
{% for epic in epics %}
|
|
<div>
|
|
<a class="epicTitle text-gray-400 font-semibold cursor-pointer"
|
|
data-epic-id="{{ epic.id }}">{{epic.title}}</a>
|
|
</div>
|
|
<p class="text-white opacity-30 font-extralight">|</p>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- LOADER -->
|
|
<div class="w-full flex justify-center items-center p-5 hidden" id="epicLoader">
|
|
<div role="status">
|
|
<svg aria-hidden="true" class="w-12 h-12 text-gray-200 animate-spin dark:text-gray-600 fill-osiblue"
|
|
viewBox="0 0 100 101" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path
|
|
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
|
fill="currentColor" />
|
|
<path
|
|
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
|
fill="currentFill" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- TO DISPLAY THE FETCHED TASKS -->
|
|
<div class="w-full flex flex-col gap-3" id="epicRelatedTasksContainer">
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
class="w-full mt-5 text-base px-3 py-2 bg-red-500 text-white outline-none border border-red-500 rounded-md cursor-pointer hover:bg-white hover:text-red-500 duration-300 deleteProjectButton"
|
|
data-modal-url="{% url 'deleteprojectmodal' project.id %}">Delete
|
|
Project</button>
|
|
|
|
</div>
|
|
|
|
|
|
<!---------------------- JS SCRIPTS -------------------->
|
|
|
|
<!-- TO FETCH THE RELATED TASKS -->
|
|
<script type="text/javascript" src='{% static "js/api_calls/fetch-epic-tasks.js" %}'></script>
|
|
|
|
<!-- TO DISPLAY THE PROJECT PROGRESS BAR BASED ON ITS REMAINING TIME -->
|
|
<script type="text/javascript" src='{% static "js/projects/calculate-project-time.js" %}'></script>
|
|
|
|
<script type="text/javascript" src='{% static "js/tickets/share-ticket.js" %}'></script>
|
|
|
|
|
|
{% endblock content %} |