mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-22 20:36:08 +00:00
feat(bots): refine event binding editor UI and i18n
- Move conditions toggle between event select and arrow; drop "IF" label - Remove "all events" (*) option from event select - Add i18n labels for concrete event names (zh/en/ja) via bots.eventNames - Narrow fallback event set to message.received for adapters without declared supported_events (legacy adapters only emit message.received) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
committed by
huanghuoguoguo
parent
68d43834bd
commit
95f3409d55
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useMemo, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { UseFormReturn } from 'react-hook-form';
|
||||
import {
|
||||
ArrowRight,
|
||||
@@ -114,15 +115,9 @@ const ELEMENTS = [
|
||||
'Quote',
|
||||
];
|
||||
|
||||
const DEFAULT_EVENTS = [
|
||||
'message.received',
|
||||
'feedback.received',
|
||||
'group.member_joined',
|
||||
'group.member_left',
|
||||
'friend.request_received',
|
||||
'bot.invited_to_group',
|
||||
'platform.specific',
|
||||
];
|
||||
// Adapters that don't declare `supported_events` (e.g. legacy adapters)
|
||||
// only emit message.received, so that's the sole fallback option.
|
||||
const DEFAULT_EVENTS = ['message.received'];
|
||||
|
||||
// ── helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -156,6 +151,20 @@ function eventNamespaces(events: string[]) {
|
||||
return Array.from(ns).sort();
|
||||
}
|
||||
|
||||
// Localized label for an event pattern. Concrete events look up
|
||||
// `bots.eventNames.<event_with_underscores>`, falling back to the raw
|
||||
// string when no translation exists (e.g. custom/unknown events).
|
||||
function eventLabel(event: string, t: TFunction) {
|
||||
if (event === '*') return t('bots.eventWildcard');
|
||||
if (event.endsWith('.*'))
|
||||
return t('bots.eventNamespaceWildcard', {
|
||||
namespace: event.replace('.*', ''),
|
||||
});
|
||||
const key = `bots.eventNames.${event.replace(/\./g, '_')}`;
|
||||
const label = t(key);
|
||||
return label === key ? event : label;
|
||||
}
|
||||
|
||||
function targetLabel(agent: Agent) {
|
||||
return `${agent.emoji ? `${agent.emoji} ` : ''}${agent.name}`;
|
||||
}
|
||||
@@ -509,10 +518,6 @@ function BindingCardContent({
|
||||
</button>
|
||||
)}
|
||||
|
||||
<span className="text-xs font-medium text-muted-foreground shrink-0">
|
||||
IF
|
||||
</span>
|
||||
|
||||
<Select
|
||||
value={binding.event_pattern}
|
||||
onValueChange={(eventPattern) => {
|
||||
@@ -535,32 +540,12 @@ function BindingCardContent({
|
||||
<SelectContent>
|
||||
{eventOptions.map((event) => (
|
||||
<SelectItem key={event} value={event}>
|
||||
{event === '*'
|
||||
? t('bots.eventWildcard')
|
||||
: event.endsWith('.*')
|
||||
? t('bots.eventNamespaceWildcard', {
|
||||
namespace: event.replace('.*', ''),
|
||||
})
|
||||
: event}
|
||||
{eventLabel(event, t)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<ArrowRight className="h-4 w-4 shrink-0 text-muted-foreground" />
|
||||
|
||||
<TargetCombobox
|
||||
binding={binding}
|
||||
agentOptions={agentOptions}
|
||||
onUpdate={(patch) => onUpdate(globalIndex, patch)}
|
||||
/>
|
||||
|
||||
{!pipelineAllowed && binding.target_type === 'pipeline' && (
|
||||
<span className="text-xs text-destructive shrink-0">
|
||||
{t('bots.unsupportedPipelineEvent')}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* conditions toggle */}
|
||||
<Button
|
||||
type="button"
|
||||
@@ -582,6 +567,20 @@ function BindingCardContent({
|
||||
)}
|
||||
</Button>
|
||||
|
||||
<ArrowRight className="h-4 w-4 shrink-0 text-muted-foreground" />
|
||||
|
||||
<TargetCombobox
|
||||
binding={binding}
|
||||
agentOptions={agentOptions}
|
||||
onUpdate={(patch) => onUpdate(globalIndex, patch)}
|
||||
/>
|
||||
|
||||
{!pipelineAllowed && binding.target_type === 'pipeline' && (
|
||||
<span className="text-xs text-destructive shrink-0">
|
||||
{t('bots.unsupportedPipelineEvent')}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* disable/enable toggle */}
|
||||
<Button
|
||||
type="button"
|
||||
@@ -669,7 +668,7 @@ export default function EventBindingsEditor({
|
||||
const eventOptions = useMemo(() => {
|
||||
const concrete =
|
||||
supportedEvents.length > 0 ? supportedEvents : DEFAULT_EVENTS;
|
||||
return ['*', ...eventNamespaces(concrete), ...concrete].filter(
|
||||
return [...eventNamespaces(concrete), ...concrete].filter(
|
||||
(e, i, a) => a.indexOf(e) === i,
|
||||
);
|
||||
}, [supportedEvents]);
|
||||
|
||||
Reference in New Issue
Block a user