From: Daniel Karbach Date: Fri, 11 Jul 2025 09:12:14 +0000 (+0200) Subject: show details in discord command log X-Git-Url: http://git.localhorst.tv/?a=commitdiff_plain;h=a23880ad3d97d5a5c7d7471d1dc77a218bdeac92;p=alttp.git show details in discord command log --- diff --git a/package-lock.json b/package-lock.json index b8998a2..f875349 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "devDependencies": { "@babel/eslint-parser": "^7.22.11", "@babel/preset-react": "^7.13.13", + "@codemirror/lang-json": "^6.0.2", "@popperjs/core": "^2.10.2", "@tailwindcss/forms": "^0.5.6", "@testing-library/jest-dom": "^6.4.2", @@ -1941,6 +1942,17 @@ "@lezer/javascript": "^1.0.0" } }, + "node_modules/@codemirror/lang-json": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", + "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@lezer/json": "^1.0.0" + } + }, "node_modules/@codemirror/language": { "version": "6.11.1", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.1.tgz", @@ -3103,6 +3115,18 @@ "@lezer/lr": "^1.3.0" } }, + "node_modules/@lezer/json": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", + "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@lezer/lr": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", diff --git a/package.json b/package.json index b51ad97..2f1696f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "devDependencies": { "@babel/eslint-parser": "^7.22.11", "@babel/preset-react": "^7.13.13", + "@codemirror/lang-json": "^6.0.2", "@popperjs/core": "^2.10.2", "@tailwindcss/forms": "^0.5.6", "@testing-library/jest-dom": "^6.4.2", diff --git a/resources/js/components/discord-bot/GuildProtocol.jsx b/resources/js/components/discord-bot/GuildProtocol.jsx index fd65cbc..e653367 100644 --- a/resources/js/components/discord-bot/GuildProtocol.jsx +++ b/resources/js/components/discord-bot/GuildProtocol.jsx @@ -1,33 +1,11 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { getUserName } from '../../helpers/User'; +import GuildProtocolEntry from './GuildProtocolEntry'; const GuildProtocol = ({ protocol }) => { - const { t } = useTranslation(); - return protocol.map((entry) => -
-
- {t(`discordBot.commandType.${entry.command}`)} - {t(`discordBot.commandStatus.${entry.status}`)} -
-
- - {entry.user - ? t('discordBot.commandTimeUser', { time: new Date(entry.created_at), user: getUserName(entry.user) }) - : t('discordBot.commandTime', { time: new Date(entry.created_at) }) - } - - - {entry.executed_at - ? t('discordBot.commandTime', { time: new Date(entry.executed_at) }) - : t('discordBot.commandPending') - } - -
-
+ ); }; diff --git a/resources/js/components/discord-bot/GuildProtocolEntry.jsx b/resources/js/components/discord-bot/GuildProtocolEntry.jsx new file mode 100644 index 0000000..dd8d52d --- /dev/null +++ b/resources/js/components/discord-bot/GuildProtocolEntry.jsx @@ -0,0 +1,105 @@ +import { json } from '@codemirror/lang-json'; +import PropTypes from 'prop-types'; +import React from 'react'; +import { Button } from 'react-bootstrap'; +import { useTranslation } from 'react-i18next'; +import { githubDark } from '@uiw/codemirror-theme-github'; +import CodeMirror from '@uiw/react-codemirror'; + +import { getUserName } from '../../helpers/User'; + +const GuildProtocolEntry = ({ entry }) => { + const [showDetail, setShowDeatil] = React.useState(false); + + const { t } = useTranslation(); + + const className = React.useMemo(() => { + const classNames = ['discord-bot-protocol', 'border-top']; + if (entry.status === 'exception') { + classNames.push('has-error'); + } + return classNames.join(' '); + }, [entry]); + + const statusLine = React.useMemo(() => { + const info = {}; + if (entry.status === 'exception') { + if (entry.result && entry.result.type === 'Discord\\Http\\Exceptions\\NoPermissionsException') { + info.message = t('discordBot.commandResult.permissionDenied'); + } else { + info.message = entry.result.type; + } + } + return t(`discordBot.commandStatus.${entry.status}`, info); + }, [entry, t]); + + return
+
+ {t(`discordBot.commandType.${entry.command}`)} + {entry.parameters || entry.result ? + + : + {statusLine} + } +
+
+ + {entry.user + ? t('discordBot.commandTimeUser', { time: new Date(entry.created_at), user: getUserName(entry.user) }) + : t('discordBot.commandTime', { time: new Date(entry.created_at) }) + } + + + {entry.executed_at + ? t('discordBot.commandTime', { time: new Date(entry.executed_at) }) + : t('discordBot.commandPending') + } + +
+
+ {entry.parameters ?
+ {t('discordBot.commandParameters')} + +
: null} + {entry.result ?
+ {t('discordBot.commandResult.heading')} + +
: null} +
+
; +}; + +GuildProtocolEntry.propTypes = { + entry: PropTypes.shape({ + command: PropTypes.string, + created_at: PropTypes.string, + executed_at: PropTypes.string, + id: PropTypes.number, + parameters: PropTypes.shape({ + }), + result: PropTypes.shape({ + type: PropTypes.string, + }), + status: PropTypes.string, + user: PropTypes.shape({ + }), + }).isRequired, +}; + +export default GuildProtocolEntry; diff --git a/resources/js/i18n/de.js b/resources/js/i18n/de.js index 8bd2248..be5da23 100644 --- a/resources/js/i18n/de.js +++ b/resources/js/i18n/de.js @@ -143,10 +143,15 @@ export default { addUser: 'User abonnieren', channel: 'Kanal', channelControls: 'Kanal-Steuerung', + commandParameters: 'Parameter', commandPending: 'Steht aus', + commandResult: { + heading: 'Ergebnis', + permissionDenied: 'Zugriff verweigert', + }, commandStatus: { done: 'Abgeschlossen', - exception: 'Fehler', + exception: 'Fehler: {{ message }}', executing: 'Ausführen', hold: 'Pausiert', pending: 'Ausstehend', diff --git a/resources/js/i18n/en.js b/resources/js/i18n/en.js index 9b4b06d..de6c223 100644 --- a/resources/js/i18n/en.js +++ b/resources/js/i18n/en.js @@ -143,10 +143,15 @@ export default { addUser: 'Subscribe to user', channel: 'Channel', channelControls: 'Channel controls', + commandParameters: 'Parameters', commandPending: 'Pending execution', + commandResult: { + heading: 'Result', + permissionDenied: 'Permission denied', + }, commandStatus: { done: 'Done', - exception: 'Error', + exception: 'Error: {{ message }}', executing: 'Executing', hold: 'Hold', pending: 'Pending', diff --git a/resources/sass/common.scss b/resources/sass/common.scss index f81daa3..bbb4f0f 100644 --- a/resources/sass/common.scss +++ b/resources/sass/common.scss @@ -30,6 +30,12 @@ h1 { } } +pre.code { + background: $dark; + color: $light; + padding: .5ex 1ex; +} + @keyframes loading-pulse { from { box-shadow: 0 0 0 2em #aaa; diff --git a/resources/sass/discord.scss b/resources/sass/discord.scss index c66b740..ae813c8 100644 --- a/resources/sass/discord.scss +++ b/resources/sass/discord.scss @@ -5,6 +5,18 @@ } } +.discord-bot-protocol { + .command-status { + color: inherit; + text-decoration: none; + } + &.has-error { + .command-status { + color: $warning; + } + } +} + .guild-box { padding: 0; color: inherit;