feat(web): add icons/emoji to selectors, sync bot enable status and plugin list in sidebar

- Bot adapter selector: show adapter icon in trigger and dropdown items
- Knowledge engine selector: show plugin icon derived from plugin_id
- Pipeline binding selector: show pipeline emoji in trigger and dropdown items
- Knowledge base selectors (single/multi): show KB emoji in all views
- Sidebar bot entries: show green/gray status dot on adapter icon for enable/disable state
- Sidebar plugin list: sync after install/uninstall from all entry points (PluginInstalledComponent, plugins page, marketplace page)
- Pipeline form: add cursor-pointer to left-side tab list buttons
- Clean up unused onBotDeleted prop from BotForm
This commit is contained in:
Junyan Qin
2026-03-27 14:51:15 +08:00
parent 127dc455c3
commit bc3199bf29
11 changed files with 178 additions and 31 deletions
@@ -310,19 +310,58 @@ export default function KBForm({
value={field.value}
>
<SelectTrigger className="w-full bg-[#ffffff] dark:bg-[#2a2a2e]">
<SelectValue
placeholder={t('knowledge.selectKnowledgeEngine')}
/>
{field.value ? (
(() => {
const [author, name] = field.value.split('/');
const engine = ragEngines.find(
(e) => e.plugin_id === field.value,
);
return (
<div className="flex items-center gap-2">
<img
src={httpClient.getPluginIconURL(
author,
name,
)}
alt=""
className="h-5 w-5 rounded"
/>
<span>
{engine
? extractI18nObject(engine.name)
: field.value}
</span>
</div>
);
})()
) : (
<SelectValue
placeholder={t('knowledge.selectKnowledgeEngine')}
/>
)}
</SelectTrigger>
<SelectContent className="fixed z-[1000]">
{ragEngines.map((engine) => (
<SelectItem
key={engine.plugin_id}
value={engine.plugin_id}
>
{extractI18nObject(engine.name)}
</SelectItem>
))}
{ragEngines.map((engine) => {
const [author, name] = engine.plugin_id.split('/');
return (
<SelectItem
key={engine.plugin_id}
value={engine.plugin_id}
>
<div className="flex items-center gap-2">
<img
src={httpClient.getPluginIconURL(
author,
name,
)}
alt=""
className="h-5 w-5 rounded"
/>
<span>{extractI18nObject(engine.name)}</span>
</div>
</SelectItem>
);
})}
</SelectContent>
</Select>
</FormControl>