zappyzep/presetup-configurator/src/LogChannels.tsx
2021-09-11 19:06:51 +03:00

193 lines
6.3 KiB
TypeScript

import React, { SetStateAction, useState } from "react";
import "./LogChannels.css";
const LOG_TYPES = {
MEMBER_WARN: "Member warned",
MEMBER_MUTE: "Member muted",
MEMBER_UNMUTE: "Member unmuted",
MEMBER_MUTE_EXPIRED: "Mute expired",
MEMBER_KICK: "Member kicked",
MEMBER_BAN: "Member banned",
MEMBER_UNBAN: "Member unbanned",
MEMBER_FORCEBAN: "Member forcebanned",
MEMBER_SOFTBAN: "Member softbanned",
MEMBER_JOIN: "Member joined",
MEMBER_LEAVE: "Member left",
MEMBER_ROLE_ADD: "Member, role added",
MEMBER_ROLE_REMOVE: "Member, role removed",
MEMBER_NICK_CHANGE: "Member nickname changed",
MEMBER_USERNAME_CHANGE: "Member username changed",
MEMBER_RESTORE: "Member roles restored",
CHANNEL_CREATE: "Channel created",
CHANNEL_DELETE: "Channel deleted",
CHANNEL_UPDATE: "Channel updated",
THREAD_CREATE: "Thread created",
THREAD_DELETE: "Thread deleted",
THREAD_UPDATE: "Thread updated",
ROLE_CREATE: "Role created",
ROLE_DELETE: "Role deleted",
ROLE_UPDATE: "Role updated",
MESSAGE_EDIT: "Message edited",
MESSAGE_DELETE: "Message deleted",
MESSAGE_DELETE_BULK: "Messages deleted in bulk",
MESSAGE_DELETE_BARE: "Message deleted (bare)",
VOICE_CHANNEL_JOIN: "Voice channel join",
VOICE_CHANNEL_LEAVE: "Voice channel leave",
VOICE_CHANNEL_MOVE: "Voice channel move",
STAGE_INSTANCE_CREATE: "Stage created",
STAGE_INSTANCE_DELETE: "Stage deleted",
STAGE_INSTANCE_UPDATE: "Stage updated",
EMOJI_CREATE: "Emoji created",
EMOJI_DELETE: "Emoji deleted",
EMOJI_UPDATE: "Emoji updated",
STICKER_CREATE: "Sticker created",
STICKER_DELETE: "Sticker deleted",
STICKER_UPDATE: "Sticker updated",
COMMAND: "Command used",
MESSAGE_SPAM_DETECTED: "Message spam detected",
CENSOR: "Message censored",
CLEAN: "Messages cleaned",
CASE_CREATE: "Case created",
MASSBAN: "Massbanned",
MASSMUTE: "Massmuted",
MEMBER_TIMED_MUTE: "Member temporarily muted",
MEMBER_TIMED_UNMUTE: "Member, scheduled unmute",
MEMBER_JOIN_WITH_PRIOR_RECORDS: "Member joined with prior records",
OTHER_SPAM_DETECTED: "Non-message spam detected",
MEMBER_ROLE_CHANGES: "Member roles changed",
VOICE_CHANNEL_FORCE_MOVE: "Force-moved to a voice channel",
CASE_UPDATE: "Case updated",
MEMBER_MUTE_REJOIN: "Muted member rejoined",
SCHEDULED_MESSAGE: "Scheduled message to be posted",
POSTED_SCHEDULED_MESSAGE: "Posted scheduled message",
BOT_ALERT: "Bot alert",
AUTOMOD_ACTION: "Automod action",
SCHEDULED_REPEATED_MESSAGE: "Scheduled message to be posted repeatedly",
REPEATED_MESSAGE: "Set a message to be posted repeatedly",
MESSAGE_DELETE_AUTO: "Message deleted (auto)",
SET_ANTIRAID_USER: "Set antiraid (user)",
SET_ANTIRAID_AUTO: "Set antiraid (auto)",
MASS_ASSIGN_ROLES: "Mass-assigned roles",
MASS_UNASSIGN_ROLES: "Mass-unassigned roles",
MEMBER_NOTE: "Member noted",
CASE_DELETE: "Case deleted",
DM_FAILED: "Failed to DM member",
};
const sortedLogTypes = Object.fromEntries(
Object.entries(LOG_TYPES).sort((a, b) => {
if (a[1].toLowerCase() > b[1].toLowerCase()) return 1;
if (a[1].toLowerCase() < b[1].toLowerCase()) return -1;
if (a[0].toLowerCase() > b[0].toLowerCase()) return 1;
if (a[0].toLowerCase() < b[0].toLowerCase()) return -1;
return 0;
}),
) as typeof LOG_TYPES;
type LOG_TYPE = keyof typeof LOG_TYPES;
export interface LogChannel {
id: string;
includeExclude: "include" | "exclude";
logTypes: Set<LOG_TYPE>;
}
interface Props {
logChannels: LogChannel[];
setLogChannels: React.Dispatch<SetStateAction<LogChannel[]>>;
}
export function LogChannels({ logChannels, setLogChannels }: Props) {
function addLogChannel(props: Partial<LogChannel> = {}) {
setLogChannels((_logChannels) => {
return [
..._logChannels,
{
id: "",
includeExclude: "include",
logTypes: new Set(),
...props,
},
];
});
}
function deleteLogChannel(index) {
setLogChannels((_logChannels) => {
const newArr = [..._logChannels];
newArr.splice(index, 1);
return newArr;
});
}
function addReverseLogChannel() {
const includedLogTypesInOtherLogChannels = new Set(logChannels.map((l) => Array.from(l.logTypes)).flat());
addLogChannel({
includeExclude: "exclude",
logTypes: includedLogTypesInOtherLogChannels,
});
}
function setId(index: number, id: string) {
setLogChannels((_logChannels) => {
_logChannels[index].id = id;
return [..._logChannels];
});
}
function setIncludeExclude(index: number, includeExclude: LogChannel["includeExclude"]) {
setLogChannels((_logChannels) => {
_logChannels[index].includeExclude = includeExclude;
return [..._logChannels];
});
}
function toggleLogType(index: number, logType: LOG_TYPE, enabled: boolean) {
setLogChannels((_logChannels) => {
if (enabled) {
_logChannels[index].logTypes.add(logType);
} else {
_logChannels[index].logTypes.delete(logType);
}
return [..._logChannels];
});
}
return (
<div className="LogChannels">
{logChannels.map((logChannel, index) => (
<div className="log-channel">
<label>
ID: <input value={logChannel.id} onChange={(e) => setId(index, e.target.value)} />
</label>
<label>
Mode:
<select
value={logChannel.includeExclude}
onChange={(e) => setIncludeExclude(index, e.target.value as LogChannel["includeExclude"])}
>
<option value={"include"}>Include</option>
<option value={"exclude"}>Exclude</option>
</select>
</label>
<div className="log-types">
{Object.entries(sortedLogTypes).map(([logType, description]) => (
<label>
<input
type="checkbox"
checked={logChannel.logTypes.has(logType as LOG_TYPE)}
onChange={(e) => toggleLogType(index, logType as LOG_TYPE, e.target.checked)}
/>
{description}
</label>
))}
</div>
<button onClick={() => deleteLogChannel(index)}>Delete</button>
</div>
))}
<button onClick={() => addLogChannel()}>Add</button>
<button onClick={() => addReverseLogChannel()}>Add "everything else"</button>
</div>
);
}