Ajout de la possibilités de communiquer une information aux partenaires Omega Kube
This commit is contained in:
parent
8bcc40f217
commit
b0535af75c
3 changed files with 287 additions and 72 deletions
|
|
@ -368,7 +368,7 @@ class ReportsFilterView(disnake.ui.View):
|
|||
val = inter.values[0]
|
||||
self.selected_status = None if val == "all" else val
|
||||
self.update_components()
|
||||
await inter.response.edit_message(components=self.get_components_v2())
|
||||
await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
|
||||
status_select.callback = status_callback
|
||||
self.add_item(status_select)
|
||||
|
||||
|
|
@ -392,7 +392,7 @@ class ReportsFilterView(disnake.ui.View):
|
|||
val = inter.values[0]
|
||||
self.selected_subject = None if val == "all" else val
|
||||
self.update_components()
|
||||
await inter.response.edit_message(components=self.get_components_v2())
|
||||
await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
|
||||
subject_select.callback = subject_callback
|
||||
self.add_item(subject_select)
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ class ReportsFilterView(disnake.ui.View):
|
|||
else:
|
||||
self.selected_user = None
|
||||
self.update_components()
|
||||
await inter.response.edit_message(components=self.get_components_v2())
|
||||
await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
|
||||
user_select.callback = user_callback
|
||||
self.add_item(user_select)
|
||||
current_row += 1
|
||||
|
|
@ -439,7 +439,7 @@ class ReportsFilterView(disnake.ui.View):
|
|||
else:
|
||||
self.selected_role = None
|
||||
self.update_components()
|
||||
await inter.response.edit_message(components=self.get_components_v2())
|
||||
await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
|
||||
role_select.callback = role_callback
|
||||
self.add_item(role_select)
|
||||
current_row += 1
|
||||
|
|
@ -453,8 +453,6 @@ class ReportsFilterView(disnake.ui.View):
|
|||
row=current_row
|
||||
)
|
||||
async def search_callback(inter: disnake.MessageInteraction):
|
||||
await inter.response.defer(ephemeral=True)
|
||||
|
||||
author_filter = None
|
||||
if not self.has_global_access:
|
||||
author_filter = self.viewer_id
|
||||
|
|
@ -474,11 +472,11 @@ class ReportsFilterView(disnake.ui.View):
|
|||
)
|
||||
|
||||
if not reports:
|
||||
await inter.followup.send("❌ Aucun rapport ne correspond à votre recherche.", ephemeral=True)
|
||||
await inter.response.send_message("❌ Aucun rapport ne correspond à votre recherche.", ephemeral=True)
|
||||
return
|
||||
|
||||
browser = ReportsBrowserView(self.cog, self.interaction, reports, filter_view=self)
|
||||
await inter.edit_original_message(content=None, embed=browser.get_embed(), view=browser)
|
||||
await inter.response.edit_message(embed=browser.get_embed(), view=browser)
|
||||
|
||||
search_btn.callback = search_callback
|
||||
self.add_item(search_btn)
|
||||
|
|
@ -496,49 +494,40 @@ class ReportsFilterView(disnake.ui.View):
|
|||
self.selected_status = None
|
||||
self.selected_subject = None
|
||||
self.update_components()
|
||||
await inter.response.edit_message(components=self.get_components_v2())
|
||||
await inter.response.edit_message(embed=self.get_filter_embed(), view=self)
|
||||
reset_btn.callback = reset_callback
|
||||
self.add_item(reset_btn)
|
||||
|
||||
def get_components_v2(self):
|
||||
sections = [
|
||||
disnake.ui.Section(
|
||||
"# 🔍 Recherche & Filtres de Rapports",
|
||||
accessory=disnake.ui.Thumbnail(self.interaction.author.display_avatar.url)
|
||||
),
|
||||
disnake.ui.Separator(divider=True)
|
||||
]
|
||||
|
||||
filters_desc = []
|
||||
if self.selected_status:
|
||||
filters_desc.append(f"🚦 **Statut** : {self.selected_status}")
|
||||
else:
|
||||
filters_desc.append("🚦 **Statut** : Tous")
|
||||
|
||||
def get_filter_embed(self) -> disnake.Embed:
|
||||
"""Génère l'embed résumant les filtres actifs."""
|
||||
author = self.interaction.author
|
||||
lines = []
|
||||
lines.append(f"🚦 **Statut** : {self.selected_status or 'Tous'}")
|
||||
if self.has_global_access:
|
||||
if self.selected_user:
|
||||
mention = self.selected_user.mention if hasattr(self.selected_user, "mention") else f"<@{self.selected_user}>"
|
||||
filters_desc.append(f"👤 **Auteur** : {mention}")
|
||||
mention = self.selected_user.mention if hasattr(self.selected_user, 'mention') else f'<@{self.selected_user}>'
|
||||
lines.append(f"👤 **Auteur** : {mention}")
|
||||
else:
|
||||
filters_desc.append("👤 **Auteur** : Tous")
|
||||
|
||||
lines.append("👤 **Auteur** : Tous")
|
||||
if self.selected_role:
|
||||
mention = self.selected_role.mention if hasattr(self.selected_role, "mention") else f"<@&{self.selected_role}>"
|
||||
filters_desc.append(f"🛡️ **Rôle Auteur** : {mention}")
|
||||
mention = self.selected_role.mention if hasattr(self.selected_role, 'mention') else f'<@&{self.selected_role}>'
|
||||
lines.append(f"🛡️ **Rôle Auteur** : {mention}")
|
||||
else:
|
||||
filters_desc.append("🛡️ **Rôle Auteur** : Tous")
|
||||
lines.append("🛡️ **Rôle Auteur** : Tous")
|
||||
else:
|
||||
filters_desc.append(f"👤 **Auteur** : {self.interaction.author.mention} *(Accès restreint à vos propres rapports)*")
|
||||
|
||||
if self.selected_subject:
|
||||
filters_desc.append(f"📁 **Objet / Catégorie** : `{self.selected_subject}`")
|
||||
else:
|
||||
filters_desc.append("📁 **Objet / Catégorie** : Tous")
|
||||
|
||||
sections.append(disnake.ui.TextDisplay(content="\n".join(filters_desc)))
|
||||
sections.append(disnake.ui.Separator(divider=True))
|
||||
|
||||
return [disnake.ui.Container(*sections)] + self.children
|
||||
lines.append(f"👤 **Auteur** : {author.mention} *(accès limité à vos rapports)*")
|
||||
lines.append(f"📁 **Objet / Catégorie** : {self.selected_subject or 'Tous'}")
|
||||
embed = disnake.Embed(
|
||||
title="🔍 Recherche & Filtres de Rapports",
|
||||
description="\n".join(lines),
|
||||
color=disnake.Color.blurple()
|
||||
)
|
||||
embed.set_thumbnail(url=author.display_avatar.url)
|
||||
return embed
|
||||
|
||||
def get_components_v2(self):
|
||||
"""Kept for backward compatibility — returns view children only."""
|
||||
return self.children
|
||||
|
||||
async def interaction_check(self, interaction: disnake.MessageInteraction) -> bool:
|
||||
if interaction.author.id != self.viewer_id:
|
||||
|
|
@ -701,9 +690,14 @@ class ReportsBrowserView(disnake.ui.View):
|
|||
if not self.reports:
|
||||
if self.filter_view:
|
||||
self.filter_view.update_components()
|
||||
await inter.response.edit_message(content=None, embed=None, components=self.filter_view.get_components_v2())
|
||||
await inter.response.edit_message(
|
||||
embed=self.filter_view.get_filter_embed(), view=self.filter_view
|
||||
)
|
||||
else:
|
||||
await inter.response.edit_message(content="✅ Le rapport a été supprimé. Plus aucun rapport dans cette recherche.", embed=None, view=None)
|
||||
await inter.response.edit_message(
|
||||
content="✅ Le rapport a été supprimé. Plus aucun rapport dans cette recherche.",
|
||||
embed=None, view=None
|
||||
)
|
||||
return
|
||||
|
||||
if self.current_index >= len(self.reports):
|
||||
|
|
@ -717,10 +711,14 @@ class ReportsBrowserView(disnake.ui.View):
|
|||
async def back_callback(inter: disnake.MessageInteraction):
|
||||
if self.filter_view:
|
||||
self.filter_view.update_components()
|
||||
await inter.response.edit_message(embed=None, components=self.filter_view.get_components_v2())
|
||||
await inter.response.edit_message(
|
||||
embed=self.filter_view.get_filter_embed(), view=self.filter_view
|
||||
)
|
||||
else:
|
||||
new_filter_view = ReportsFilterView(self.cog, self.interaction)
|
||||
await inter.response.edit_message(embed=None, components=new_filter_view.get_components_v2())
|
||||
await inter.response.edit_message(
|
||||
embed=new_filter_view.get_filter_embed(), view=new_filter_view
|
||||
)
|
||||
|
||||
edit_btn.callback = edit_callback
|
||||
delete_btn.callback = delete_callback
|
||||
|
|
@ -732,9 +730,9 @@ class ReportsBrowserView(disnake.ui.View):
|
|||
# Row 3: Menu Déroulant "Changer l'état" (Admin uniquement)
|
||||
if self.is_admin:
|
||||
status_options = [
|
||||
disnake.SelectOption(label="En attente", emoji="🟡", value="En attente", default=(report['status'] == "En attente")),
|
||||
disnake.SelectOption(label="Traité", emoji="🟢", value="Traité", default=(report['status'] == "Traité")),
|
||||
disnake.SelectOption(label="Classé", emoji="🔴", value="Classé", default=(report['status'] == "Classé"))
|
||||
disnake.SelectOption(label="En attente", emoji="🟡", value="En attente"),
|
||||
disnake.SelectOption(label="Traité", emoji="🟢", value="Traité"),
|
||||
disnake.SelectOption(label="Classé", emoji="🔴", value="Classé")
|
||||
]
|
||||
status_menu = disnake.ui.StringSelect(
|
||||
placeholder="Changer le statut...",
|
||||
|
|
@ -746,16 +744,81 @@ class ReportsBrowserView(disnake.ui.View):
|
|||
async def status_callback(inter: disnake.MessageInteraction):
|
||||
if not inter.author.guild_permissions.administrator:
|
||||
return await inter.response.send_message("❌ Seuls les administrateurs peuvent modifier le statut.", ephemeral=True)
|
||||
|
||||
|
||||
old_status = report['status']
|
||||
new_status = inter.values[0]
|
||||
|
||||
if old_status == new_status:
|
||||
return await inter.response.send_message(f"ℹ️ Le rapport est déjà en statut **{new_status}**.", ephemeral=True)
|
||||
|
||||
self.cog.db.update_report_status(report['id'], new_status)
|
||||
|
||||
updated_rep = self.cog.db.get_report(report['id'])
|
||||
self.reports[self.current_index] = updated_rep
|
||||
|
||||
|
||||
self.update_components()
|
||||
await inter.response.edit_message(embed=self.get_embed(), view=self)
|
||||
await inter.followup.send(f"✅ Statut du rapport #{report['id']} mis à jour vers : **{new_status}**.", ephemeral=True)
|
||||
await inter.followup.send(
|
||||
f"✅ Statut du rapport **#{report['id']}** mis à jour : **{old_status}** → **{new_status}**.",
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
# === Notification DM à l'auteur ===
|
||||
status_colors = {
|
||||
"En attente": disnake.Color.yellow(),
|
||||
"Traité": disnake.Color.green(),
|
||||
"Classé": disnake.Color.greyple(),
|
||||
}
|
||||
status_emojis = {"En attente": "🟡", "Traité": "🟢", "Classé": "🔴"}
|
||||
dm_sent = False
|
||||
try:
|
||||
author_member = inter.guild.get_member(report['author_id'])
|
||||
if not author_member:
|
||||
author_member = await inter.guild.fetch_member(report['author_id'])
|
||||
|
||||
if author_member:
|
||||
dm_embed = disnake.Embed(
|
||||
title="📋 Mise à jour de votre rapport",
|
||||
description=(
|
||||
f"Le statut de votre rapport **#{report['id']} — {report['title']}** "
|
||||
f"vient d'être modifié."
|
||||
),
|
||||
color=status_colors.get(new_status, disnake.Color.blurple()),
|
||||
timestamp=datetime.now(PARIS_TZ)
|
||||
)
|
||||
dm_embed.add_field(
|
||||
name="Ancien statut",
|
||||
value=f"{status_emojis.get(old_status, '⚪')} {old_status}",
|
||||
inline=True
|
||||
)
|
||||
dm_embed.add_field(
|
||||
name="Nouveau statut",
|
||||
value=f"{status_emojis.get(new_status, '⚪')} {new_status}",
|
||||
inline=True
|
||||
)
|
||||
dm_embed.add_field(name="Modifié par", value=inter.author.mention, inline=False)
|
||||
dm_embed.add_field(name="Serveur", value=inter.guild.name, inline=False)
|
||||
dm_embed.set_footer(text=f"Rapport #{report['id']} • {inter.guild.name}")
|
||||
if inter.guild.icon:
|
||||
dm_embed.set_thumbnail(url=inter.guild.icon.url)
|
||||
try:
|
||||
await author_member.send(embed=dm_embed)
|
||||
dm_sent = True
|
||||
except disnake.Forbidden:
|
||||
kuby_logger.info(
|
||||
f"[Rapports] DM impossible pour {author_member} (DMs fermés) — rapport #{report['id']}"
|
||||
)
|
||||
except Exception as e:
|
||||
kuby_logger.error(f"[Rapports] Erreur DM notification: {e}", exc_info=True)
|
||||
except disnake.NotFound:
|
||||
pass
|
||||
except Exception as e:
|
||||
kuby_logger.error(f"[Rapports] Erreur récupération membre pour DM: {e}", exc_info=True)
|
||||
|
||||
dm_note = " • 📬 Auteur notifié par DM." if dm_sent else " • ⚠️ DM non envoyé (DMs fermés ou membre introuvable)."
|
||||
await inter.followup.send(
|
||||
f"ℹ️{dm_note}",
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
status_menu.callback = status_callback
|
||||
self.add_item(status_menu)
|
||||
|
|
@ -898,7 +961,20 @@ class Rapports(commands.Cog):
|
|||
filter_view.selected_role = role
|
||||
|
||||
filter_view.update_components()
|
||||
await interaction.response.send_message(components=filter_view.get_components_v2(), ephemeral=True)
|
||||
await interaction.response.send_message(
|
||||
embed=disnake.Embed(
|
||||
title="🔍 Recherche & Filtres de Rapports",
|
||||
description=(
|
||||
f"🚦 **Statut** : {filter_view.selected_status or 'Tous'}\n"
|
||||
f"📁 **Objet / Catégorie** : {filter_view.selected_subject or 'Tous'}\n"
|
||||
+ (f"👤 **Auteur** : {filter_view.selected_user.mention if hasattr(filter_view.selected_user, 'mention') else 'Tous'}\n" if filter_view.has_global_access else f"👤 **Auteur** : {interaction.author.mention} *(accès limité à vos rapports)*\n")
|
||||
+ (f"🛡️ **Rôle Auteur** : {filter_view.selected_role.mention if hasattr(filter_view.selected_role, 'mention') else 'Tous'}" if filter_view.has_global_access else "")
|
||||
),
|
||||
color=disnake.Color.blurple()
|
||||
),
|
||||
view=filter_view,
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Rapports(bot))
|
||||
|
|
|
|||
|
|
@ -1,24 +1,166 @@
|
|||
import disnake
|
||||
from disnake.ext import commands
|
||||
|
||||
|
||||
OWNER_ID = 971446412690722826
|
||||
|
||||
|
||||
def is_authorized(interaction: disnake.ApplicationCommandInteraction) -> bool:
|
||||
return interaction.user.id == OWNER_ID
|
||||
|
||||
|
||||
class AnnouncementModal(disnake.ui.Modal):
|
||||
def __init__(self, cog: "SentBotMessages"):
|
||||
self.cog = cog
|
||||
components = [
|
||||
disnake.ui.TextInput(
|
||||
label="Titre principal de l'annonce",
|
||||
placeholder="Ex: Mise à jour important / Maintenance / Nouveau système",
|
||||
custom_id="announcement_title",
|
||||
required=True,
|
||||
max_length=100,
|
||||
),
|
||||
disnake.ui.TextInput(
|
||||
label="Message de l'annonce (contenu réel)",
|
||||
style=disnake.TextInputStyle.paragraph,
|
||||
placeholder="Écris le vrai contenu de l'annonce ici.",
|
||||
custom_id="announcement_message",
|
||||
required=True,
|
||||
max_length=4000,
|
||||
),
|
||||
disnake.ui.TextInput(
|
||||
label="Message de prévention / contexte MP",
|
||||
style=disnake.TextInputStyle.paragraph,
|
||||
placeholder="Ex: Ce MP vous informe d'une annonce importante.",
|
||||
custom_id="announcement_prevention",
|
||||
required=True,
|
||||
max_length=1000,
|
||||
),
|
||||
]
|
||||
super().__init__(
|
||||
title="Annonce aux propriétaires",
|
||||
custom_id="announcement_modal",
|
||||
components=components,
|
||||
)
|
||||
|
||||
async def callback(self, interaction: disnake.ModalInteraction):
|
||||
title = (interaction.text_values.get("announcement_title") or "").strip()
|
||||
message = (interaction.text_values.get("announcement_message") or "").strip()
|
||||
prevention = (interaction.text_values.get("announcement_prevention") or "").strip()
|
||||
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
|
||||
preview_container = disnake.ui.Container(
|
||||
disnake.ui.TextDisplay(content=f"# {title}"),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(content=prevention),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(content=message),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(
|
||||
content=(
|
||||
"📍 **Prévisualisation**\n"
|
||||
"Le même format sera envoyé aux propriétaires."
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
successful = 0
|
||||
failed_servers = []
|
||||
|
||||
for guild in self.cog.bot.guilds:
|
||||
try:
|
||||
owner = guild.owner
|
||||
if owner is None:
|
||||
owner = await guild.fetch_member(guild.owner_id)
|
||||
|
||||
container = disnake.ui.Container(
|
||||
disnake.ui.TextDisplay(content=f"# {title}"),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(content=prevention),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(content=message),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(
|
||||
content=(
|
||||
f"📍 **Serveur** : {guild.name}\n"
|
||||
f"🆔 **ID** : `{guild.id}`"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
await owner.send(components=[container])
|
||||
successful += 1
|
||||
except Exception as e:
|
||||
failed_servers.append(f"{guild.name} ({guild.id}) : {e}")
|
||||
|
||||
result_text = (
|
||||
f"✅ Annonce envoyée à {successful} propriétaire(s)."
|
||||
if not failed_servers
|
||||
else (
|
||||
f"✅ Annonce envoyée à {successful} propriétaire(s).\n"
|
||||
f"❌ Échecs ({len(failed_servers)}):\n"
|
||||
f"- {'\n- '.join(failed_servers[:10])}"
|
||||
f"{'\n... et ' + str(len(failed_servers) - 10) + ' autres' if len(failed_servers) > 10 else ''}"
|
||||
)
|
||||
)
|
||||
|
||||
result_container = disnake.ui.Container(
|
||||
disnake.ui.TextDisplay(content=result_text),
|
||||
disnake.ui.Separator(divider=True),
|
||||
disnake.ui.TextDisplay(content="🧩 Aperçu du format envoyé aux propriétaires :"),
|
||||
disnake.ui.Separator(divider=True),
|
||||
*preview_container.children
|
||||
)
|
||||
|
||||
await interaction.edit_original_response(components=[result_container])
|
||||
|
||||
|
||||
class SentBotMessages(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.slash_command(name="sentbotmessages", description="Le bot envoie un message dans un salon choisi.")
|
||||
async def sentbotmessages(self, interaction: disnake.ApplicationCommandInteraction,
|
||||
message: str = commands.Param(description="Le message à envoyer"),
|
||||
salon: disnake.TextChannel = commands.Param(description="Le salon où envoyer le message")):
|
||||
@commands.slash_command(
|
||||
name="sentbotmessages",
|
||||
description="Le bot envoie un message dans un salon choisi."
|
||||
)
|
||||
async def sentbotmessages(
|
||||
self,
|
||||
interaction: disnake.ApplicationCommandInteraction,
|
||||
message: str = commands.Param(description="Le message à envoyer"),
|
||||
salon: disnake.TextChannel = commands.Param(description="Le salon où envoyer le message")
|
||||
):
|
||||
# Vérifie si l'utilisateur est admin
|
||||
if not interaction.user.guild_permissions.administrator:
|
||||
await interaction.response.send_message("⛔ Tu n'as pas la permission d'utiliser cette commande.", ephemeral=True)
|
||||
await interaction.response.send_message(
|
||||
"⛔ Tu n'as pas la permission d'utiliser cette commande.",
|
||||
ephemeral=True
|
||||
)
|
||||
return
|
||||
|
||||
try:
|
||||
await salon.send(message)
|
||||
await interaction.response.send_message(f"✅ Message envoyé dans {salon.mention}.", ephemeral=True)
|
||||
await interaction.response.send_message(
|
||||
f"✅ Message envoyé dans {salon.mention}.",
|
||||
ephemeral=True
|
||||
)
|
||||
except Exception as e:
|
||||
await interaction.response.send_message(f"❌ Une erreur est survenue : {e}", ephemeral=True)
|
||||
await interaction.response.send_message(
|
||||
f"❌ Une erreur est survenue : {e}",
|
||||
ephemeral=True
|
||||
)
|
||||
|
||||
@commands.slash_command(
|
||||
name="annonce_proprietaires",
|
||||
description="Ouvrir le formulaire d'annonce pour les propriétaires."
|
||||
)
|
||||
@commands.check(is_authorized)
|
||||
async def annonce_proprietaires(
|
||||
self,
|
||||
interaction: disnake.ApplicationCommandInteraction,
|
||||
):
|
||||
await interaction.response.send_modal(AnnouncementModal(self))
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(SentBotMessages(bot))
|
||||
|
|
|
|||
|
|
@ -3158,13 +3158,11 @@ class TicketCommands(commands.Cog):
|
|||
if not custom_id:
|
||||
return
|
||||
|
||||
# Accept both ticket_* / catv2_* / close_* custom_ids
|
||||
|
||||
|
||||
# Accept only ticket_* / catv2_* / cat_* / close_* custom_ids
|
||||
# reports_filter_* are intentionally excluded — handled by ReportsFilterView callbacks
|
||||
if not (str(custom_id).startswith("ticket_")
|
||||
or str(custom_id).startswith("catv2_")
|
||||
or str(custom_id).startswith("cat_")
|
||||
or str(custom_id).startswith("reports_filter_")
|
||||
or str(custom_id) in {"close_confirm", "close_cancel", "delay_cancel"}):
|
||||
return
|
||||
|
||||
|
|
@ -3222,6 +3220,7 @@ class TicketCommands(commands.Cog):
|
|||
await inter.response.send_message(f"Erreur interne: {e}", ephemeral=True)
|
||||
|
||||
# backward compatibility (legacy cat_<id>_<suffix>)
|
||||
|
||||
elif custom_id.startswith("cat_"):
|
||||
try:
|
||||
parts = str(custom_id).split("_")
|
||||
|
|
@ -3402,13 +3401,11 @@ class TicketCommands(commands.Cog):
|
|||
await self._send_recruitment_decision(inter, ticket, category, accepted=False)
|
||||
|
||||
# === Fermeture via composants V2 (sans view=, donc custom_id) ===
|
||||
elif custom_id == "close_cancel":
|
||||
await inter.response.defer()
|
||||
# Retire la réponse éphémère du user (si c'est bien une réponse d'interaction)
|
||||
try:
|
||||
await inter.delete_original_response()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
elif custom_id.startswith("reports_filter_"):
|
||||
# No direct response; let the view's callback handle the interaction
|
||||
return
|
||||
|
||||
|
||||
elif custom_id == "close_confirm":
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue