ojuhrgft
This commit is contained in:
parent
427043f334
commit
af57514549
@ -423,6 +423,22 @@ except ImportError as e:
|
||||
log.error(f"Could not import command customization endpoints: {e}")
|
||||
log.error("Command customization endpoints will not be available")
|
||||
|
||||
# Import cog management endpoints
|
||||
try:
|
||||
# Try relative import first
|
||||
try:
|
||||
from .cog_management_endpoints import router as cog_management_router
|
||||
except ImportError:
|
||||
# Fall back to absolute import
|
||||
from cog_management_endpoints import router as cog_management_router
|
||||
|
||||
# Add the cog management router to the dashboard API app
|
||||
dashboard_api_app.include_router(cog_management_router, tags=["Cog Management"])
|
||||
log.info("Cog management endpoints loaded successfully")
|
||||
except ImportError as e:
|
||||
log.error(f"Could not import cog management endpoints: {e}")
|
||||
log.error("Cog management endpoints will not be available")
|
||||
|
||||
# Mount the API apps at their respective paths
|
||||
app.mount("/api", api_app)
|
||||
app.mount("/discordapi", discordapi_app)
|
||||
|
244
api_service/cog_management_endpoints.py
Normal file
244
api_service/cog_management_endpoints.py
Normal file
@ -0,0 +1,244 @@
|
||||
"""
|
||||
Cog Management API endpoints for the bot dashboard.
|
||||
These endpoints provide functionality for managing cogs and commands.
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Optional, Any
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Body
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
# Import the dependencies from api_server.py
|
||||
try:
|
||||
# Try relative import first
|
||||
from .api_server import (
|
||||
get_dashboard_user,
|
||||
verify_dashboard_guild_admin
|
||||
)
|
||||
except ImportError:
|
||||
# Fall back to absolute import
|
||||
from api_server import (
|
||||
get_dashboard_user,
|
||||
verify_dashboard_guild_admin
|
||||
)
|
||||
|
||||
# Import settings_manager for database access
|
||||
try:
|
||||
from discordbot import settings_manager
|
||||
except ImportError:
|
||||
# Try relative import
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
|
||||
from discordbot import settings_manager
|
||||
|
||||
# Set up logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Create a router for the cog management API endpoints
|
||||
router = APIRouter(tags=["Cog Management"])
|
||||
|
||||
# --- Models ---
|
||||
class CommandInfo(BaseModel):
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
enabled: bool = True
|
||||
|
||||
class CogInfo(BaseModel):
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
enabled: bool = True
|
||||
commands: List[Dict[str, Any]] = []
|
||||
|
||||
# --- Endpoints ---
|
||||
@router.get("/guilds/{guild_id}/cogs", response_model=List[CogInfo])
|
||||
async def get_guild_cogs(
|
||||
guild_id: int,
|
||||
_user: dict = Depends(get_dashboard_user),
|
||||
_admin: bool = Depends(verify_dashboard_guild_admin)
|
||||
):
|
||||
"""Get all cogs and their commands for a guild."""
|
||||
try:
|
||||
# Check if bot instance is available via discord_bot_sync_api
|
||||
try:
|
||||
from discordbot import discord_bot_sync_api
|
||||
bot = discord_bot_sync_api.bot_instance
|
||||
if not bot:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot instance not available"
|
||||
)
|
||||
except ImportError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot sync API not available"
|
||||
)
|
||||
|
||||
# Get all cogs from the bot
|
||||
cogs_list = []
|
||||
for cog_name, cog in bot.cogs.items():
|
||||
# Get enabled status from settings_manager
|
||||
is_enabled = await settings_manager.is_cog_enabled(guild_id, cog_name, default_enabled=True)
|
||||
|
||||
# Get commands for this cog
|
||||
commands_list = []
|
||||
for command in cog.get_commands():
|
||||
# Get command enabled status
|
||||
cmd_enabled = await settings_manager.is_command_enabled(guild_id, command.qualified_name, default_enabled=True)
|
||||
commands_list.append({
|
||||
"name": command.qualified_name,
|
||||
"description": command.help or "No description available",
|
||||
"enabled": cmd_enabled
|
||||
})
|
||||
|
||||
# Add slash commands if any
|
||||
app_commands = [cmd for cmd in bot.tree.get_commands() if hasattr(cmd, 'cog') and cmd.cog and cmd.cog.qualified_name == cog_name]
|
||||
for cmd in app_commands:
|
||||
# Get command enabled status
|
||||
cmd_enabled = await settings_manager.is_command_enabled(guild_id, cmd.name, default_enabled=True)
|
||||
if not any(c["name"] == cmd.name for c in commands_list): # Avoid duplicates
|
||||
commands_list.append({
|
||||
"name": cmd.name,
|
||||
"description": cmd.description or "No description available",
|
||||
"enabled": cmd_enabled
|
||||
})
|
||||
|
||||
cogs_list.append(CogInfo(
|
||||
name=cog_name,
|
||||
description=cog.__doc__ or "No description available",
|
||||
enabled=is_enabled,
|
||||
commands=commands_list
|
||||
))
|
||||
|
||||
return cogs_list
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error getting cogs for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error getting cogs: {str(e)}"
|
||||
)
|
||||
|
||||
@router.patch("/guilds/{guild_id}/cogs/{cog_name}", status_code=status.HTTP_200_OK)
|
||||
async def update_cog_status(
|
||||
guild_id: int,
|
||||
cog_name: str,
|
||||
enabled: bool = Body(..., embed=True),
|
||||
_user: dict = Depends(get_dashboard_user),
|
||||
_admin: bool = Depends(verify_dashboard_guild_admin)
|
||||
):
|
||||
"""Enable or disable a cog for a guild."""
|
||||
try:
|
||||
# Check if settings_manager is available
|
||||
if not settings_manager or not settings_manager.pg_pool:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Settings manager not available"
|
||||
)
|
||||
|
||||
# Check if the cog exists
|
||||
try:
|
||||
from discordbot import discord_bot_sync_api
|
||||
bot = discord_bot_sync_api.bot_instance
|
||||
if not bot:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot instance not available"
|
||||
)
|
||||
|
||||
if cog_name not in bot.cogs:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Cog '{cog_name}' not found"
|
||||
)
|
||||
|
||||
# Check if it's a core cog
|
||||
if cog_name in bot.core_cogs:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Core cog '{cog_name}' cannot be disabled"
|
||||
)
|
||||
except ImportError:
|
||||
# If we can't import the bot, we'll just assume the cog exists
|
||||
log.warning("Bot sync API not available, skipping cog existence check")
|
||||
|
||||
# Update the cog enabled status
|
||||
success = await settings_manager.set_cog_enabled(guild_id, cog_name, enabled)
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to update cog '{cog_name}' status"
|
||||
)
|
||||
|
||||
return {"message": f"Cog '{cog_name}' {'enabled' if enabled else 'disabled'} successfully"}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error updating cog status for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error updating cog status: {str(e)}"
|
||||
)
|
||||
|
||||
@router.patch("/guilds/{guild_id}/commands/{command_name}", status_code=status.HTTP_200_OK)
|
||||
async def update_command_status(
|
||||
guild_id: int,
|
||||
command_name: str,
|
||||
enabled: bool = Body(..., embed=True),
|
||||
_user: dict = Depends(get_dashboard_user),
|
||||
_admin: bool = Depends(verify_dashboard_guild_admin)
|
||||
):
|
||||
"""Enable or disable a command for a guild."""
|
||||
try:
|
||||
# Check if settings_manager is available
|
||||
if not settings_manager or not settings_manager.pg_pool:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Settings manager not available"
|
||||
)
|
||||
|
||||
# Check if the command exists
|
||||
try:
|
||||
from discordbot import discord_bot_sync_api
|
||||
bot = discord_bot_sync_api.bot_instance
|
||||
if not bot:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot instance not available"
|
||||
)
|
||||
|
||||
# Check if it's a prefix command
|
||||
command = bot.get_command(command_name)
|
||||
if not command:
|
||||
# Check if it's an app command
|
||||
app_commands = [cmd for cmd in bot.tree.get_commands() if cmd.name == command_name]
|
||||
if not app_commands:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Command '{command_name}' not found"
|
||||
)
|
||||
except ImportError:
|
||||
# If we can't import the bot, we'll just assume the command exists
|
||||
log.warning("Bot sync API not available, skipping command existence check")
|
||||
|
||||
# Update the command enabled status
|
||||
success = await settings_manager.set_command_enabled(guild_id, command_name, enabled)
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to update command '{command_name}' status"
|
||||
)
|
||||
|
||||
return {"message": f"Command '{command_name}' {'enabled' if enabled else 'disabled'} successfully"}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error updating command status for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error updating command status: {str(e)}"
|
||||
)
|
@ -99,11 +99,7 @@ class GlobalSettings(BaseModel):
|
||||
max_tokens: Optional[int] = None
|
||||
theme: Optional[ThemeSettings] = None
|
||||
|
||||
class CogInfo(BaseModel):
|
||||
name: str
|
||||
description: Optional[str] = None
|
||||
enabled: bool = True
|
||||
commands: List[Dict[str, Any]] = []
|
||||
# CogInfo model moved to cog_management_endpoints.py
|
||||
|
||||
class CommandInfo(BaseModel):
|
||||
name: str
|
||||
@ -826,198 +822,7 @@ async def update_global_settings(
|
||||
)
|
||||
|
||||
# --- Cog and Command Management Endpoints ---
|
||||
|
||||
@router.get("/guilds/{guild_id}/cogs", response_model=List[CogInfo])
|
||||
async def get_guild_cogs(
|
||||
guild_id: int,
|
||||
_user: dict = Depends(get_dashboard_user),
|
||||
_admin: bool = Depends(verify_dashboard_guild_admin)
|
||||
):
|
||||
"""Get all cogs and their commands for a guild."""
|
||||
try:
|
||||
# Check if bot instance is available via discord_bot_sync_api
|
||||
try:
|
||||
from discordbot import discord_bot_sync_api
|
||||
bot = discord_bot_sync_api.bot_instance
|
||||
if not bot:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot instance not available"
|
||||
)
|
||||
except ImportError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot sync API not available"
|
||||
)
|
||||
|
||||
# Get all cogs from the bot
|
||||
cogs_list = []
|
||||
for cog_name, cog in bot.cogs.items():
|
||||
# Get enabled status from settings_manager
|
||||
is_enabled = await settings_manager.is_cog_enabled(guild_id, cog_name, default_enabled=True)
|
||||
|
||||
# Get commands for this cog
|
||||
commands_list = []
|
||||
for command in cog.get_commands():
|
||||
# Get command enabled status
|
||||
cmd_enabled = await settings_manager.is_command_enabled(guild_id, command.qualified_name, default_enabled=True)
|
||||
commands_list.append({
|
||||
"name": command.qualified_name,
|
||||
"description": command.help or "No description available",
|
||||
"enabled": cmd_enabled
|
||||
})
|
||||
|
||||
# Add slash commands if any
|
||||
app_commands = [cmd for cmd in bot.tree.get_commands() if hasattr(cmd, 'cog') and cmd.cog and cmd.cog.qualified_name == cog_name]
|
||||
for cmd in app_commands:
|
||||
# Get command enabled status
|
||||
cmd_enabled = await settings_manager.is_command_enabled(guild_id, cmd.name, default_enabled=True)
|
||||
if not any(c["name"] == cmd.name for c in commands_list): # Avoid duplicates
|
||||
commands_list.append({
|
||||
"name": cmd.name,
|
||||
"description": cmd.description or "No description available",
|
||||
"enabled": cmd_enabled
|
||||
})
|
||||
|
||||
cogs_list.append(CogInfo(
|
||||
name=cog_name,
|
||||
description=cog.__doc__ or "No description available",
|
||||
enabled=is_enabled,
|
||||
commands=commands_list
|
||||
))
|
||||
|
||||
return cogs_list
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error getting cogs for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error getting cogs: {str(e)}"
|
||||
)
|
||||
|
||||
@router.patch("/guilds/{guild_id}/cogs/{cog_name}", status_code=status.HTTP_200_OK)
|
||||
async def update_cog_status(
|
||||
guild_id: int,
|
||||
cog_name: str,
|
||||
enabled: bool = Body(..., embed=True),
|
||||
_user: dict = Depends(get_dashboard_user),
|
||||
_admin: bool = Depends(verify_dashboard_guild_admin)
|
||||
):
|
||||
"""Enable or disable a cog for a guild."""
|
||||
try:
|
||||
# Check if settings_manager is available
|
||||
if not settings_manager or not settings_manager.pg_pool:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Settings manager not available"
|
||||
)
|
||||
|
||||
# Check if the cog exists
|
||||
try:
|
||||
from discordbot import discord_bot_sync_api
|
||||
bot = discord_bot_sync_api.bot_instance
|
||||
if not bot:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot instance not available"
|
||||
)
|
||||
|
||||
if cog_name not in bot.cogs:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Cog '{cog_name}' not found"
|
||||
)
|
||||
|
||||
# Check if it's a core cog
|
||||
if cog_name in bot.core_cogs:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Core cog '{cog_name}' cannot be disabled"
|
||||
)
|
||||
except ImportError:
|
||||
# If we can't import the bot, we'll just assume the cog exists
|
||||
log.warning("Bot sync API not available, skipping cog existence check")
|
||||
|
||||
# Update the cog enabled status
|
||||
success = await settings_manager.set_cog_enabled(guild_id, cog_name, enabled)
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to update cog '{cog_name}' status"
|
||||
)
|
||||
|
||||
return {"message": f"Cog '{cog_name}' {'enabled' if enabled else 'disabled'} successfully"}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error updating cog status for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error updating cog status: {str(e)}"
|
||||
)
|
||||
|
||||
@router.patch("/guilds/{guild_id}/commands/{command_name}", status_code=status.HTTP_200_OK)
|
||||
async def update_command_status(
|
||||
guild_id: int,
|
||||
command_name: str,
|
||||
enabled: bool = Body(..., embed=True),
|
||||
_user: dict = Depends(get_dashboard_user),
|
||||
_admin: bool = Depends(verify_dashboard_guild_admin)
|
||||
):
|
||||
"""Enable or disable a command for a guild."""
|
||||
try:
|
||||
# Check if settings_manager is available
|
||||
if not settings_manager or not settings_manager.pg_pool:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Settings manager not available"
|
||||
)
|
||||
|
||||
# Check if the command exists
|
||||
try:
|
||||
from discordbot import discord_bot_sync_api
|
||||
bot = discord_bot_sync_api.bot_instance
|
||||
if not bot:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
detail="Bot instance not available"
|
||||
)
|
||||
|
||||
# Check if it's a prefix command
|
||||
command = bot.get_command(command_name)
|
||||
if not command:
|
||||
# Check if it's an app command
|
||||
app_commands = [cmd for cmd in bot.tree.get_commands() if cmd.name == command_name]
|
||||
if not app_commands:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Command '{command_name}' not found"
|
||||
)
|
||||
except ImportError:
|
||||
# If we can't import the bot, we'll just assume the command exists
|
||||
log.warning("Bot sync API not available, skipping command existence check")
|
||||
|
||||
# Update the command enabled status
|
||||
success = await settings_manager.set_command_enabled(guild_id, command_name, enabled)
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Failed to update command '{command_name}' status"
|
||||
)
|
||||
|
||||
return {"message": f"Command '{command_name}' {'enabled' if enabled else 'disabled'} successfully"}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error updating command status for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error updating command status: {str(e)}"
|
||||
)
|
||||
# Note: These endpoints have been moved to cog_management_endpoints.py
|
||||
|
||||
# --- Conversations Endpoints ---
|
||||
|
||||
|
@ -30,7 +30,7 @@ function initCogManagement() {
|
||||
navCogManagement.addEventListener('click', () => {
|
||||
// Show cog management section
|
||||
showSection('cog-management');
|
||||
|
||||
|
||||
// Load guilds if not already loaded
|
||||
if (!cogManagementLoaded) {
|
||||
loadGuildsForCogManagement();
|
||||
@ -79,17 +79,17 @@ function initCogManagement() {
|
||||
*/
|
||||
function loadGuildsForCogManagement() {
|
||||
const cogGuildSelect = document.getElementById('cog-guild-select');
|
||||
|
||||
|
||||
// Show loading state
|
||||
cogGuildSelect.disabled = true;
|
||||
cogGuildSelect.innerHTML = '<option value="">Loading servers...</option>';
|
||||
|
||||
|
||||
// Fetch guilds from API
|
||||
API.get('/dashboard/api/guilds')
|
||||
.then(guilds => {
|
||||
// Clear loading state
|
||||
cogGuildSelect.innerHTML = '<option value="">--Please choose a server--</option>';
|
||||
|
||||
|
||||
// Add guilds to select
|
||||
guilds.forEach(guild => {
|
||||
const option = document.createElement('option');
|
||||
@ -97,7 +97,7 @@ function loadGuildsForCogManagement() {
|
||||
option.textContent = guild.name;
|
||||
cogGuildSelect.appendChild(option);
|
||||
});
|
||||
|
||||
|
||||
// Enable select
|
||||
cogGuildSelect.disabled = false;
|
||||
})
|
||||
@ -117,19 +117,21 @@ function loadCogsAndCommands(guildId) {
|
||||
// Show loading state
|
||||
document.getElementById('cog-management-loading').style.display = 'flex';
|
||||
document.getElementById('cog-management-content').style.display = 'none';
|
||||
|
||||
|
||||
// Fetch cogs and commands from API
|
||||
console.log(`Loading cogs and commands for guild ${guildId}...`);
|
||||
API.get(`/dashboard/api/guilds/${guildId}/cogs`)
|
||||
.then(data => {
|
||||
console.log('Cogs and commands loaded successfully:', data);
|
||||
// Store data
|
||||
cogsData = data;
|
||||
|
||||
|
||||
// Populate cogs list
|
||||
populateCogsUI(data);
|
||||
|
||||
|
||||
// Populate commands list
|
||||
populateCommandsUI(data);
|
||||
|
||||
|
||||
// Hide loading state
|
||||
document.getElementById('cog-management-loading').style.display = 'none';
|
||||
document.getElementById('cog-management-content').style.display = 'block';
|
||||
@ -148,68 +150,68 @@ function loadCogsAndCommands(guildId) {
|
||||
function populateCogsUI(cogs) {
|
||||
const cogsList = document.getElementById('cogs-list');
|
||||
const cogFilter = document.getElementById('cog-filter');
|
||||
|
||||
|
||||
// Clear previous content
|
||||
cogsList.innerHTML = '';
|
||||
|
||||
|
||||
// Clear filter options except "All Cogs"
|
||||
cogFilter.innerHTML = '<option value="all">All Cogs</option>';
|
||||
|
||||
|
||||
// Add cogs to list
|
||||
cogs.forEach(cog => {
|
||||
// Create cog card
|
||||
const cogCard = document.createElement('div');
|
||||
cogCard.className = 'cog-card p-4 border rounded';
|
||||
|
||||
|
||||
// Create cog header
|
||||
const cogHeader = document.createElement('div');
|
||||
cogHeader.className = 'cog-header flex items-center justify-between mb-2';
|
||||
|
||||
|
||||
// Create cog checkbox
|
||||
const cogCheckbox = document.createElement('div');
|
||||
cogCheckbox.className = 'cog-checkbox flex items-center';
|
||||
|
||||
|
||||
const checkbox = document.createElement('input');
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.id = `cog-${cog.name}`;
|
||||
checkbox.className = 'mr-2';
|
||||
checkbox.checked = cog.enabled;
|
||||
checkbox.dataset.cogName = cog.name;
|
||||
|
||||
|
||||
// Disable checkbox for core cogs
|
||||
if (cog.name === 'SettingsCog' || cog.name === 'HelpCog') {
|
||||
checkbox.disabled = true;
|
||||
checkbox.title = 'Core cogs cannot be disabled';
|
||||
}
|
||||
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.htmlFor = `cog-${cog.name}`;
|
||||
label.textContent = cog.name;
|
||||
label.className = 'font-medium';
|
||||
|
||||
|
||||
cogCheckbox.appendChild(checkbox);
|
||||
cogCheckbox.appendChild(label);
|
||||
|
||||
|
||||
// Create command count badge
|
||||
const commandCount = document.createElement('span');
|
||||
commandCount.className = 'command-count bg-gray-200 text-gray-800 px-2 py-1 rounded text-xs';
|
||||
commandCount.textContent = `${cog.commands.length} commands`;
|
||||
|
||||
|
||||
cogHeader.appendChild(cogCheckbox);
|
||||
cogHeader.appendChild(commandCount);
|
||||
|
||||
|
||||
// Create cog description
|
||||
const cogDescription = document.createElement('p');
|
||||
cogDescription.className = 'cog-description text-sm text-gray-600 mt-1';
|
||||
cogDescription.textContent = cog.description || 'No description available';
|
||||
|
||||
|
||||
// Add elements to cog card
|
||||
cogCard.appendChild(cogHeader);
|
||||
cogCard.appendChild(cogDescription);
|
||||
|
||||
|
||||
// Add cog card to list
|
||||
cogsList.appendChild(cogCard);
|
||||
|
||||
|
||||
// Add cog to filter options
|
||||
const option = document.createElement('option');
|
||||
option.value = cog.name;
|
||||
@ -224,13 +226,13 @@ function populateCogsUI(cogs) {
|
||||
*/
|
||||
function populateCommandsUI(cogs) {
|
||||
const commandsList = document.getElementById('commands-list');
|
||||
|
||||
|
||||
// Clear previous content
|
||||
commandsList.innerHTML = '';
|
||||
|
||||
|
||||
// Create a flat list of all commands with their cog
|
||||
commandsData = {};
|
||||
|
||||
|
||||
cogs.forEach(cog => {
|
||||
cog.commands.forEach(command => {
|
||||
// Store command data with cog name
|
||||
@ -238,10 +240,10 @@ function populateCommandsUI(cogs) {
|
||||
...command,
|
||||
cog_name: cog.name
|
||||
};
|
||||
|
||||
|
||||
// Create command card
|
||||
const commandCard = createCommandCard(command, cog.name);
|
||||
|
||||
|
||||
// Add command card to list
|
||||
commandsList.appendChild(commandCard);
|
||||
});
|
||||
@ -259,47 +261,47 @@ function createCommandCard(command, cogName) {
|
||||
const commandCard = document.createElement('div');
|
||||
commandCard.className = 'command-card p-4 border rounded';
|
||||
commandCard.dataset.cogName = cogName;
|
||||
|
||||
|
||||
// Create command header
|
||||
const commandHeader = document.createElement('div');
|
||||
commandHeader.className = 'command-header flex items-center justify-between mb-2';
|
||||
|
||||
|
||||
// Create command checkbox
|
||||
const commandCheckbox = document.createElement('div');
|
||||
commandCheckbox.className = 'command-checkbox flex items-center';
|
||||
|
||||
|
||||
const checkbox = document.createElement('input');
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.id = `command-${command.name}`;
|
||||
checkbox.className = 'mr-2';
|
||||
checkbox.checked = command.enabled;
|
||||
checkbox.dataset.commandName = command.name;
|
||||
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.htmlFor = `command-${command.name}`;
|
||||
label.textContent = command.name;
|
||||
label.className = 'font-medium';
|
||||
|
||||
|
||||
commandCheckbox.appendChild(checkbox);
|
||||
commandCheckbox.appendChild(label);
|
||||
|
||||
|
||||
// Create cog badge
|
||||
const cogBadge = document.createElement('span');
|
||||
cogBadge.className = 'cog-badge bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs';
|
||||
cogBadge.textContent = cogName;
|
||||
|
||||
|
||||
commandHeader.appendChild(commandCheckbox);
|
||||
commandHeader.appendChild(cogBadge);
|
||||
|
||||
|
||||
// Create command description
|
||||
const commandDescription = document.createElement('p');
|
||||
commandDescription.className = 'command-description text-sm text-gray-600 mt-1';
|
||||
commandDescription.textContent = command.description || 'No description available';
|
||||
|
||||
|
||||
// Add elements to command card
|
||||
commandCard.appendChild(commandHeader);
|
||||
commandCard.appendChild(commandDescription);
|
||||
|
||||
|
||||
return commandCard;
|
||||
}
|
||||
|
||||
@ -309,7 +311,7 @@ function createCommandCard(command, cogName) {
|
||||
*/
|
||||
function filterCommands(cogName) {
|
||||
const commandCards = document.querySelectorAll('.command-card');
|
||||
|
||||
|
||||
commandCards.forEach(card => {
|
||||
if (cogName === 'all' || card.dataset.cogName === cogName) {
|
||||
card.style.display = 'block';
|
||||
@ -324,22 +326,22 @@ function filterCommands(cogName) {
|
||||
*/
|
||||
function saveCogsSettings() {
|
||||
if (!selectedGuildId) return;
|
||||
|
||||
|
||||
// Show loading state
|
||||
const saveButton = document.getElementById('save-cogs-button');
|
||||
saveButton.disabled = true;
|
||||
saveButton.textContent = 'Saving...';
|
||||
|
||||
|
||||
// Get cog settings
|
||||
const cogsPayload = {};
|
||||
const cogCheckboxes = document.querySelectorAll('#cogs-list input[type="checkbox"]');
|
||||
|
||||
|
||||
cogCheckboxes.forEach(checkbox => {
|
||||
if (!checkbox.disabled) {
|
||||
cogsPayload[checkbox.dataset.cogName] = checkbox.checked;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${selectedGuildId}/settings`, {
|
||||
cogs: cogsPayload
|
||||
@ -348,30 +350,30 @@ function saveCogsSettings() {
|
||||
// Reset button state
|
||||
saveButton.disabled = false;
|
||||
saveButton.textContent = 'Save Cog Settings';
|
||||
|
||||
|
||||
// Show success message
|
||||
document.getElementById('cogs-feedback').textContent = 'Cog settings saved successfully!';
|
||||
document.getElementById('cogs-feedback').className = 'mt-2 text-green-600';
|
||||
|
||||
|
||||
// Clear message after 3 seconds
|
||||
setTimeout(() => {
|
||||
document.getElementById('cogs-feedback').textContent = '';
|
||||
document.getElementById('cogs-feedback').className = 'mt-2';
|
||||
}, 3000);
|
||||
|
||||
|
||||
Toast.success('Cog settings saved successfully!');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error saving cog settings:', error);
|
||||
|
||||
|
||||
// Reset button state
|
||||
saveButton.disabled = false;
|
||||
saveButton.textContent = 'Save Cog Settings';
|
||||
|
||||
|
||||
// Show error message
|
||||
document.getElementById('cogs-feedback').textContent = 'Error saving cog settings. Please try again.';
|
||||
document.getElementById('cogs-feedback').className = 'mt-2 text-red-600';
|
||||
|
||||
|
||||
Toast.error('Failed to save cog settings. Please try again.');
|
||||
});
|
||||
}
|
||||
@ -381,20 +383,20 @@ function saveCogsSettings() {
|
||||
*/
|
||||
function saveCommandsSettings() {
|
||||
if (!selectedGuildId) return;
|
||||
|
||||
|
||||
// Show loading state
|
||||
const saveButton = document.getElementById('save-commands-button');
|
||||
saveButton.disabled = true;
|
||||
saveButton.textContent = 'Saving...';
|
||||
|
||||
|
||||
// Get command settings
|
||||
const commandsPayload = {};
|
||||
const commandCheckboxes = document.querySelectorAll('#commands-list input[type="checkbox"]');
|
||||
|
||||
|
||||
commandCheckboxes.forEach(checkbox => {
|
||||
commandsPayload[checkbox.dataset.commandName] = checkbox.checked;
|
||||
});
|
||||
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${selectedGuildId}/settings`, {
|
||||
commands: commandsPayload
|
||||
@ -403,30 +405,30 @@ function saveCommandsSettings() {
|
||||
// Reset button state
|
||||
saveButton.disabled = false;
|
||||
saveButton.textContent = 'Save Command Settings';
|
||||
|
||||
|
||||
// Show success message
|
||||
document.getElementById('commands-feedback').textContent = 'Command settings saved successfully!';
|
||||
document.getElementById('commands-feedback').className = 'mt-2 text-green-600';
|
||||
|
||||
|
||||
// Clear message after 3 seconds
|
||||
setTimeout(() => {
|
||||
document.getElementById('commands-feedback').textContent = '';
|
||||
document.getElementById('commands-feedback').className = 'mt-2';
|
||||
}, 3000);
|
||||
|
||||
|
||||
Toast.success('Command settings saved successfully!');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error saving command settings:', error);
|
||||
|
||||
|
||||
// Reset button state
|
||||
saveButton.disabled = false;
|
||||
saveButton.textContent = 'Save Command Settings';
|
||||
|
||||
|
||||
// Show error message
|
||||
document.getElementById('commands-feedback').textContent = 'Error saving command settings. Please try again.';
|
||||
document.getElementById('commands-feedback').className = 'mt-2 text-red-600';
|
||||
|
||||
|
||||
Toast.error('Failed to save command settings. Please try again.');
|
||||
});
|
||||
}
|
||||
@ -438,28 +440,28 @@ function saveCommandsSettings() {
|
||||
function showSection(sectionId) {
|
||||
// Get all sections
|
||||
const sections = document.querySelectorAll('.dashboard-section');
|
||||
|
||||
|
||||
// Hide all sections
|
||||
sections.forEach(section => {
|
||||
section.style.display = 'none';
|
||||
});
|
||||
|
||||
|
||||
// Get all nav buttons
|
||||
const navButtons = document.querySelectorAll('.nav-button');
|
||||
|
||||
|
||||
// Remove active class from all nav buttons
|
||||
navButtons.forEach(button => {
|
||||
button.classList.remove('active');
|
||||
});
|
||||
|
||||
|
||||
// Show the selected section and activate the corresponding nav button
|
||||
const selectedSection = document.getElementById(`${sectionId}-section`);
|
||||
const selectedNavButton = document.getElementById(`nav-${sectionId}`);
|
||||
|
||||
|
||||
if (selectedSection) {
|
||||
selectedSection.style.display = 'block';
|
||||
}
|
||||
|
||||
|
||||
if (selectedNavButton) {
|
||||
selectedNavButton.classList.add('active');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user