Add Discord allowed mentions configuration

This commit is contained in:
2026-04-24 17:01:34 +00:00
parent 9958db10b9
commit 55db0ac642
6 changed files with 300 additions and 1 deletions
@@ -44,6 +44,23 @@ const timestampFormatter = new Intl.DateTimeFormat(undefined, {
dateStyle: 'medium',
timeStyle: 'short',
});
const discordAllowedMentionOptions: Array<{
value: string;
label: string;
}> = [
{
value: 'users',
label: 'User mentions (@username)',
},
{
value: 'roles',
label: 'Role mentions (@role)',
},
{
value: 'everyone',
label: '@everyone and @here',
},
];
const breadcrumbs: BreadcrumbItem[] = [
{
@@ -67,6 +84,41 @@ props.notificationActions.forEach((notificationAction) => {
const selectedChannel = (notificationAction: NotificationActionModel): string =>
editChannelState[notificationAction.id] ?? notificationAction.channel;
const notificationActionAllowedMentions = (
notificationAction: NotificationActionModel,
): string[] => {
const allowedMentions =
notificationAction.channel_configuration['allowed_mentions'];
if (!Array.isArray(allowedMentions)) {
return [];
}
return allowedMentions
.filter(
(allowedMention): allowedMention is string =>
typeof allowedMention === 'string',
)
.map((allowedMention) => allowedMention.trim().toLowerCase())
.filter((allowedMention) => allowedMention !== '');
};
const allowedMentionsError = (
errors: Record<string, string>,
): string | undefined => {
const generalError = errors['channel_configuration.allowed_mentions'];
if (generalError !== undefined) {
return generalError;
}
const itemErrorKey = Object.keys(errors).find((key) =>
key.startsWith('channel_configuration.allowed_mentions.'),
);
return itemErrorKey === undefined ? undefined : errors[itemErrorKey];
};
const notificationActionTimestamp = (
notificationAction: NotificationActionModel,
): string => {
@@ -249,6 +301,52 @@ const notificationActionTimestamp = (
<InputError :message="errors.delivery_url" />
</div>
<div class="grid gap-2">
<Label>Allowed mentions</Label>
<div
:class="[
'grid gap-2',
createChannelState.value !==
'discord'
? 'hidden'
: '',
]"
>
<label
v-for="allowedMentionOption in discordAllowedMentionOptions"
:key="`create-allowed-mention-${allowedMentionOption.value}`"
class="border-border flex items-center gap-2 rounded-lg border px-3 py-2"
>
<input
type="checkbox"
name="channel_configuration[allowed_mentions][]"
:value="
allowedMentionOption.value
"
:disabled="
createChannelState.value !==
'discord'
"
class="border-input text-primary focus:ring-ring size-4 rounded"
/>
<span>
{{ allowedMentionOption.label }}
</span>
</label>
</div>
<p class="text-muted-foreground text-sm">
{{
createChannelState.value ===
'discord'
? 'Pick which Discord mention types are allowed. Leave all unchecked to keep mentions fully disabled.'
: 'Allowed mentions are only used when the channel is Discord.'
}}
</p>
<InputError
:message="allowedMentionsError(errors)"
/>
</div>
<div class="grid gap-2">
<Label
for="create-notification-message-template"
@@ -529,6 +627,59 @@ const notificationActionTimestamp = (
</div>
</div>
<div class="grid gap-2">
<Label>Allowed mentions</Label>
<div
:class="[
'grid gap-2',
selectedChannel(notificationAction) !==
'discord'
? 'hidden'
: '',
]"
>
<label
v-for="allowedMentionOption in discordAllowedMentionOptions"
:key="`notification-allowed-mention-${notificationAction.id}-${allowedMentionOption.value}`"
class="border-border flex items-center gap-2 rounded-lg border px-3 py-2"
>
<input
type="checkbox"
name="channel_configuration[allowed_mentions][]"
:value="
allowedMentionOption.value
"
:default-checked="
notificationActionAllowedMentions(
notificationAction,
).includes(
allowedMentionOption.value,
)
"
:disabled="
selectedChannel(notificationAction) !==
'discord'
"
class="border-input text-primary focus:ring-ring size-4 rounded"
/>
<span>
{{ allowedMentionOption.label }}
</span>
</label>
</div>
<p class="text-muted-foreground text-sm">
{{
selectedChannel(notificationAction) ===
'discord'
? 'Pick which Discord mention types are allowed. Leave all unchecked to keep mentions fully disabled.'
: 'Allowed mentions are only used when the channel is Discord.'
}}
</p>
<InputError
:message="allowedMentionsError(errors)"
/>
</div>
<div class="grid gap-2">
<Label
:for="