Arch/templates/projects/view.html

258 lines
12 KiB
HTML

{% extends "base.html" %}
{% block title %}Proyecto: {{ project.descripcion }}{% endblock %}
{% block styles %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/projects.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/documents.css') }}">
{% endblock %}
{% block page_title %}Proyecto: {{ project.descripcion }}{% endblock %}
{% block content %}
<div class="container mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Detalles del Proyecto</h2>
<div>
<a href="{{ url_for('projects.edit', project_id=project.codigo) }}" class="btn btn-outline-primary me-1" title="Editar proyecto">
<i class="fas fa-edit fa-lg"></i>
</a>
<a href="{{ url_for('projects.list') }}" class="btn btn-outline-secondary" title="Volver a la lista">
<i class="fas fa-arrow-left fa-lg"></i>
</a>
</div>
</div>
<div class="card mb-4">
<div class="card-header bg-light">
<h3>{{ project.descripcion }}</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Código:</strong> {{ project.codigo }}</p>
<p><strong>Cliente:</strong> {{ project.cliente }}</p>
<p><strong>Destinación:</strong> {{ project.destinacion or 'No especificada' }}</p>
<p><strong>Estado:</strong> <span class="badge {{ 'bg-success' if project.estado == 'activo' else 'bg-secondary' }}">{{ project.estado|capitalize }}</span></p>
</div>
<div class="col-md-6">
<p><strong>Esquema:</strong> {{ project.esquema }}</p>
<p><strong>Proyecto Padre:</strong> {{ project.proyecto_padre or 'Ninguno' }}</p>
<p><strong>Año Creación:</strong> {{ project.ano_creacion }}</p>
<p><strong>Fecha Creación:</strong> {{ project.fecha_creacion|default('No disponible', true) }}</p>
</div>
</div>
<div class="row mt-3">
<div class="col">
<p><strong>Creado por:</strong> {{ project.creado_por }}</p>
<p><strong>Última modificación:</strong> {{ project.ultima_modificacion|default('No modificado', true) }}</p>
<p><strong>Modificado por:</strong> {{ project.modificado_por|default('No modificado', true) }}</p>
</div>
</div>
</div>
</div>
<!-- Proyectos Hijos -->
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="mb-0">Proyectos Relacionados</h4>
<a href="{{ url_for('projects.create') }}" class="btn btn-outline-success" title="Nuevo proyecto relacionado">
<i class="fas fa-plus fa-lg"></i>
</a>
</div>
<div class="card-body">
{% if children %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Código</th>
<th>Descripción</th>
<th>Cliente</th>
<th>Estado</th>
<th width="100">Acciones</th>
</tr>
</thead>
<tbody>
{% for child in children %}
<tr>
<td>{{ child.codigo }}</td>
<td>{{ child.descripcion }}</td>
<td>{{ child.cliente }}</td>
<td><span class="badge {{ 'bg-success' if child.estado == 'activo' else 'bg-secondary' }}">{{ child.estado|capitalize }}</span></td>
<td>
<div class="btn-group btn-group-sm">
<a href="{{ url_for('projects.view', project_id=child.codigo) }}" class="btn btn-outline-info" title="Ver detalles">
<i class="fas fa-eye fa-lg"></i>
</a>
<a href="{{ url_for('projects.edit', project_id=child.codigo) }}" class="btn btn-outline-primary" title="Editar">
<i class="fas fa-edit fa-lg"></i>
</a>
<button type="button" class="btn btn-outline-danger" title="Eliminar"
onclick="confirmDelete('{{ child.codigo }}', '{{ child.descripcion }}')">
<i class="fas fa-trash-alt fa-lg"></i>
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="text-muted">No hay proyectos relacionados.</p>
{% endif %}
</div>
</div>
<!-- Documentos -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="mb-0">Documentos ({{ document_count }})</h4>
<a href="{{ url_for('documents.upload', project_id=project.codigo) }}" class="btn btn-outline-success" title="Subir documento">
<i class="fas fa-upload fa-lg"></i>
</a>
</div>
<div class="card-body">
<div id="documents-container">
{% if document_count > 0 %}
<div class="text-center">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Cargando...</span>
</div>
<p>Cargando documentos...</p>
</div>
{% else %}
<p class="text-muted">No hay documentos en este proyecto.</p>
{% endif %}
</div>
{% if document_count > 0 %}
<div class="mt-3">
<a href="{{ url_for('documents.list', project_id=project.codigo) }}" class="btn btn-outline-primary">
<i class="fas fa-list fa-lg"></i> Ver todos los documentos
</a>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Modal de confirmación para eliminar -->
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteModalLabel">Confirmar eliminación</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
¿Está seguro de que desea eliminar el proyecto <span id="projectToDelete"></span>?
<p class="text-danger mt-2">Esta acción no se puede deshacer.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<form id="deleteForm" method="POST">
{{ csrf_token() }}
<button type="submit" class="btn btn-danger">Eliminar</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='js/projects.js') }}"></script>
<script>
// Cargar documentos del proyecto mediante AJAX
$(document).ready(function() {
$.ajax({
url: "{{ url_for('documents.api_list', project_id=project.codigo) }}",
type: "GET",
dataType: "json",
success: function(data) {
displayDocuments(data);
},
error: function() {
$("#documents-container").html(
'<div class="alert alert-danger">Error al cargar los documentos.</div>'
);
}
});
});
function displayDocuments(documents) {
if (documents.length === 0) {
$("#documents-container").html(
'<div class="alert alert-info">No hay documentos en este proyecto.</div>'
);
return;
}
let html = '<div class="table-responsive">' +
'<table class="table table-hover table-striped">' +
'<thead class="table-light">' +
'<tr>' +
'<th>Nombre</th>' +
'<th>Tipo</th>' +
'<th>Última versión</th>' +
'<th>Creado por</th>' +
'<th>Acciones</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
documents.forEach(function(doc) {
// Obtener la última versión
let latestVersion = doc.versions.reduce((prev, current) =>
(prev.version > current.version) ? prev : current
);
// Determinar ícono según tipo MIME
let icon = '<i class="bi bi-file-earmark"></i>';
if (latestVersion.mime_type.includes('pdf')) {
icon = '<i class="bi bi-file-earmark-pdf"></i>';
} else if (latestVersion.mime_type.includes('image')) {
icon = '<i class="bi bi-file-earmark-image"></i>';
} else if (latestVersion.mime_type.includes('zip')) {
icon = '<i class="bi bi-file-earmark-zip"></i>';
} else if (latestVersion.mime_type.includes('text')) {
icon = '<i class="bi bi-file-earmark-text"></i>';
}
html += '<tr>' +
'<td>' + icon + ' ' + doc.original_filename + '</td>' +
'<td>' + latestVersion.mime_type + '</td>' +
'<td>v' + latestVersion.version + ' (' + latestVersion.created_at.replace('T', ' ').replace('Z', '') + ')</td>' +
'<td>' + latestVersion.created_by + '</td>' +
'<td>' +
'<div class="btn-group btn-group-sm">' +
'<a href="/documents/' + project.codigo + '/' + doc.id + '" class="btn btn-primary" title="Ver versiones">' +
'<i class="bi bi-eye"></i>' +
'</a>' +
'<a href="/documents/' + project.codigo + '/' + doc.id + '/download/' + latestVersion.version + '" class="btn btn-success" title="Descargar última versión">' +
'<i class="bi bi-download"></i>' +
'</a>' +
'</div>' +
'</td>' +
'</tr>';
});
html += '</tbody></table></div>';
$("#documents-container").html(html);
}
// Configurar modal de eliminación
function confirmDelete(projectId, projectName) {
document.getElementById('projectToDelete').textContent = projectName;
document.getElementById('deleteForm').action = "{{ url_for('projects.delete', project_id='PLACEHOLDER') }}".replace('PLACEHOLDER', projectId);
// Mostrar modal usando Bootstrap
var myModal = new bootstrap.Modal(document.getElementById('deleteModal'));
myModal.show();
}
</script>
{% endblock %}