From f157174ae49b84a062129d82f971225ecfb79bea Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Fri, 26 Jun 2026 19:52:01 +0800 Subject: [PATCH] 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 --- .../bot-form/EventBindingsEditor.tsx | 69 +++++++++---------- web/src/i18n/locales/en-US.ts | 17 +++++ web/src/i18n/locales/ja-JP.ts | 17 +++++ web/src/i18n/locales/zh-Hans.ts | 17 +++++ 4 files changed, 85 insertions(+), 35 deletions(-) diff --git a/web/src/app/home/bots/components/bot-form/EventBindingsEditor.tsx b/web/src/app/home/bots/components/bot-form/EventBindingsEditor.tsx index fa73d62dd..54ba788da 100644 --- a/web/src/app/home/bots/components/bot-form/EventBindingsEditor.tsx +++ b/web/src/app/home/bots/components/bot-form/EventBindingsEditor.tsx @@ -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.`, 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({ )} - - IF - - - - - onUpdate(globalIndex, patch)} - /> - - {!pipelineAllowed && binding.target_type === 'pipeline' && ( - - {t('bots.unsupportedPipelineEvent')} - - )} - {/* conditions toggle */}