diff --git a/integrations/context-menu/file-context-menu-integration.ts b/integrations/context-menu/file-context-menu-integration.ts index 6de8e46..9ffa482 100644 --- a/integrations/context-menu/file-context-menu-integration.ts +++ b/integrations/context-menu/file-context-menu-integration.ts @@ -1,11 +1,11 @@ import { App, Menu, TFile } from 'obsidian'; -import { NoteStatusSettings } from '../../models/types'; -import { ExplorerIntegration } from '../explorer/explorer-integration'; +import { NoteStatusSettings } from 'models/types'; import { StatusService } from 'services/status-service'; -import { StatusContextMenu } from './status-context-menu'; +import { ExplorerIntegration } from 'integrations/explorer/explorer-integration'; +import { StatusContextMenu } from 'integrations/context-menu/status-context-menu'; /** - * Gestiona menús contextuales del explorador de archivos + * Gestiona la integración de menús contextuales con el explorador de archivos */ export class FileContextMenuIntegration { private app: App; @@ -36,15 +36,17 @@ export class FileContextMenuIntegration { } /** - * Registra los elementos del menú de archivo + * Registra los eventos del menú contextual de archivos */ public registerFileContextMenuEvents(): void { + // Evento para archivo único this.app.workspace.on('file-menu', (menu, file, source) => { if (source === 'file-explorer-context-menu' && file instanceof TFile && file.extension === 'md') { this.addStatusChangeMenu(menu, file); } }); + // Evento para múltiples archivos this.app.workspace.on('files-menu', (menu, files) => { const mdFiles = files.filter(file => file instanceof TFile && file.extension === 'md' @@ -57,45 +59,25 @@ export class FileContextMenuIntegration { } /** - * Añade opción de cambio de estado al menú de archivo + * Añade opción de cambio de estado al menú contextual de un archivo */ private addStatusChangeMenu(menu: Menu, file: TFile): void { - menu.addItem(item => - item - .setTitle('Change status') - .setIcon('tag') - .onClick(() => { - const selectedFiles = this.explorerIntegration.getSelectedFiles(); - if (selectedFiles.length > 1) { - this.showStatusChangeModal(selectedFiles); - } else { - this.showStatusChangeModal([file]); - } - }) - ); + this.statusContextMenu.addStatusMenuItemToSingleFile(menu, file, (file) => { + const selectedFiles = this.explorerIntegration.getSelectedFiles(); + if (selectedFiles.length > 1) { + this.statusContextMenu.showForFiles(selectedFiles); + } else { + this.statusContextMenu.showForFiles([file]); + } + }); } /** * Añade opción de cambio de estado para múltiples archivos */ private addBatchStatusChangeMenu(menu: Menu, files: TFile[]): void { - menu.addItem(item => - item - .setTitle('Change status') - .setIcon('tag') - .onClick(() => { - this.showStatusChangeModal(files); - }) - ); - } - - /** - * Muestra el modal para cambiar estado - */ - private showStatusChangeModal(files: TFile[]): void { - // Implementación que mostraría un modal para seleccionar estado - // En la práctica, esta función delegaría en un servicio de UI - console.log(`Cambiar estado para ${files.length} archivos`); - this.statusContextMenu.showForFiles(files) + this.statusContextMenu.addStatusMenuItemToBatch(menu, files, (files) => { + this.statusContextMenu.showForFiles(files); + }); } } \ No newline at end of file diff --git a/integrations/context-menu/status-context-menu.ts b/integrations/context-menu/status-context-menu.ts index 7367bd3..7f23f7a 100644 --- a/integrations/context-menu/status-context-menu.ts +++ b/integrations/context-menu/status-context-menu.ts @@ -1,18 +1,18 @@ import { App, Menu, TFile } from 'obsidian'; -import { NoteStatusSettings } from '../../models/types'; -import { StatusService } from '../../services/status-service'; +import { NoteStatusSettings } from 'models/types'; +import { StatusService } from 'services/status-service'; import { StatusDropdown } from 'components/status-dropdown'; -import { ExplorerIntegration } from 'integrations/explorer'; +import { ExplorerIntegration } from 'integrations/explorer/explorer-integration'; /** - * Handles context menu interactions for status changes + * Gestiona los menús contextuales para cambios de estado */ export class StatusContextMenu { - private statusDropdown: StatusDropdown; + private app: App; private settings: NoteStatusSettings; private statusService: StatusService; + private statusDropdown: StatusDropdown; private explorerIntegration: ExplorerIntegration; - public app: App; constructor( app: App, @@ -29,14 +29,40 @@ export class StatusContextMenu { } /** - * Updates settings reference + * Actualiza la configuración */ public updateSettings(settings: NoteStatusSettings): void { this.settings = settings; } /** - * Shows the context menu for changing status of one or more files + * Añade ítem de menú para cambiar estado de un archivo + */ + public addStatusMenuItemToSingleFile(menu: Menu, file: TFile, onClick: (file: TFile) => void): void { + menu.addItem(item => + item + .setTitle('Change status') + .setIcon('tag') + .onClick(() => onClick(file)) + ); + } + + /** + * Añade ítem de menú para cambiar estado de múltiples archivos + */ + public addStatusMenuItemToBatch(menu: Menu, files: TFile[], onClick: (files: TFile[]) => void): void { + menu.addItem(item => + item + .setTitle('Change status') + .setIcon('tag') + .onClick(() => onClick(files)) + ); + } + + /** + * Muestra el menú contextual para cambiar estado de uno o más archivos + * @param files Archivos a los que cambiar el estado + * @param position Posición opcional para mostrar el menú */ public showForFiles(files: TFile[], position?: { x: number; y: number }): void { if (files.length === 0) return; @@ -44,38 +70,16 @@ export class StatusContextMenu { if (files.length === 1) { this.showForSingleFile(files[0], position); } else { - const menu = new Menu(); - - menu.addItem((item) => { - item.setTitle(`Update ${files.length} files`) - .setDisabled(true); - return item; - }); - - menu.addItem((item) => - item - .setTitle('Manage statuses...') - .setIcon('tag') - .onClick(() => { - this.statusDropdown.openStatusDropdown({ - position, - files - }); - }) - ); - - if (position) { - menu.showAtPosition(position); - } else { - menu.showAtMouseEvent(new MouseEvent('contextmenu')); - } + this.showForMultipleFiles(files, position); } } /** - * Shows a context menu for a single file + * Muestra el menú contextual para un solo archivo + * @param file Archivo al que cambiar el estado + * @param position Posición opcional para mostrar el menú */ - public showForSingleFile(file: TFile, position?: { x: number; y: number }): void { + private showForSingleFile(file: TFile, position?: { x: number; y: number }): void { if (!(file instanceof TFile) || file.extension !== 'md') return; this.statusDropdown.openStatusDropdown({ @@ -83,4 +87,40 @@ export class StatusContextMenu { files: [file] }); } + + /** + * Muestra el menú contextual para múltiples archivos + * @param files Archivos a los que cambiar el estado + * @param position Posición opcional para mostrar el menú + */ + private showForMultipleFiles(files: TFile[], position?: { x: number; y: number }): void { + const menu = new Menu(); + + // Elemento de información (deshabilitado) + menu.addItem((item) => { + item.setTitle(`Update ${files.length} files`) + .setDisabled(true); + return item; + }); + + // Opción para gestionar estados + menu.addItem((item) => + item + .setTitle('Manage statuses...') + .setIcon('tag') + .onClick(() => { + this.statusDropdown.openStatusDropdown({ + position, + files + }); + }) + ); + + // Mostrar el menú en la posición adecuada + if (position) { + menu.showAtPosition(position); + } else { + menu.showAtMouseEvent(new MouseEvent('contextmenu')); + } + } } \ No newline at end of file