/** * TASKMATE - Proposals Manager * ============================ * Genehmigungen (projektbezogen) */ import api from './api.js'; import { $, $$ } from './utils.js'; import authManager from './auth.js'; import store from './store.js'; class ProposalsManager { constructor() { this.proposals = []; this.currentSort = 'date'; this.showArchived = false; this.searchQuery = ''; this.allTasks = []; this.initialized = false; } async init() { console.log('[Proposals] init() called, initialized:', this.initialized); if (this.initialized) { await this.loadProposals(); return; } // DOM Elements - erst bei init() laden this.proposalsView = $('#view-proposals'); this.proposalsList = $('#proposals-list'); this.proposalsEmpty = $('#proposals-empty'); this.sortSelect = $('#proposals-sort'); this.newProposalBtn = $('#btn-new-proposal'); this.archiveBtn = $('#btn-show-proposals-archive'); this.proposalsTitle = $('#proposals-title'); console.log('[Proposals] newProposalBtn found:', !!this.newProposalBtn); // Modal Elements this.proposalModal = $('#proposal-modal'); this.proposalForm = $('#proposal-form'); this.proposalTitle = $('#proposal-title'); this.proposalDescription = $('#proposal-description'); this.proposalTask = $('#proposal-task'); this.bindEvents(); this.initialized = true; console.log('[Proposals] Initialization complete'); await this.loadProposals(); } bindEvents() { console.log('[Proposals] bindEvents() called'); // Sort Change this.sortSelect?.addEventListener('change', () => { this.currentSort = this.sortSelect.value; this.loadProposals(); }); // Archive Toggle Button this.archiveBtn?.addEventListener('click', () => { this.showArchived = !this.showArchived; this.updateArchiveButton(); this.loadProposals(); }); // New Proposal Button if (this.newProposalBtn) { console.log('[Proposals] Binding click event to newProposalBtn'); this.newProposalBtn.addEventListener('click', () => { console.log('[Proposals] Button clicked!'); this.openNewProposalModal(); }); } else { console.error('[Proposals] newProposalBtn not found!'); } // Proposal Form Submit this.proposalForm?.addEventListener('submit', (e) => this.handleProposalSubmit(e)); // Modal close buttons this.proposalModal?.querySelectorAll('[data-close-modal]').forEach(btn => { btn.addEventListener('click', () => this.closeModal()); }); } updateArchiveButton() { if (this.archiveBtn) { this.archiveBtn.textContent = this.showArchived ? 'Aktive anzeigen' : 'Archiv anzeigen'; } if (this.proposalsTitle) { this.proposalsTitle.textContent = this.showArchived ? 'Archiv' : 'Genehmigungen'; } } resetToActiveView() { this.showArchived = false; this.searchQuery = ''; this.updateArchiveButton(); this.loadProposals(); } setSearchQuery(query) { this.searchQuery = query.toLowerCase().trim(); this.render(); } getFilteredProposals() { if (!this.searchQuery) { return this.proposals; } return this.proposals.filter(proposal => { const titleMatch = proposal.title?.toLowerCase().includes(this.searchQuery); const descriptionMatch = proposal.description?.toLowerCase().includes(this.searchQuery); return titleMatch || descriptionMatch; }); } getCurrentProjectId() { // Direkt die currentProjectId aus dem Store holen return store.get('currentProjectId') || null; } async loadProposals() { try { const projectId = this.getCurrentProjectId(); this.proposals = await api.getProposals(this.currentSort, this.showArchived, projectId); this.render(); } catch (error) { console.error('Error loading proposals:', error); this.showToast('Fehler beim Laden der Genehmigungen', 'error'); } } async loadTasks() { try { this.allTasks = await api.getAllTasks(); this.populateTaskDropdown(); } catch (error) { console.error('Error loading tasks:', error); } } populateTaskDropdown() { if (!this.proposalTask) return; const currentProjectId = this.getCurrentProjectId(); // Reset dropdown this.proposalTask.innerHTML = ''; // Nur Aufgaben des aktuellen Projekts anzeigen const projectTasks = this.allTasks.filter(task => task.project_id === currentProjectId); projectTasks.forEach(task => { const option = document.createElement('option'); option.value = task.id; option.textContent = task.title; this.proposalTask.appendChild(option); }); } render() { if (!this.proposalsList) return; const filteredProposals = this.getFilteredProposals(); if (filteredProposals.length === 0) { this.proposalsList.classList.add('hidden'); this.proposalsEmpty?.classList.remove('hidden'); // Update empty message based on search if (this.proposalsEmpty) { const h3 = this.proposalsEmpty.querySelector('h3'); const p = this.proposalsEmpty.querySelector('p'); if (this.searchQuery) { if (h3) h3.textContent = 'Keine Treffer'; if (p) p.textContent = 'Keine Genehmigungen entsprechen der Suche.'; } else { if (h3) h3.textContent = 'Keine Genehmigungen vorhanden'; if (p) p.textContent = 'Erstellen Sie die erste Genehmigung!'; } } return; } this.proposalsEmpty?.classList.add('hidden'); this.proposalsList.classList.remove('hidden'); const currentUserId = authManager.getUser()?.id; const canApprove = authManager.hasPermission('genehmigung'); this.proposalsList.innerHTML = filteredProposals.map(proposal => this.renderProposalCard(proposal, currentUserId, canApprove) ).join(''); // Bind event listeners this.bindProposalEvents(); } renderProposalCard(proposal, currentUserId, canApprove) { const isOwn = proposal.created_by === currentUserId; const initial = (proposal.created_by_name || 'U').charAt(0).toUpperCase(); const dateStr = this.formatDate(proposal.created_at); const isArchived = proposal.archived === 1; return `
${this.escapeHtml(proposal.description)}
` : ''} ${proposal.task_title ? `