Files
docupulse/templates/rooms/room.html
2025-06-05 14:43:06 +02:00

298 lines
17 KiB
HTML

{% extends "common/base.html" %}
{% from "components/header.html" import header %}
{% block title %}{{ room.name }} - DocuPulse{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/room.css') }}?v={{ 'css/room.css'|asset_version }}">
{% endblock %}
{% block content %}
<!-- Meta tags for JavaScript -->
<meta name="csrf-token" content="{{ csrf_token }}">
<meta name="room-id" content="{{ room.id }}">
<meta name="room-name" content="{{ room.name }}">
<meta name="can-upload" content="{{ 'true' if can_upload else 'false' }}">
<meta name="can-delete" content="{{ 'true' if can_delete else 'false' }}">
<meta name="can-rename" content="{{ 'true' if can_rename else 'false' }}">
<meta name="can-move" content="{{ 'true' if can_move else 'false' }}">
<meta name="can-share" content="{{ 'true' if can_share else 'false' }}">
<meta name="can-download" content="{{ 'true' if can_download else 'false' }}">
{{ header(
title=room.name,
description=room.description or 'No description',
button_text="Back to Rooms",
button_url=url_for('rooms.rooms'),
icon="fa-door-open",
button_class="btn-secondary",
button_icon="fa-arrow-left"
) }}
<div class="container-fluid mt-4">
<div class="card shadow-sm mb-4">
<div class="card-header d-flex justify-content-between align-items-center bg-white">
<div class="d-flex align-items-center gap-3">
<div class="btn-group btn-group-sm" role="group" style="margin-right: 0.5rem;">
<button type="button" id="gridViewBtn" class="btn btn-outline-secondary active"
onclick="window.roomManager.viewManager.toggleView('grid')">
<i class="fas fa-th-large"></i>
</button>
<button type="button" id="listViewBtn" class="btn btn-outline-secondary"
onclick="window.roomManager.viewManager.toggleView('list')">
<i class="fas fa-list"></i>
</button>
</div>
<h5 class="mb-0">Files</h5>
</div>
<div class="d-flex gap-2" id="actionButtonsRow">
{% if current_user.is_admin or (current_user.is_manager and room.member_permissions|selectattr('user_id', 'equalto', current_user.id)|list|length > 0) %}
<a href="{{ url_for('rooms.room_members', room_id=room.id) }}"
class="btn btn-outline-primary d-flex align-items-center gap-2"
style="border-color:var(--primary-color); color:var(--primary-color);"
onmouseover="this.style.backgroundColor='var(--primary-color)'; this.style.color='white'"
onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--primary-color)'">
<i class="fas fa-users"></i> Manage Members
</a>
{% endif %}
{% if current_user.is_admin or (current_user.is_manager and room.member_permissions|selectattr('user_id', 'equalto', current_user.id)|list|length > 0) or can_upload %}
<button type="button" id="newFolderBtn" class="btn btn-outline-primary d-flex align-items-center gap-2"
style="border-color:var(--primary-color); color:var(--primary-color);"
onmouseover="this.style.backgroundColor='var(--primary-color)'; this.style.color='white'"
onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--primary-color)'">
<i class="fas fa-folder-plus"></i> New Folder
</button>
<form id="uploadForm" enctype="multipart/form-data" class="d-inline">
<input type="file" id="fileInput" name="file" multiple style="display:none;" />
<button type="button" id="uploadBtn" class="btn btn-primary d-flex align-items-center gap-2"
style="background-color:var(--primary-color); border:1px solid var(--primary-color);"
onmouseover="this.style.backgroundColor='var(--primary-light)'"
onmouseout="this.style.backgroundColor='var(--primary-color)'">
<i class="fas fa-upload"></i> Upload
</button>
</form>
{% endif %}
{% if current_user.is_admin or (current_user.is_manager and room.member_permissions|selectattr('user_id', 'equalto', current_user.id)|list|length > 0) or can_download %}
<button id="downloadSelectedBtn" class="btn btn-outline-primary btn-sm d-flex align-items-center gap-2"
style="display:none; border-color:var(--primary-color); color:var(--primary-color);"
onmouseover="this.style.backgroundColor='var(--primary-color)'; this.style.color='white'"
onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--primary-color)'">
<i class="fas fa-download"></i> Download Selected
</button>
{% endif %}
{% if current_user.is_admin or (current_user.is_manager and room.member_permissions|selectattr('user_id', 'equalto', current_user.id)|list|length > 0) or can_delete %}
<button id="deleteSelectedBtn" class="btn btn-outline-danger btn-sm d-flex align-items-center gap-2"
style="display:none; border-color:var(--danger-color); color:var(--danger-color);"
onmouseover="this.style.backgroundColor='var(--danger-color)'; this.style.color='white'"
onmouseout="this.style.backgroundColor='transparent'; this.style.color='var(--danger-color)'">
<i class="fas fa-trash"></i> Delete Selected
</button>
{% endif %}
</div>
</div>
<div class="card-body">
<div id="uploadProgressContainer" style="display:none; margin-bottom: 1rem; width: 100%;">
<div class="progress" style="height: 1.25rem; background-color: var(--primary-bg-light);">
<div id="uploadProgressBar" class="progress-bar" role="progressbar"
style="width:0%; background-color:var(--primary-color); color:var(--white);">0%</div>
</div>
<div id="uploadProgressText" class="small text-muted mt-1"></div>
<div id="uploadError" class="alert alert-danger alert-dismissible fade show mt-2" style="display:none;"
role="alert">
<div id="uploadErrorContent"></div>
<button type="button" class="btn-close"
onclick="document.getElementById('uploadError').style.display='none'; document.getElementById('uploadErrorContent').innerHTML='';"></button>
</div>
</div>
<div class="d-flex align-items-center gap-2 mb-3">
<button id="upBtn" class="btn btn-outline-secondary btn-sm" hidden style="display:none;"
title="Go up one level" onclick="navigateToParent()">
<i class="fas fa-arrow-up"></i>
</button>
<div id="breadcrumb" class="d-flex align-items-center gap-2"></div>
<div class="ms-auto" style="max-width: 300px; position: relative;">
<input type="text" id="quickSearchInput" class="form-control form-control-sm"
placeholder="Quick search files..." autocomplete="off" style="padding-right: 2rem;" />
<button id="clearSearchBtn" type="button"
style="position: absolute; right: 0.25rem; top: 50%; transform: translateY(-50%); display: none; border: none; background: transparent; font-size: 1.2rem; color: #888; cursor: pointer; z-index: 2;">&times;</button>
</div>
</div>
<div id="fileGrid" class="row g-3" style="min-height: 200px; position: relative; margin-top: 0.5rem;">
<div id="dropZoneOverlay"
style="display: none; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(22, 118, 123, 0.1); border: 2px dashed #16767b; border-radius: 8px; z-index: 1000; pointer-events: none;">
<div
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #16767b;">
<i class="fas fa-cloud-upload-alt" style="font-size: 3rem; margin-bottom: 1rem;"></i>
<div style="font-size: 1.2rem; font-weight: 500;">Drop files here to upload</div>
</div>
</div>
</div>
<div id="fileError" class="text-danger mt-2"></div>
</div>
</div>
</div>
<div id="deleteConfirmModal" class="modal fade" tabindex="-1" aria-labelledby="deleteConfirmLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteConfirmLabel">Move to Trash</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="d-flex align-items-center gap-3 mb-3">
<i class="fas fa-trash" style="font-size: 2rem; color: var(--danger-color);"></i>
<div>
<h6 class="mb-1">Move to Trash</h6>
<p class="text-muted mb-0" id="deleteFileName"></p>
</div>
</div>
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
This item will be moved to trash. You can restore it from the trash page within 30 days.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" id="confirmDeleteBtn"
style="background-color: var(--danger-color); border-color: var(--danger-color);">
<i class="fas fa-trash me-1"></i>Move to Trash
</button>
</div>
</div>
</div>
</div>
<div id="newFolderModal" class="modal fade" tabindex="-1" aria-labelledby="newFolderLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newFolderLabel">Create New Folder</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="text" id="folderNameInput" class="form-control" placeholder="Folder name"
autocomplete="off" />
<div id="folderError" class="text-danger mt-2"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="createFolderBtn"
style="background-color: var(--primary-color); border-color: var(--primary-color);">Create</button>
</div>
</div>
</div>
</div>
<div id="renameModal" class="modal fade" tabindex="-1" aria-labelledby="renameLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="renameLabel">Rename</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="renameInputGroup"></div>
<div id="renameError" class="text-danger mt-2"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="confirmRenameBtn"
style="background-color: var(--primary-color); border-color: var(--primary-color);">Rename</button>
</div>
</div>
</div>
</div>
<!-- Details Modal -->
<div id="detailsModal" class="modal fade" tabindex="-1" aria-labelledby="detailsModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="detailsModalLabel">Item Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="detailsModalBody">
<!-- Populated by JS -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="overwriteConfirmModal" class="modal fade" tabindex="-1" aria-labelledby="overwriteConfirmLabel"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="overwriteConfirmLabel">Overwrite File?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p id="overwriteFileMsg">A file with this name already exists. Do you want to overwrite <span
id="overwriteFileName" class="fw-bold"></span>?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="skipOverwriteBtn">Skip</button>
<button type="button" class="btn btn-secondary" id="skipAllOverwriteBtn">Skip All</button>
<button type="button" class="btn btn-danger" id="confirmOverwriteBtn"
style="background-color: var(--danger-color); border-color: var(--danger-color);">Overwrite</button>
<button type="button" class="btn btn-danger" id="confirmAllOverwriteBtn"
style="background-color: var(--danger-color); border-color: var(--danger-color);">Overwrite
All</button>
</div>
</div>
</div>
</div>
<!-- Move Modal -->
<div id="moveModal" class="modal fade" tabindex="-1" aria-labelledby="moveModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="moveModalLabel">Move File</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label for="moveTargetFolder" class="form-label">Select Target Folder</label>
<select class="form-select" id="moveTargetFolder">
<option value="">Root Folder</option>
</select>
</div>
<div id="moveError" class="text-danger"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="confirmMoveBtn"
style="background-color: var(--primary-color); border-color: var(--primary-color);">Move</button>
</div>
</div>
</div>
</div>
<!-- Include modals -->
{% include 'components/details_modal.html' %}
{% include 'components/file_preview_modal.html' %}
{% endblock %}
{% block extra_js %}
<script>
// Add error handling for script loading
window.addEventListener('error', function (e) {
console.error('Script loading error:', e);
});
</script>
<script type="module">
// Test if modules are working
console.log('Module system is working');
</script>
<script type="module" src="{{ url_for('static', filename='js/rooms/room.js') }}?v={{ 'js/rooms/room.js'|asset_version }}"></script>
<script type="module" src="{{ url_for('static', filename='js/rooms/fileManager.js') }}?v={{ 'js/rooms/fileManager.js'|asset_version }}"></script>
<script type="module" src="{{ url_for('static', filename='js/rooms/viewManager.js') }}?v={{ 'js/rooms/viewManager.js'|asset_version }}"></script>
<script type="module" src="{{ url_for('static', filename='js/rooms/uploadManager.js') }}?v={{ 'js/rooms/uploadManager.js'|asset_version }}"></script>
<script type="module" src="{{ url_for('static', filename='js/rooms/searchManager.js') }}?v={{ 'js/rooms/searchManager.js'|asset_version }}"></script>
<script type="module" src="{{ url_for('static', filename='js/rooms/modalManager.js') }}?v={{ 'js/rooms/modalManager.js'|asset_version }}"></script>
{% endblock %}