2025-05-24 15:17:02 +02:00

318 lines
12 KiB
JavaScript

// Team management functionality
// Load teams
async function loadTeams() {
if (!config.isConfigured()) {
showAlert('Please configure your API settings first.', 'warning');
return;
}
const container = document.getElementById('teamsContainer');
container.innerHTML = '<div class="text-center"><div class="loading-spinner"></div> Loading teams...</div>';
try {
const teams = await apiClient.getTeams();
displayTeams(teams);
} catch (error) {
handleApiError(error, 'loading teams');
container.innerHTML = '<div class="alert alert-danger">Failed to load teams</div>';
}
}
// Display teams
function displayTeams(teams) {
const container = document.getElementById('teamsContainer');
if (!teams || teams.length === 0) {
container.innerHTML = `
<div class="text-center py-5">
<i class="fas fa-users fa-3x text-muted mb-3"></i>
<h4>No teams found</h4>
<p class="text-muted">Create your first team to get started!</p>
<button class="btn btn-primary" onclick="showCreateTeamModal()">
<i class="fas fa-plus me-1"></i>Create Team
</button>
</div>
`;
return;
}
const teamsHtml = `
<div class="row">
${teams.map(team => `
<div class="col-md-6 col-lg-4 mb-4">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">
<i class="fas fa-users me-2 text-primary"></i>
${escapeHtml(team.name)}
</h5>
<p class="card-text">${escapeHtml(team.description || 'No description')}</p>
<div class="text-muted small mb-3">
<i class="fas fa-calendar me-1"></i>Created: ${formatDate(team.created_at)}
</div>
</div>
<div class="card-footer bg-transparent">
<div class="btn-group w-100" role="group">
<button class="btn btn-outline-primary" onclick="viewTeam('${team.id}')">
<i class="fas fa-eye"></i> View
</button>
<button class="btn btn-outline-secondary" onclick="editTeam('${team.id}')">
<i class="fas fa-edit"></i> Edit
</button>
<button class="btn btn-outline-danger" onclick="deleteTeam('${team.id}')">
<i class="fas fa-trash"></i> Delete
</button>
</div>
</div>
</div>
</div>
`).join('')}
</div>
`;
container.innerHTML = teamsHtml;
}
// Show create team modal
function showCreateTeamModal() {
const modalBody = `
<form id="createTeamForm">
<div class="mb-3">
<label for="teamName" class="form-label">Team Name *</label>
<input type="text" class="form-control" id="teamName" required>
</div>
<div class="mb-3">
<label for="teamDescription" class="form-label">Description</label>
<textarea class="form-control" id="teamDescription" rows="3"
placeholder="Describe this team's purpose..."></textarea>
</div>
</form>
`;
const modalFooter = `
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="createTeam()">
<i class="fas fa-plus me-1"></i>Create Team
</button>
`;
const modal = createModal('createTeamModal', 'Create New Team', modalBody, modalFooter);
// Handle form submission
document.getElementById('createTeamForm').addEventListener('submit', (e) => {
e.preventDefault();
createTeam();
});
modal.show();
// Focus on name field
setTimeout(() => document.getElementById('teamName').focus(), 100);
}
// Create team
async function createTeam() {
const name = document.getElementById('teamName').value.trim();
const description = document.getElementById('teamDescription').value.trim();
if (!name) {
showAlert('Team name is required', 'danger');
return;
}
const createButton = document.querySelector('#createTeamModal .btn-primary');
setLoadingState(createButton);
try {
await apiClient.createTeam({
name,
description
});
showAlert('Team created successfully!', 'success');
// Close modal and refresh teams
bootstrap.Modal.getInstance(document.getElementById('createTeamModal')).hide();
removeModal('createTeamModal');
loadTeams();
} catch (error) {
handleApiError(error, 'creating team');
} finally {
setLoadingState(createButton, false);
}
}
// View team details
async function viewTeam(teamId) {
try {
const teams = await apiClient.getTeams();
const team = teams.find(t => t.id === teamId);
if (!team) {
showAlert('Team not found', 'danger');
return;
}
const modalBody = `
<div class="row">
<div class="col-12">
<h5><i class="fas fa-users me-2"></i>${escapeHtml(team.name)}</h5>
<p class="text-muted">${escapeHtml(team.description || 'No description')}</p>
<hr>
<div class="row">
<div class="col-md-6">
<h6>Team Information</h6>
<p><strong>Created:</strong> ${formatDate(team.created_at)}</p>
<p><strong>ID:</strong> <code>${team.id}</code></p>
</div>
<div class="col-md-6">
<h6>Statistics</h6>
<p><strong>Members:</strong> <span id="teamMemberCount">Loading...</span></p>
<p><strong>Status:</strong> <span class="badge bg-success">Active</span></p>
</div>
</div>
</div>
</div>
`;
const modalFooter = `
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="editTeam('${teamId}')">
<i class="fas fa-edit me-1"></i>Edit Team
</button>
`;
const modal = createModal('viewTeamModal', 'Team Details', modalBody, modalFooter);
modal.show();
// Load team member count
loadTeamMemberCount(teamId);
} catch (error) {
handleApiError(error, 'loading team details');
}
}
// Load team member count
async function loadTeamMemberCount(teamId) {
try {
const users = await apiClient.getUsers();
const teamMembers = users.filter(user => user.team_id === teamId);
document.getElementById('teamMemberCount').textContent = teamMembers.length;
} catch (error) {
document.getElementById('teamMemberCount').textContent = 'Error loading';
}
}
// Edit team
async function editTeam(teamId) {
try {
const teams = await apiClient.getTeams();
const team = teams.find(t => t.id === teamId);
if (!team) {
showAlert('Team not found', 'danger');
return;
}
const modalBody = `
<form id="editTeamForm">
<div class="mb-3">
<label for="editTeamName" class="form-label">Team Name *</label>
<input type="text" class="form-control" id="editTeamName"
value="${escapeHtml(team.name)}" required>
</div>
<div class="mb-3">
<label for="editTeamDescription" class="form-label">Description</label>
<textarea class="form-control" id="editTeamDescription" rows="3">${escapeHtml(team.description || '')}</textarea>
</div>
</form>
`;
const modalFooter = `
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="saveTeamChanges('${teamId}')">
<i class="fas fa-save me-1"></i>Save Changes
</button>
`;
const modal = createModal('editTeamModal', 'Edit Team', modalBody, modalFooter);
// Handle form submission
document.getElementById('editTeamForm').addEventListener('submit', (e) => {
e.preventDefault();
saveTeamChanges(teamId);
});
modal.show();
} catch (error) {
handleApiError(error, 'loading team for editing');
}
}
// Save team changes
async function saveTeamChanges(teamId) {
const name = document.getElementById('editTeamName').value.trim();
const description = document.getElementById('editTeamDescription').value.trim();
if (!name) {
showAlert('Team name is required', 'danger');
return;
}
const saveButton = document.querySelector('#editTeamModal .btn-primary');
setLoadingState(saveButton);
try {
await apiClient.updateTeam(teamId, {
name,
description
});
showAlert('Team updated successfully!', 'success');
// Close modal and refresh teams
bootstrap.Modal.getInstance(document.getElementById('editTeamModal')).hide();
removeModal('editTeamModal');
loadTeams();
// Close view modal if open
const viewModal = document.getElementById('viewTeamModal');
if (viewModal) {
bootstrap.Modal.getInstance(viewModal)?.hide();
removeModal('viewTeamModal');
}
} catch (error) {
handleApiError(error, 'updating team');
} finally {
setLoadingState(saveButton, false);
}
}
// Delete team
function deleteTeam(teamId) {
confirmAction('Are you sure you want to delete this team? This action cannot be undone and will affect all team members.', async () => {
try {
await apiClient.deleteTeam(teamId);
showAlert('Team deleted successfully!', 'success');
loadTeams();
// Close any open modals
const modals = ['viewTeamModal', 'editTeamModal'];
modals.forEach(modalId => {
const modalElement = document.getElementById(modalId);
if (modalElement) {
bootstrap.Modal.getInstance(modalElement)?.hide();
removeModal(modalId);
}
});
} catch (error) {
handleApiError(error, 'deleting team');
}
});
}