feat(ticket): add claim, add member, persistent management view
All checks were successful
ci / ci (push) Successful in 47s
All checks were successful
ci / ci (push) Successful in 47s
- ClaimButton: staff claim/unclaim with log - AddMemberButton: UserSelect to add member to ticket channel - TicketManagementView: persistent LayoutView with all 3 buttons - claimed_by field in TicketData - Buttons registered as persistent views for bot restart survival
This commit is contained in:
parent
80daeae55c
commit
4d1e265848
3 changed files with 135 additions and 2 deletions
|
|
@ -8,7 +8,7 @@ from discord.ext import commands
|
||||||
|
|
||||||
from tickets import storage
|
from tickets import storage
|
||||||
from tickets.data import TicketCategory
|
from tickets.data import TicketCategory
|
||||||
from tickets.ui import PanelCreateButton
|
from tickets.ui import AddMemberButton, ClaimButton, CloseButton, PanelCreateButton
|
||||||
|
|
||||||
logger = logging.getLogger("vision")
|
logger = logging.getLogger("vision")
|
||||||
|
|
||||||
|
|
@ -130,12 +130,21 @@ class ConfigSetLogButton(discord.ui.Button):
|
||||||
await interaction.response.send_message("Selectionnez le canal de logs :", view=view, ephemeral=True)
|
await interaction.response.send_message("Selectionnez le canal de logs :", view=view, ephemeral=True)
|
||||||
|
|
||||||
|
|
||||||
|
class TicketManagementView(discord.ui.LayoutView):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(timeout=None)
|
||||||
|
container = discord.ui.Container()
|
||||||
|
container.add_item(discord.ui.ActionRow(ClaimButton(), AddMemberButton(), CloseButton()))
|
||||||
|
self.add_item(container)
|
||||||
|
|
||||||
|
|
||||||
class TicketSystem(commands.Cog):
|
class TicketSystem(commands.Cog):
|
||||||
ticket = app_commands.Group(name="ticket", description="Systeme de tickets")
|
ticket = app_commands.Group(name="ticket", description="Systeme de tickets")
|
||||||
|
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.bot.add_view(PanelView())
|
self.bot.add_view(PanelView())
|
||||||
|
self.bot.add_view(TicketManagementView())
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_ready(self):
|
async def on_ready(self):
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ class TicketData:
|
||||||
created_at: str = ""
|
created_at: str = ""
|
||||||
closed_at: str | None = None
|
closed_at: str | None = None
|
||||||
closed_by: int | None = None
|
closed_by: int | None = None
|
||||||
|
claimed_by: int | None = None
|
||||||
messages: list[TicketMessage] = field(default_factory=list)
|
messages: list[TicketMessage] = field(default_factory=list)
|
||||||
reason: str = ""
|
reason: str = ""
|
||||||
|
|
||||||
|
|
@ -66,6 +67,7 @@ class TicketData:
|
||||||
"created_at": self.created_at,
|
"created_at": self.created_at,
|
||||||
"closed_at": self.closed_at,
|
"closed_at": self.closed_at,
|
||||||
"closed_by": self.closed_by,
|
"closed_by": self.closed_by,
|
||||||
|
"claimed_by": self.claimed_by,
|
||||||
"messages": [
|
"messages": [
|
||||||
{
|
{
|
||||||
"author_id": m.author_id,
|
"author_id": m.author_id,
|
||||||
|
|
|
||||||
124
tickets/ui.py
124
tickets/ui.py
|
|
@ -185,7 +185,13 @@ class TicketModal(discord.ui.Modal, title="Nouveau Ticket"):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
container.add_item(discord.ui.Separator())
|
container.add_item(discord.ui.Separator())
|
||||||
container.add_item(discord.ui.ActionRow(CloseButton()))
|
container.add_item(
|
||||||
|
discord.ui.ActionRow(
|
||||||
|
ClaimButton(),
|
||||||
|
AddMemberButton(),
|
||||||
|
CloseButton(),
|
||||||
|
)
|
||||||
|
)
|
||||||
view = discord.ui.LayoutView()
|
view = discord.ui.LayoutView()
|
||||||
view.add_item(container)
|
view.add_item(container)
|
||||||
|
|
||||||
|
|
@ -208,6 +214,122 @@ class TicketModal(discord.ui.Modal, title="Nouveau Ticket"):
|
||||||
await _send_log(guild, config, embed)
|
await _send_log(guild, config, embed)
|
||||||
|
|
||||||
|
|
||||||
|
class ClaimButton(discord.ui.Button):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(
|
||||||
|
label="Claim",
|
||||||
|
style=discord.ButtonStyle.success,
|
||||||
|
custom_id="ticket_claim",
|
||||||
|
emoji="Claim",
|
||||||
|
)
|
||||||
|
|
||||||
|
async def callback(self, interaction: discord.Interaction):
|
||||||
|
config = storage.get_config(interaction.guild_id)
|
||||||
|
ticket = storage.get_ticket(interaction.channel.id)
|
||||||
|
if not ticket:
|
||||||
|
await interaction.response.send_message("Ce n'est pas un ticket.", ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
member = interaction.guild.get_member(interaction.user.id)
|
||||||
|
if not member or not _is_staff(member, config):
|
||||||
|
await interaction.response.send_message("Seul le staff peut claim un ticket.", ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
if ticket.claimed_by:
|
||||||
|
if ticket.claimed_by == interaction.user.id:
|
||||||
|
ticket.claimed_by = None
|
||||||
|
storage.save_ticket(ticket)
|
||||||
|
await interaction.response.send_message(
|
||||||
|
f"{interaction.user.mention} a retire son claim.", ephemeral=True
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await interaction.response.send_message(
|
||||||
|
f"Ce ticket est deja claim par <@{ticket.claimed_by}>.", ephemeral=True
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
ticket.claimed_by = interaction.user.id
|
||||||
|
storage.save_ticket(ticket)
|
||||||
|
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="Ticket claim",
|
||||||
|
description=f"Claim par {interaction.user.mention}",
|
||||||
|
color=discord.Color.green(),
|
||||||
|
timestamp=datetime.now(timezone.utc),
|
||||||
|
)
|
||||||
|
await _send_log(interaction.guild, config, embed)
|
||||||
|
|
||||||
|
container = discord.ui.Container()
|
||||||
|
container.add_item(discord.ui.TextDisplay(f"## Ticket claim\nClaim par {interaction.user.mention}"))
|
||||||
|
view = discord.ui.LayoutView()
|
||||||
|
view.add_item(container)
|
||||||
|
await interaction.response.send_message(view=view)
|
||||||
|
|
||||||
|
|
||||||
|
class AddMemberButton(discord.ui.Button):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(
|
||||||
|
label="Ajouter un membre",
|
||||||
|
style=discord.ButtonStyle.secondary,
|
||||||
|
custom_id="ticket_add_member",
|
||||||
|
emoji="Ajouter",
|
||||||
|
)
|
||||||
|
|
||||||
|
async def callback(self, interaction: discord.Interaction):
|
||||||
|
config = storage.get_config(interaction.guild_id)
|
||||||
|
ticket = storage.get_ticket(interaction.channel.id)
|
||||||
|
if not ticket:
|
||||||
|
await interaction.response.send_message("Ce n'est pas un ticket.", ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
member = interaction.guild.get_member(interaction.user.id)
|
||||||
|
if not member or not _is_staff(member, config):
|
||||||
|
await interaction.response.send_message("Seul le staff peut ajouter des membres.", ephemeral=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
await interaction.response.send_message(
|
||||||
|
"Selectionnez le membre a ajouter :",
|
||||||
|
view=AddMemberSelectView(),
|
||||||
|
ephemeral=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AddMemberSelect(discord.ui.UserSelect):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(
|
||||||
|
placeholder="Selectionnez un membre...",
|
||||||
|
custom_id="ticket_add_member_select",
|
||||||
|
min_values=1,
|
||||||
|
max_values=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def callback(self, interaction: discord.Interaction):
|
||||||
|
user = self.values[0]
|
||||||
|
await interaction.channel.set_permissions(
|
||||||
|
user,
|
||||||
|
view_channel=True,
|
||||||
|
send_messages=True,
|
||||||
|
read_message_history=True,
|
||||||
|
)
|
||||||
|
await interaction.response.edit_message(
|
||||||
|
content=f"{user.mention} a ete ajoute au ticket.",
|
||||||
|
view=None,
|
||||||
|
)
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="Membre ajoute",
|
||||||
|
description=f"{user.mention} a ete ajoute par {interaction.user.mention}",
|
||||||
|
color=discord.Color.blue(),
|
||||||
|
timestamp=datetime.now(timezone.utc),
|
||||||
|
)
|
||||||
|
await _send_log(interaction.guild, storage.get_config(interaction.guild_id), embed)
|
||||||
|
|
||||||
|
|
||||||
|
class AddMemberSelectView(discord.ui.View):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(timeout=300)
|
||||||
|
self.add_item(AddMemberSelect())
|
||||||
|
|
||||||
|
|
||||||
class CloseButton(discord.ui.Button):
|
class CloseButton(discord.ui.Button):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue