chore: make sidebar non sticky
This commit is contained in:
parent
35e34b36f9
commit
7091dc152f
@ -1805,8 +1805,6 @@ h3 {
|
||||
padding: 2rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--border);
|
||||
position: sticky;
|
||||
top: 120px;
|
||||
}
|
||||
|
||||
.sidebar-widget h3 {
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Meldung eingereicht. Unser Team wird sie prüfen."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Befehle & Berechtigungen",
|
||||
"title": "Befehle",
|
||||
"no_commands": "Keine Befehle für dieses Plugin angegeben.",
|
||||
"aliases": "Aliasse",
|
||||
"permission": "Berechtigung",
|
||||
"no_permission": "Keine erforderlich",
|
||||
"copy_command": "Befehl kopieren",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Report submitted. Our moderation team will investigate."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Commands & Permissions",
|
||||
"title": "Commands",
|
||||
"no_commands": "No commands listed for this plugin.",
|
||||
"aliases": "Aliases",
|
||||
"permission": "Permission",
|
||||
"no_permission": "None required",
|
||||
"copy_command": "Copy command",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Reporte enviado. Nuestro equipo lo revisará."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Comandos y Permisos",
|
||||
"title": "Comandos",
|
||||
"no_commands": "No hay comandos listados para este plugin.",
|
||||
"aliases": "Alias",
|
||||
"permission": "Permiso",
|
||||
"no_permission": "Ninguno requerido",
|
||||
"copy_command": "Copiar comando",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Signalement envoyé. Notre équipe va l'examiner."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Commandes et Permissions",
|
||||
"title": "Commandes",
|
||||
"no_commands": "Aucune commande listée pour ce plugin.",
|
||||
"aliases": "Alias",
|
||||
"permission": "Permission",
|
||||
"no_permission": "Aucune requise",
|
||||
"copy_command": "Copier la commande",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Segnalazione inviata. Il team di moderazione verificherà."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Comandi e Permessi",
|
||||
"title": "Comandi",
|
||||
"no_commands": "Nessun comando elencato per questo plugin.",
|
||||
"aliases": "Alias",
|
||||
"permission": "Permesso",
|
||||
"no_permission": "Nessuno richiesto",
|
||||
"copy_command": "Copia comando",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "報告を受け付けました。運営チームが確認いたします。"
|
||||
},
|
||||
"commands": {
|
||||
"title": "コマンドと権限",
|
||||
"title": "コマンド",
|
||||
"no_commands": "このプラグインに登録されているコマンドはありません。",
|
||||
"aliases": "エイリアス",
|
||||
"permission": "権限",
|
||||
"no_permission": "権限不要",
|
||||
"copy_command": "コマンドをコピー",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "신고가 접수되었습니다. 검토 후 처리하겠습니다."
|
||||
},
|
||||
"commands": {
|
||||
"title": "명령어 및 권한",
|
||||
"title": "명령어",
|
||||
"no_commands": "이 플러그인에 등록된 명령어가 없습니다.",
|
||||
"aliases": "별칭",
|
||||
"permission": "권한",
|
||||
"no_permission": "필요 없음",
|
||||
"copy_command": "명령어 복사",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Melding verzonden. Ons moderatieteam zal dit onderzoeken."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Commando's & Permissies",
|
||||
"title": "Commando's",
|
||||
"no_commands": "Geen commando's vermeld voor deze plugin.",
|
||||
"aliases": "Aliassen",
|
||||
"permission": "Permissie",
|
||||
"no_permission": "Geen vereist",
|
||||
"copy_command": "Kopieer commando",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Zgłoszenie wysłane. Zespół moderacji zajmie się sprawą."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Polecenia i Uprawnienia",
|
||||
"title": "Polecenia",
|
||||
"no_commands": "Brak poleceń dla tego pluginu.",
|
||||
"aliases": "Aliasy",
|
||||
"permission": "Uprawnienie",
|
||||
"no_permission": "Brak wymaganego",
|
||||
"copy_command": "Kopiuj polecenie",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Denúncia enviada com sucesso. Nossa equipe irá analisar."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Comandos e Permissões",
|
||||
"title": "Comandos",
|
||||
"no_commands": "Nenhum comando listado para este plugin.",
|
||||
"aliases": "Aliases",
|
||||
"permission": "Permissão",
|
||||
"no_permission": "Nenhuma necessária",
|
||||
"copy_command": "Copiar comando",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "Жалоба отправлена на рассмотрение модераторам."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Команды и Права",
|
||||
"title": "Команды",
|
||||
"no_commands": "У этого плагина нет зарегистрированных команд.",
|
||||
"aliases": "Алиасы",
|
||||
"permission": "Право",
|
||||
"no_permission": "Не требуется",
|
||||
"copy_command": "Скопировать команду",
|
||||
|
||||
@ -76,9 +76,10 @@
|
||||
"success": "Bildirim iletildi. Moderasyon ekibimiz inceleyecektir."
|
||||
},
|
||||
"commands": {
|
||||
"title": "Komutlar ve İzinler",
|
||||
"title": "Komutlar",
|
||||
"no_commands": "Bu eklenti için listelenmiş komut yok.",
|
||||
"permission": "İzin",
|
||||
"aliases": "Takma Adlar",
|
||||
"permission": "Yetki",
|
||||
"no_permission": "Gerekli değil",
|
||||
"copy_command": "Komutu kopyala",
|
||||
"copy_permission": "İzni kopyala",
|
||||
|
||||
@ -76,8 +76,9 @@
|
||||
"success": "举报已提交,审核团队将尽快处理。"
|
||||
},
|
||||
"commands": {
|
||||
"title": "命令与权限",
|
||||
"title": "指令",
|
||||
"no_commands": "此插件未列出任何指令。",
|
||||
"aliases": "别名",
|
||||
"permission": "权限",
|
||||
"no_permission": "无需权限",
|
||||
"copy_command": "复制指令",
|
||||
|
||||
@ -208,7 +208,7 @@ const PluginCommandsSidebarWidget = ({ commands }: { commands?: PluginCommand[]
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '0.85rem' }}>
|
||||
<h3 style={{ margin: 0, display: 'flex', alignItems: 'center', gap: '0.45rem', fontSize: '0.82rem' }}>
|
||||
<Terminal size={14} color="var(--primary)" />
|
||||
{t('plugin.commands.title', 'Commands & Permissions')}
|
||||
{t('plugin.commands.title', 'Commands')}
|
||||
</h3>
|
||||
<span style={{
|
||||
fontSize: '0.7rem',
|
||||
@ -283,6 +283,34 @@ const PluginCommandsSidebarWidget = ({ commands }: { commands?: PluginCommand[]
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Aliases row */}
|
||||
{cmd.aliases && Array.isArray(cmd.aliases) && cmd.aliases.length > 0 ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: '0.3rem', marginTop: '-0.1rem' }}>
|
||||
<span style={{ fontSize: '0.66rem', color: 'var(--text-muted)', fontWeight: 600 }}>
|
||||
{t('plugin.commands.aliases', 'Aliases')}:
|
||||
</span>
|
||||
{cmd.aliases.map((alias: string, aIdx: number) => {
|
||||
const formattedAlias = alias.startsWith('/') ? alias : `/${alias}`;
|
||||
return (
|
||||
<span
|
||||
key={aIdx}
|
||||
style={{
|
||||
fontFamily: 'var(--font-mono)',
|
||||
fontSize: '0.68rem',
|
||||
color: 'var(--text-2, #cbd5e1)',
|
||||
background: 'rgba(255, 255, 255, 0.05)',
|
||||
border: '1px solid rgba(255, 255, 255, 0.08)',
|
||||
borderRadius: '4px',
|
||||
padding: '1px 5px',
|
||||
}}
|
||||
>
|
||||
{formattedAlias}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* Permission row */}
|
||||
{cmd.permission ? (
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '0.5rem' }}>
|
||||
|
||||
@ -236,6 +236,7 @@ const AddPlugin = () => {
|
||||
|
||||
const [commands, setCommands] = useState<Array<{
|
||||
name: string;
|
||||
aliases: string;
|
||||
permission: string;
|
||||
descriptions: Record<string, string>;
|
||||
}>>([]);
|
||||
@ -245,13 +246,14 @@ const AddPlugin = () => {
|
||||
...prev,
|
||||
{
|
||||
name: '',
|
||||
aliases: '',
|
||||
permission: '',
|
||||
descriptions: { [activeLocale]: '' }
|
||||
}
|
||||
]);
|
||||
};
|
||||
|
||||
const updateCommandField = (index: number, field: 'name' | 'permission', value: string) => {
|
||||
const updateCommandField = (index: number, field: 'name' | 'permission' | 'aliases', value: string) => {
|
||||
const cleanValue = field === 'name' ? value.replace(/^\/+/, '') : value;
|
||||
setCommands(prev => {
|
||||
const next = [...prev];
|
||||
@ -462,12 +464,18 @@ const AddPlugin = () => {
|
||||
try {
|
||||
const validCommands = commands
|
||||
.filter(c => c.name.trim().replace(/^\/+/, '').length > 0)
|
||||
.map((c, idx) => ({
|
||||
.map((c, idx) => {
|
||||
const aliases = c.aliases
|
||||
? c.aliases.split(',').map(a => a.trim().replace(/^\/+/, '')).filter(a => a.length > 0)
|
||||
: undefined;
|
||||
return {
|
||||
name: c.name.trim().replace(/^\/+/, ''),
|
||||
aliases: aliases && aliases.length > 0 ? aliases : undefined,
|
||||
permission: c.permission.trim() || undefined,
|
||||
description: c.descriptions,
|
||||
display_order: idx,
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
||||
const metadata = {
|
||||
name,
|
||||
@ -810,11 +818,11 @@ const AddPlugin = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Commands & Permissions */}
|
||||
{/* Commands */}
|
||||
<div className="mp-card">
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '0.85rem' }}>
|
||||
<div className="mp-card-title" style={{ margin: 0 }}>
|
||||
<Terminal size={14} />Commands & Permissions
|
||||
<Terminal size={14} />Commands
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
@ -857,8 +865,8 @@ const AddPlugin = () => {
|
||||
gap: '0.65rem'
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr auto', gap: '0.75rem', alignItems: 'flex-start' }}>
|
||||
<div>
|
||||
<label className="mp-label" style={{ fontSize: '0.72rem', marginBottom: '0.25rem' }}>
|
||||
Command <span style={{ color: 'var(--mp-error)' }}>*</span>
|
||||
</label>
|
||||
@ -872,7 +880,20 @@ const AddPlugin = () => {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div>
|
||||
<label className="mp-label" style={{ fontSize: '0.72rem', marginBottom: '0.25rem' }}>
|
||||
Aliases <span style={{ color: 'var(--mp-text-3)', fontWeight: 400 }}>(optional, comma-separated)</span>
|
||||
</label>
|
||||
<input
|
||||
className="mp-input"
|
||||
style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', padding: '0.45rem 0.65rem' }}
|
||||
placeholder="hub, lobby, s"
|
||||
value={cmd.aliases}
|
||||
maxLength={128}
|
||||
onChange={e => updateCommandField(idx, 'aliases', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="mp-label" style={{ fontSize: '0.72rem', marginBottom: '0.25rem' }}>
|
||||
Permission Node <span style={{ color: 'var(--mp-text-3)', fontWeight: 400 }}>(optional)</span>
|
||||
</label>
|
||||
|
||||
@ -208,6 +208,7 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
const [commands, setCommands] = useState<Array<{
|
||||
id?: number;
|
||||
name: string;
|
||||
aliases: string;
|
||||
permission: string;
|
||||
descriptions: Record<string, string>;
|
||||
}>>(() => {
|
||||
@ -235,6 +236,7 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
return {
|
||||
id: cmd.id,
|
||||
name: (cmd.name || '').replace(/^\/+/, ''),
|
||||
aliases: Array.isArray(cmd.aliases) ? cmd.aliases.join(', ') : '',
|
||||
permission: cmd.permission || '',
|
||||
descriptions: descMap,
|
||||
};
|
||||
@ -246,13 +248,14 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
...prev,
|
||||
{
|
||||
name: '',
|
||||
aliases: '',
|
||||
permission: '',
|
||||
descriptions: { [activeLocale]: '' },
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const updateCommandField = (index: number, field: 'name' | 'permission', value: string) => {
|
||||
const updateCommandField = (index: number, field: 'name' | 'permission' | 'aliases', value: string) => {
|
||||
const cleanValue = field === 'name' ? value.replace(/^\/+/, '') : value;
|
||||
setCommands(prev => {
|
||||
const next = [...prev];
|
||||
@ -313,13 +316,19 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
setSaveSuccess(false);
|
||||
const validCommands = commands
|
||||
.filter(c => c.name.trim().replace(/^\/+/, '').length > 0)
|
||||
.map((c, idx) => ({
|
||||
.map((c, idx) => {
|
||||
const aliases = c.aliases
|
||||
? c.aliases.split(',').map(a => a.trim().replace(/^\/+/, '')).filter(a => a.length > 0)
|
||||
: undefined;
|
||||
return {
|
||||
id: c.id,
|
||||
name: c.name.trim().replace(/^\/+/, ''),
|
||||
aliases: aliases && aliases.length > 0 ? aliases : undefined,
|
||||
permission: c.permission.trim() || undefined,
|
||||
description: c.descriptions,
|
||||
display_order: idx,
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
||||
const metadata = {
|
||||
name,
|
||||
@ -631,11 +640,11 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* ── Commands & Permissions ── */}
|
||||
{/* ── Commands ── */}
|
||||
<div className="mp-card">
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '0.85rem' }}>
|
||||
<div className="mp-card-title" style={{ margin: 0 }}>
|
||||
<Terminal size={14} />Commands & Permissions
|
||||
<Terminal size={14} />Commands
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
@ -678,8 +687,8 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
gap: '0.65rem'
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr auto', gap: '0.75rem', alignItems: 'flex-start' }}>
|
||||
<div>
|
||||
<label className="mp-label" style={{ fontSize: '0.72rem', marginBottom: '0.25rem' }}>
|
||||
Command <span style={{ color: 'var(--mp-error)' }}>*</span>
|
||||
</label>
|
||||
@ -693,7 +702,20 @@ const StoreListing = ({ plugin, onSaved }: Props) => {
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div>
|
||||
<label className="mp-label" style={{ fontSize: '0.72rem', marginBottom: '0.25rem' }}>
|
||||
Aliases <span style={{ color: 'var(--mp-text-3)', fontWeight: 400 }}>(optional, comma-separated)</span>
|
||||
</label>
|
||||
<input
|
||||
className="mp-input"
|
||||
style={{ fontFamily: 'var(--font-mono)', fontSize: '0.82rem', padding: '0.45rem 0.65rem' }}
|
||||
placeholder="hub, lobby, s"
|
||||
value={cmd.aliases}
|
||||
maxLength={128}
|
||||
onChange={e => updateCommandField(idx, 'aliases', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="mp-label" style={{ fontSize: '0.72rem', marginBottom: '0.25rem' }}>
|
||||
Permission Node <span style={{ color: 'var(--mp-text-3)', fontWeight: 400 }}>(optional)</span>
|
||||
</label>
|
||||
|
||||
@ -8,6 +8,7 @@ export interface PluginCommand {
|
||||
name: string;
|
||||
permission?: string;
|
||||
description?: Record<string, string> | string | null;
|
||||
aliases?: string[];
|
||||
display_order?: number;
|
||||
created_at?: string;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user