documentation for all JS files

This commit is contained in:
2025-05-28 16:01:18 +02:00
parent 1134f5b099
commit 5c5829c487
22 changed files with 984 additions and 26 deletions

View File

@@ -1,4 +1,23 @@
/**
* @fileoverview Manages file operations and state for the room interface.
* This file handles:
* - File fetching and state management
* - File operations (delete, rename, move, download)
* - File selection and batch operations
* - Star/unstar functionality
* - Navigation and path management
*/
/**
* @class FileManager
* @classdesc Manages all file-related operations and state in the room interface.
* Handles file operations, selection, and navigation.
*/
export class FileManager {
/**
* Creates a new FileManager instance.
* @param {RoomManager} roomManager - The parent RoomManager instance
*/
constructor(roomManager) {
console.log('[FileManager] Initializing...');
this.roomManager = roomManager;
@@ -13,6 +32,12 @@ export class FileManager {
console.log('[FileManager] Initialized with roomManager:', roomManager);
}
/**
* Fetches files from the server for the current path.
* @async
* @returns {Promise<Array>} A promise that resolves with the array of files
* @throws {Error} If the fetch operation fails
*/
async fetchFiles() {
console.log('[FileManager] Fetching files...');
try {
@@ -44,6 +69,13 @@ export class FileManager {
}
}
/**
* Deletes a file from the server.
* @async
* @param {string} filename - The name of the file to delete
* @param {string} [path=''] - The path of the file to delete
* @throws {Error} If the delete operation fails
*/
async deleteFile(filename, path = '') {
console.log('[FileManager] Deleting file:', { filename, path });
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
@@ -90,6 +122,14 @@ export class FileManager {
}
}
/**
* Renames a file on the server.
* @async
* @param {string} fileId - The ID of the file to rename
* @param {string} newName - The new name for the file
* @returns {Promise<Object>} A promise that resolves with the result of the rename operation
* @throws {Error} If the rename operation fails
*/
async renameFile(fileId, newName) {
console.log('[FileManager] Renaming file:', { fileId, newName });
try {
@@ -127,6 +167,14 @@ export class FileManager {
}
}
/**
* Moves a file to a new location.
* @async
* @param {string} fileId - The ID of the file to move
* @param {string} targetPath - The target path to move the file to
* @returns {Promise<Object>} A promise that resolves with the result of the move operation
* @throws {Error} If the move operation fails
*/
async moveFile(fileId, targetPath) {
console.log('[FileManager] Starting moveFile...');
console.log('[FileManager] Parameters:', { fileId, targetPath });
@@ -178,6 +226,11 @@ export class FileManager {
}
}
/**
* Handles the confirmed move operation after user confirmation.
* @async
* @throws {Error} If the move operation fails
*/
async moveFileConfirmed() {
console.log('[FileManager] Starting moveFileConfirmed...');
console.log('[FileManager] Current state:', {
@@ -258,6 +311,13 @@ export class FileManager {
}
}
/**
* Toggles the star status of a file.
* @async
* @param {string} filename - The name of the file to toggle star for
* @param {string} path - The path of the file
* @throws {Error} If the star toggle operation fails
*/
async toggleStar(filename, path) {
console.log('[FileManager] Toggling star for:', filename, 'path:', path);
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
@@ -323,6 +383,13 @@ export class FileManager {
}
}
/**
* Downloads a single file.
* @async
* @param {string} filename - The name of the file to download
* @param {string} [path=''] - The path of the file
* @throws {Error} If the download operation fails
*/
async downloadFile(filename, path = '') {
console.log('[FileManager] Downloading file:', { filename, path });
const url = `/api/rooms/${this.roomManager.roomId}/files/${encodeURIComponent(filename)}`;
@@ -360,6 +427,11 @@ export class FileManager {
}
}
/**
* Downloads multiple selected files as a zip archive.
* @async
* @throws {Error} If the download operation fails
*/
async downloadSelected() {
console.log('[FileManager] Downloading selected files...');
const selectedItems = this.getSelectedItems();
@@ -414,6 +486,12 @@ export class FileManager {
}
}
/**
* Handles the confirmed delete operation after user confirmation.
* Supports both single file and batch deletion.
* @async
* @throws {Error} If the delete operation fails
*/
async deleteFileConfirmed() {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
if (this.batchDeleteItems && this.batchDeleteItems.length) {
@@ -476,6 +554,12 @@ export class FileManager {
}
}
/**
* Updates the file selection based on user interaction.
* Supports single selection, CTRL+click for multiple selection, and SHIFT+click for range selection.
* @param {number} index - The index of the file being selected
* @param {Event} event - The click event that triggered the selection
*/
updateSelection(index, event) {
console.log('[FileManager] Updating selection:', { index, event });
@@ -521,11 +605,18 @@ export class FileManager {
this.roomManager.viewManager.updateMultiSelectUI();
}
/**
* Gets an array of currently selected file objects.
* @returns {Array<Object>} Array of selected file objects
*/
getSelectedItems() {
console.log('[FileManager] Getting selected items');
return Array.from(this.selectedItems).map(index => this.currentFiles[index]);
}
/**
* Clears all file selections and updates the UI.
*/
clearSelection() {
console.log('[FileManager] Clearing selection');
this.selectedItems.clear();
@@ -535,6 +626,9 @@ export class FileManager {
this.roomManager.viewManager.updateMultiSelectUI();
}
/**
* Navigates to the parent folder of the current path.
*/
navigateToParent() {
if (!this.roomManager.currentPath) return;
const parts = this.roomManager.currentPath.split('/');

View File

@@ -1,4 +1,24 @@
/**
* @fileoverview Manages modal dialogs for the room interface.
* This file handles:
* - Modal initialization and configuration
* - File operations (delete, rename, move)
* - Folder creation
* - File details display
* - Overwrite confirmation
* - Batch operations
*/
/**
* @class ModalManager
* @classdesc Manages all modal dialogs and their interactions in the room interface.
* Handles file operations, folder creation, and various confirmation dialogs.
*/
export class ModalManager {
/**
* Creates a new ModalManager instance.
* @param {RoomManager} roomManager - The parent RoomManager instance
*/
constructor(roomManager) {
this.roomManager = roomManager;
@@ -16,6 +36,10 @@ export class ModalManager {
this.initializeModals();
}
/**
* Initializes event listeners for all modals.
* Sets up handlers for delete, new folder, rename, and move operations.
*/
initializeModals() {
// Initialize delete modal
if (this.roomManager.canDelete) {
@@ -55,6 +79,11 @@ export class ModalManager {
}
}
/**
* Shows the delete confirmation modal for a single file.
* @param {string} filename - The name of the file to delete
* @param {string} [path=''] - The path of the file to delete
*/
showDeleteModal(filename, path = '') {
console.log('[ModalManager] Showing delete modal for:', { filename, path });
const fileNameEl = document.getElementById('deleteFileName');
@@ -82,6 +111,10 @@ export class ModalManager {
this.deleteModal.show();
}
/**
* Shows the delete confirmation modal for multiple selected files.
* Processes all selected checkboxes and prepares for batch deletion.
*/
showBatchDeleteModal() {
const selectedCheckboxes = document.querySelectorAll('.select-item-checkbox:checked');
if (selectedCheckboxes.length === 0) return;
@@ -130,6 +163,10 @@ export class ModalManager {
this.deleteModal.show();
}
/**
* Shows the rename modal for a file or folder.
* @param {string} filename - The current name of the file/folder
*/
showRenameModal(filename) {
document.getElementById('renameError').textContent = '';
const ext = filename.includes('.') ? filename.substring(filename.lastIndexOf('.')) : '';
@@ -149,6 +186,10 @@ export class ModalManager {
}, 100);
}
/**
* Shows the file details modal.
* @param {Object} file - The file object containing details to display
*/
showDetailsModal(file) {
const icon = file.type === 'folder'
? `<i class='fas fa-folder' style='font-size:2.2rem;color:var(--primary-color);'></i>`
@@ -182,6 +223,11 @@ export class ModalManager {
this.detailsModal.show();
}
/**
* Shows the overwrite confirmation modal.
* @param {string} filename - The name of the file that would be overwritten
* @returns {Promise<string>} A promise that resolves with the user's choice ('skip', 'skip_all', 'overwrite', or 'overwrite_all')
*/
showOverwriteModal(filename) {
return new Promise((resolve) => {
const fileNameEl = document.getElementById('overwriteFileName');
@@ -206,6 +252,11 @@ export class ModalManager {
});
}
/**
* Shows the move file modal.
* @param {string} fileId - The ID of the file to move
* @param {string} path - The current path of the file
*/
showMoveModal(fileId, path) {
console.log('[ModalManager] Showing move modal for file:', { fileId, path });
document.getElementById('moveError').textContent = '';
@@ -251,6 +302,10 @@ export class ModalManager {
});
}
/**
* Creates a new folder in the current path.
* @async
*/
async createFolder() {
const folderName = document.getElementById('folderNameInput').value.trim();
if (!folderName) {
@@ -290,6 +345,10 @@ export class ModalManager {
}
}
/**
* Renames a file or folder.
* @async
*/
async renameFile() {
const newName = document.getElementById('renameInput').value.trim();
if (!newName) {

View File

@@ -1,3 +1,13 @@
/**
* @fileoverview Main room management module that coordinates all room functionality.
* This file handles:
* - Room initialization and configuration
* - Manager coordination (File, View, Upload, Search, Modal)
* - Navigation and path management
* - Event handling and user interactions
* - Permission management
*/
console.log('[RoomManager] Script loaded');
// Main room.js file - Coordinates all room functionality
@@ -9,7 +19,23 @@ import { ModalManager } from './modalManager.js';
console.log('[RoomManager] All modules imported successfully');
/**
* @class RoomManager
* @classdesc Main class that coordinates all room functionality and manages the various
* sub-managers (File, View, Upload, Search, Modal).
*/
class RoomManager {
/**
* Creates a new RoomManager instance.
* @param {Object} config - Configuration object for the room
* @param {string} config.roomId - The ID of the room
* @param {boolean} config.canDelete - Whether the user can delete files
* @param {boolean} config.canShare - Whether the user can share files
* @param {boolean} config.canUpload - Whether the user can upload files
* @param {boolean} config.canDownload - Whether the user can download files
* @param {boolean} config.canRename - Whether the user can rename files
* @param {boolean} config.canMove - Whether the user can move files
*/
constructor(config) {
console.log('[RoomManager] Initializing with config:', config);
this.roomId = config.roomId;
@@ -33,6 +59,11 @@ class RoomManager {
this.initialize();
}
/**
* Initializes the room functionality.
* Sets up the view, fetches files, initializes search, and sets up event listeners.
* @async
*/
async initialize() {
console.log('[RoomManager] Starting initialization...');
// Get current path from URL
@@ -68,12 +99,19 @@ class RoomManager {
}
}
/**
* Navigates to a subfolder within the current path.
* @param {string} folderName - The name of the folder to navigate to
*/
navigateToFolder(folderName) {
console.log('[RoomManager] Navigating to folder:', folderName);
const newPath = this.currentPath ? `${this.currentPath}/${folderName}` : folderName;
this.navigateTo(newPath);
}
/**
* Navigates to the parent folder of the current path.
*/
navigateToParent() {
console.log('[RoomManager] Navigating to parent folder');
if (!this.currentPath) return;
@@ -84,6 +122,10 @@ class RoomManager {
this.navigateTo(newPath);
}
/**
* Navigates to a specific path and updates the URL.
* @param {string} path - The path to navigate to
*/
navigateTo(path) {
console.log('[RoomManager] Navigating to path:', path);
this.currentPath = path;
@@ -101,11 +143,20 @@ class RoomManager {
});
}
/**
* Gets the current path from the URL parameters.
* @returns {string} The current path from the URL
*/
getPathFromUrl() {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get('path') || '';
}
/**
* Initializes event listeners for user interactions.
* Sets up handlers for select all, download selected, delete selected,
* and click outside to clear selection.
*/
initializeEventListeners() {
console.log('[RoomManager] Setting up event listeners');
@@ -151,7 +202,10 @@ class RoomManager {
}
}
// Initialize the room manager when the DOM is loaded
/**
* Initializes the room manager when the DOM is loaded.
* Creates a new RoomManager instance with configuration from meta tags.
*/
document.addEventListener('DOMContentLoaded', () => {
const config = {
roomId: document.querySelector('meta[name="room-id"]').getAttribute('content'),

View File

@@ -1,10 +1,34 @@
/**
* @fileoverview Manages search functionality for the room interface.
* This file handles:
* - Quick search input processing
* - Debounced search execution
* - File filtering based on search terms
* - Search state management
* - Clear search functionality
*/
/**
* @class SearchManager
* @classdesc Manages search operations including input handling, debounced search execution,
* and file filtering based on search criteria.
*/
export class SearchManager {
/**
* Creates a new SearchManager instance.
* @param {RoomManager} roomManager - The parent RoomManager instance
*/
constructor(roomManager) {
this.roomManager = roomManager;
this.searchInput = document.getElementById('quickSearchInput');
this.clearSearchBtn = document.getElementById('clearSearchBtn');
}
/**
* Initializes the search functionality.
* Sets up event listeners for search input and clear button.
* Creates a debounced search function to prevent excessive searches.
*/
initialize() {
if (!this.searchInput) return;
@@ -35,6 +59,11 @@ export class SearchManager {
}
}
/**
* Performs the search operation on the current file list.
* Filters files based on name and type matching the search term.
* @param {string} searchTerm - The term to search for
*/
performSearch(searchTerm) {
if (!this.roomManager.fileManager.currentFiles) return;
@@ -47,6 +76,14 @@ export class SearchManager {
this.roomManager.viewManager.renderFiles(filteredFiles);
}
/**
* Creates a debounced version of a function.
* Delays the execution of the function until after a specified wait time
* has elapsed since the last time it was invoked.
* @param {Function} func - The function to debounce
* @param {number} wait - The number of milliseconds to delay
* @returns {Function} The debounced function
*/
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {

View File

@@ -1,4 +1,24 @@
/**
* @fileoverview Manages file upload functionality for the room interface.
* This file handles:
* - File upload initialization and configuration
* - Drag and drop file handling
* - Upload progress tracking
* - File type validation
* - Overwrite handling
* - Batch upload management
*/
/**
* @class UploadManager
* @classdesc Manages file upload operations including drag-and-drop, progress tracking,
* and handling of file conflicts and validations.
*/
export class UploadManager {
/**
* Creates a new UploadManager instance.
* @param {RoomManager} roomManager - The parent RoomManager instance
*/
constructor(roomManager) {
this.roomManager = roomManager;
this.pendingUploads = [];
@@ -19,6 +39,10 @@ export class UploadManager {
this.initializeUploadHandlers();
}
/**
* Initializes event handlers for file upload functionality.
* Sets up drag and drop handlers and file input change handlers.
*/
initializeUploadHandlers() {
if (!this.roomManager.canUpload) return;
@@ -44,19 +68,33 @@ export class UploadManager {
this.fileInput.addEventListener('change', this.handleFileSelect.bind(this));
}
/**
* Prevents default browser behavior for drag and drop events.
* @param {Event} e - The event object
*/
preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
/**
* Highlights the drop zone when files are dragged over it.
*/
highlight() {
this.dropZoneOverlay.style.display = 'block';
}
/**
* Removes highlight from the drop zone.
*/
unhighlight() {
this.dropZoneOverlay.style.display = 'none';
}
/**
* Handles files dropped onto the drop zone.
* @param {DragEvent} e - The drop event object
*/
async handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
@@ -66,11 +104,18 @@ export class UploadManager {
}
}
/**
* Handles files selected through the file input.
*/
async handleFileSelect() {
if (!this.fileInput.files.length) return;
await this.startUpload(Array.from(this.fileInput.files));
}
/**
* Initiates the upload process for a set of files.
* @param {Array<File>} files - Array of files to upload
*/
async startUpload(files) {
this.uploadProgressContainer.style.display = 'block';
this.uploadProgressBar.style.width = '0%';
@@ -85,6 +130,10 @@ export class UploadManager {
await this.uploadFilesSequentially();
}
/**
* Uploads files one at a time, handling progress and errors.
* @async
*/
async uploadFilesSequentially() {
let completedFiles = 0;
let currentFileIndex = 0;
@@ -182,6 +231,11 @@ export class UploadManager {
await processNextFile();
}
/**
* Uploads a single file to the server.
* @param {FormData} formData - Form data containing the file and upload parameters
* @returns {Promise<Object>} Response object containing success status and error message if any
*/
async uploadFile(formData) {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const response = await fetch(`/api/rooms/${this.roomManager.roomId}/files/upload`, {
@@ -197,6 +251,11 @@ export class UploadManager {
};
}
/**
* Handles file type validation errors.
* Displays error message with allowed file types.
* @param {File} file - The file that failed validation
*/
handleFileTypeError(file) {
const allowedTypes = [
'Documents: PDF, DOCX, DOC, TXT, RTF, ODT, MD, CSV',
@@ -225,6 +284,12 @@ export class UploadManager {
this.uploadProgressBar.className = 'progress-bar bg-danger-opacity-15 text-danger';
}
/**
* Handles file existence conflicts during upload.
* @param {File} file - The file being uploaded
* @param {FormData} formData - Form data for the upload
* @returns {Promise<Object>} Object containing continue status
*/
async handleFileExists(file, formData) {
if (this.overwriteAll) {
formData.append('overwrite', 'true');

View File

@@ -1,4 +1,23 @@
/**
* @fileoverview Manages the file view functionality for the room interface.
* This file handles:
* - Grid and list view rendering
* - File sorting and organization
* - Breadcrumb navigation
* - File action buttons
* - Multi-select functionality
*/
/**
* @class ViewManager
* @classdesc Manages the visual representation and interaction of files in the room interface.
* Handles view switching, file rendering, sorting, and UI updates.
*/
export class ViewManager {
/**
* Creates a new ViewManager instance.
* @param {RoomManager} roomManager - The parent RoomManager instance
*/
constructor(roomManager) {
console.log('[ViewManager] Initializing...');
this.roomManager = roomManager;
@@ -8,6 +27,11 @@ export class ViewManager {
console.log('[ViewManager] Initialized with roomManager:', roomManager);
}
/**
* Initializes the view with user preferences.
* Fetches and applies the user's preferred view type.
* @async
*/
async initializeView() {
console.log('[ViewManager] Initializing view...');
try {
@@ -29,6 +53,12 @@ export class ViewManager {
}
}
/**
* Toggles between grid and list views.
* Updates UI and saves user preference.
* @async
* @param {string} view - The view type to switch to ('grid' or 'list')
*/
async toggleView(view) {
console.log('[ViewManager] Toggling view to:', view);
this.currentView = view;
@@ -60,6 +90,11 @@ export class ViewManager {
}
}
/**
* Renders the file list in the current view mode.
* @async
* @param {Array<Object>} files - Array of file objects to render
*/
async renderFiles(files) {
console.log('[ViewManager] Rendering files:', files);
const fileGrid = document.getElementById('fileGrid');
@@ -83,6 +118,10 @@ export class ViewManager {
}
}
/**
* Renders the breadcrumb navigation.
* Shows the current path and provides navigation controls.
*/
renderBreadcrumb() {
console.log('[ViewManager] Rendering breadcrumb');
const breadcrumb = document.getElementById('breadcrumb');
@@ -140,6 +179,11 @@ export class ViewManager {
console.log('[ViewManager] Breadcrumb rendered');
}
/**
* Renders the file list in list view mode.
* @async
* @param {Array<Object>} files - Array of file objects to render
*/
async renderListView(files) {
console.log('[ViewManager] Rendering list view');
const fileGrid = document.getElementById('fileGrid');
@@ -172,6 +216,11 @@ export class ViewManager {
console.log('[ViewManager] List view rendered');
}
/**
* Renders the file list in grid view mode.
* @async
* @param {Array<Object>} files - Array of file objects to render
*/
async renderGridView(files) {
console.log('[ViewManager] Rendering grid view');
const fileGrid = document.getElementById('fileGrid');
@@ -193,6 +242,12 @@ export class ViewManager {
console.log('[ViewManager] Grid view rendered');
}
/**
* Renders a single file row for list view.
* @param {Object} file - The file object to render
* @param {number} index - The index of the file in the list
* @returns {string} HTML string for the file row
*/
renderFileRow(file, index) {
console.log('[ViewManager] Rendering file row:', { file, index });
const isFolder = file.type === 'folder';
@@ -226,6 +281,12 @@ export class ViewManager {
`;
}
/**
* Renders a single file card for grid view.
* @param {Object} file - The file object to render
* @param {number} index - The index of the file in the list
* @returns {string} HTML string for the file card
*/
renderFileCard(file, index) {
console.log('[ViewManager] Rendering file card:', { file, index });
const isFolder = file.type === 'folder';
@@ -260,6 +321,12 @@ export class ViewManager {
`;
}
/**
* Renders the action buttons for a file.
* @param {Object} file - The file object
* @param {number} index - The index of the file in the list
* @returns {string} HTML string for the action buttons
*/
renderFileActions(file, index) {
console.log('[ViewManager] Rendering file actions:', { file, index });
const actions = [];
@@ -321,6 +388,11 @@ export class ViewManager {
return actions.join('');
}
/**
* Sorts the file list based on current sort settings.
* @param {Array<Object>} files - Array of file objects to sort
* @returns {Array<Object>} Sorted array of file objects
*/
sortFiles(files) {
console.log('[ViewManager] Sorting files:', {
column: this.sortColumn,
@@ -342,6 +414,11 @@ export class ViewManager {
});
}
/**
* Gets the appropriate icon class for a file based on its extension.
* @param {string} filename - The name of the file
* @returns {string} Font Awesome icon class name
*/
getFileIcon(filename) {
const extension = filename.split('.').pop().toLowerCase();
console.log('[ViewManager] Getting icon for file:', { filename, extension });
@@ -368,6 +445,11 @@ export class ViewManager {
return iconMap[extension] || 'fa-file';
}
/**
* Formats a file size in bytes to a human-readable string.
* @param {number} bytes - The file size in bytes
* @returns {string} Formatted file size string
*/
formatFileSize(bytes) {
if (!bytes) return '0 B';
@@ -383,6 +465,9 @@ export class ViewManager {
return `${size.toFixed(1)} ${units[unitIndex]}`;
}
/**
* Updates the multi-select UI based on current selection state.
*/
updateMultiSelectUI() {
console.log('[ViewManager] Updating multi-select UI');
const selectedItems = this.roomManager.fileManager.getSelectedItems();