Skip to content

Commit 17f156c

Browse files
committed
Consolidate UI components by merging Presets into the Configurations component
1 parent 79e4b42 commit 17f156c

9 files changed

Lines changed: 237 additions & 747 deletions

File tree

‎apps/editor/src/views/panel/frontend/Main/MainView/MainView.tsx‎

Lines changed: 113 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import styles from './MainView.module.scss'
22
import { Configurations as UiConfigurations } from '@ui/components/editor/panel/Configurations'
3-
import { Presets as UiPresets } from '@ui/components/editor/panel/Presets'
43
import { PromptField as UiPromptField } from '@ui/components/editor/panel/prompts/PromptField'
54
import { Separator as UiSeparator } from '@ui/components/editor/panel/Separator'
65
import { Preset } from '@shared/types/preset'
@@ -19,6 +18,8 @@ import { use_invocation_counts } from './hooks/use-invocation-counts'
1918
import { SelectionState } from '@/views/panel/types/messages'
2019
import { use_translation } from '../../i18n/use-translation'
2120
import { Checkbox as UiCheckbox } from '@ui/components/editor/common/Checkbox'
21+
import { Icon } from '@ui/components/editor/common/Icon'
22+
import { CHATBOTS } from '@shared/constants/chatbots'
2223

2324
type Props = {
2425
scroll_reset_key: number
@@ -125,6 +126,29 @@ type Props = {
125126
voice_input_push_to_talk: boolean
126127
}
127128

129+
const chatbot_to_icon: Record<keyof typeof CHATBOTS, Icon.Variant> = {
130+
'AI Studio': 'AI_STUDIO',
131+
ChatGPT: 'CHATGPT',
132+
Claude: 'CLAUDE',
133+
Copilot: 'COPILOT',
134+
DeepSeek: 'DEEPSEEK',
135+
Doubao: 'DOUBAO',
136+
Gemini: 'GEMINI',
137+
'GitHub Copilot': 'GITHUB_COPILOT',
138+
Grok: 'GROK',
139+
HuggingChat: 'HUGGING_CHAT',
140+
Kimi: 'KIMI',
141+
Mistral: 'MISTRAL',
142+
'Meta AI': 'META',
143+
Arena: 'ARENA',
144+
'Open WebUI': 'OPEN_WEBUI',
145+
OpenRouter: 'OPENROUTER',
146+
Qwen: 'QWEN',
147+
Together: 'TOGETHER',
148+
Yuanbao: 'YUANBAO',
149+
Z: 'Z_AI'
150+
}
151+
128152
export const MainView: React.FC<Props> = (props) => {
129153
const { t } = use_translation()
130154

@@ -196,6 +220,51 @@ export const MainView: React.FC<Props> = (props) => {
196220
configurations: props.configurations
197221
})
198222

223+
const web_configurations: UiConfigurations.Configuration[] = props.presets.map(
224+
(preset, index) => {
225+
const is_unnamed = !preset.name || /^\(\d+\)$/.test(preset.name.trim())
226+
const display_name = is_unnamed
227+
? preset.chatbot!
228+
: preset.name!.replace(/ \(\d+\)$/, '')
229+
230+
const get_details = (): string[] => {
231+
const { chatbot, model } = preset
232+
const model_display_name =
233+
model && chatbot ? CHATBOTS[chatbot].models?.[model]?.label || model : null
234+
235+
if (is_unnamed) return model_display_name ? [model_display_name] : []
236+
if (model_display_name) return [chatbot!, model_display_name]
237+
return chatbot ? [chatbot] : []
238+
}
239+
240+
return {
241+
id: preset.name ?? `unnamed-${index}`,
242+
title: display_name,
243+
details: get_details(),
244+
is_pinned: preset.is_pinned,
245+
icon: preset.chatbot ? chatbot_to_icon[preset.chatbot] : undefined,
246+
}
247+
}
248+
)
249+
250+
const api_configurations: UiConfigurations.Configuration[] = props.configurations.map(
251+
(c) => {
252+
const details = [c.provider_name]
253+
if (c.reasoning_effort) {
254+
details.push(`${c.reasoning_effort}`)
255+
}
256+
if (c.temperature != null) {
257+
details.push(`${c.temperature}`)
258+
}
259+
return {
260+
id: c.id,
261+
title: c.model,
262+
details,
263+
is_pinned: c.is_pinned
264+
}
265+
}
266+
)
267+
199268
return (
200269
<>
201270
<Header
@@ -331,46 +400,52 @@ export const MainView: React.FC<Props> = (props) => {
331400
{props.mode == MODE.WEB && (
332401
<>
333402
<UiSeparator height={8} />
334-
<UiPresets
335-
web_prompt_type={props.web_prompt_type}
336-
is_connected={props.is_connected}
337-
has_instructions={!!props.instructions}
338-
has_context={props.token_count > 0}
339-
is_in_code_completions_mode={
340-
props.web_prompt_type == 'code-at-cursor'
403+
<UiConfigurations
404+
configurations={web_configurations}
405+
on_create={(params) =>
406+
props.on_create_preset(
407+
params?.create_on_top ? 'top' : 'bottom',
408+
params?.insertion_index
409+
)
341410
}
342-
presets={props.presets}
343-
on_create={props.on_create_preset}
344-
on_preset_click={(preset_name) =>
411+
on_configuration_click={(id) => {
345412
props.initialize_chats({
346-
preset_name,
413+
preset_name: id,
347414
show_quick_pick: false,
348415
invocation_count: current_invocation_count
349416
})
350-
}
351-
on_preset_copy={props.copy_to_clipboard}
352-
on_preset_edit={props.on_preset_edit}
353-
on_presets_reorder={props.on_presets_reorder}
354-
on_duplicate={props.on_duplicate_preset}
355-
on_delete={props.on_delete_preset}
356-
on_toggle_preset_pinned={props.on_toggle_preset_pinned}
357-
selected_preset_name={props.selected_preset_name}
417+
}}
418+
on_edit={(id) => props.on_preset_edit(id)}
419+
on_reorder={(reordered) => {
420+
const new_presets = reordered.map((c) => {
421+
return props.presets.find(
422+
(p, i) => (p.name ?? `unnamed-${i}`) === c.id
423+
)!
424+
})
425+
props.on_presets_reorder(new_presets)
426+
}}
427+
on_duplicate={(id) => {
428+
const idx = props.presets.findIndex((p, i) => (p.name ?? `unnamed-${i}`) === id)
429+
props.on_duplicate_preset(idx)
430+
}}
431+
on_delete={(id) => {
432+
const idx = props.presets.findIndex((p, i) => (p.name ?? `unnamed-${i}`) === id)
433+
props.on_delete_preset(idx)
434+
}}
435+
on_toggle_pinned={(id) => props.on_toggle_preset_pinned(id)}
436+
selected_configuration_id={props.selected_preset_name}
358437
is_collapsed={props.presets_collapsed}
359438
on_toggle_collapsed={props.on_presets_collapsed_change}
360439
translations={{
361440
title: t('presets.title'),
362441
empty: t('presets.empty'),
363-
preset: t('presets.preset'),
364-
presets: t('presets.presets'),
365442
add_new: t('action.add-new'),
366-
add_new_tooltip: t('action.add-new'),
367-
copy_tooltip: t('action.copy'),
368-
pin_tooltip: t('action.pin'),
369-
unpin_tooltip: t('action.unpin'),
370-
duplicate_tooltip: t('action.duplicate-preset'),
371-
edit_tooltip: t('action.edit'),
372-
delete_tooltip: t('action.delete'),
373-
insert_tooltip: t('action.insert-preset')
443+
pin: t('action.pin'),
444+
unpin: t('action.unpin'),
445+
duplicate_configuration: t('action.duplicate-configuration'),
446+
edit: t('action.edit'),
447+
delete: t('action.delete'),
448+
insert: t('action.insert-configuration'),
374449
}}
375450
/>
376451
</>
@@ -380,10 +455,9 @@ export const MainView: React.FC<Props> = (props) => {
380455
<>
381456
<UiSeparator height={8} />
382457
<UiConfigurations
383-
api_prompt_type={props.api_prompt_type}
384-
configurations={props.configurations}
458+
configurations={api_configurations}
385459
on_configuration_click={props.on_configuration_click}
386-
on_reorder={props.on_configurations_reorder}
460+
on_reorder={(reordered) => props.on_configurations_reorder(reordered)}
387461
on_toggle_pinned={props.on_toggle_pinned_configuration}
388462
on_edit={props.on_edit_configuration}
389463
on_delete={props.on_delete_configuration}
@@ -396,13 +470,12 @@ export const MainView: React.FC<Props> = (props) => {
396470
title: t('configurations.title'),
397471
empty: t('configurations.empty'),
398472
add_new: t('action.add-new'),
399-
add_new_tooltip: t('action.add-new'),
400-
pin_tooltip: t('action.pin'),
401-
unpin_tooltip: t('action.unpin'),
402-
insert_tooltip: t('action.insert-configuration'),
403-
edit_tooltip: t('action.edit'),
404-
delete_tooltip: t('action.delete'),
405-
duplicate_tooltip: t('action.duplicate-configuration')
473+
pin: t('action.pin'),
474+
unpin: t('action.unpin'),
475+
insert: t('action.insert-configuration'),
476+
edit: t('action.edit'),
477+
delete: t('action.delete'),
478+
duplicate_configuration: t('action.duplicate-configuration')
406479
}}
407480
/>
408481
</>

‎apps/editor/src/views/panel/frontend/i18n/translations/actions.ts‎

Lines changed: 16 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -71,24 +71,6 @@ export const actions = {
7171
hu: 'Rögzítés feloldása',
7272
bg: 'Откачане'
7373
},
74-
'action.duplicate-preset': {
75-
en: 'Duplicate preset',
76-
pl: 'Duplikuj preset',
77-
'zh-cn': '复制预设',
78-
ja: 'プリセットを複製',
79-
'zh-tw': '複製預設',
80-
de: 'Voreinstellung duplizieren',
81-
es: 'Duplicar ajuste preestablecido',
82-
fr: 'Dupliquer le préréglage',
83-
'pt-br': 'Duplicar predefinição',
84-
ru: 'Дублировать пресет',
85-
ko: '사전 설정 복제',
86-
it: 'Duplica preimpostazione',
87-
tr: 'Ön ayarı çoğalt',
88-
cs: 'Duplikovat předvolbu',
89-
hu: 'Előbeállítás duplikálása',
90-
bg: 'Дублиране на шаблона'
91-
},
9274
'action.duplicate-configuration': {
9375
en: 'Duplicate configuration',
9476
pl: 'Duplikuj konfigurację',
@@ -107,24 +89,6 @@ export const actions = {
10789
hu: 'Konfiguráció duplikálása',
10890
bg: 'Дублиране на конфигурация'
10991
},
110-
'action.duplicate': {
111-
en: 'Duplicate',
112-
pl: 'Duplikuj',
113-
'zh-cn': '复制',
114-
ja: '複製',
115-
'zh-tw': '複製',
116-
de: 'Duplizieren',
117-
es: 'Duplicar',
118-
fr: 'Dupliquer',
119-
'pt-br': 'Duplicar',
120-
ru: 'Дублировать',
121-
ko: '복제',
122-
it: 'Duplica',
123-
tr: 'Çoğalt',
124-
cs: 'Duplikovat',
125-
hu: 'Kettőzés',
126-
bg: 'Дублиране'
127-
},
12892
'action.edit': {
12993
en: 'Edit',
13094
pl: 'Edytuj',
@@ -161,41 +125,23 @@ export const actions = {
161125
hu: 'Törlés',
162126
bg: 'Изтриване'
163127
},
164-
'action.insert-preset': {
165-
en: 'Insert a new item below/above',
166-
pl: 'Wstaw nowy element poniżej/powyżej',
167-
'zh-cn': '在下方/上方插入新项',
168-
ja: '下/上に新しいアイテムを挿入',
169-
'zh-tw': '在下方/上方插入新項目',
170-
de: 'Neues Element darunter/darüber einfügen',
171-
es: 'Insertar un nuevo elemento debajo/arriba',
172-
fr: 'Insérer un nouvel élément en dessous/au-dessus',
173-
'pt-br': 'Inserir um novo item abaixo/acima',
174-
ru: 'Вставить новый элемент ниже/выше',
175-
ko: '아래/위에 새 항목 삽입',
176-
it: 'Inserisci un nuovo elemento sotto/sopra',
177-
tr: 'Aşağıya/yukarıya yeni bir öğe ekle',
178-
cs: 'Vložit novou položku pod/nad',
179-
hu: 'Új elem beszúrása alá/fölé',
180-
bg: 'Вмъкване на нов елемент отдолу/отгоре'
181-
},
182128
'action.insert-configuration': {
183-
en: 'Insert a new configuration below/above',
184-
pl: 'Wstaw nową konfigurację poniżej/powyżej',
185-
'zh-cn': '在下方/上方插入新配置',
186-
ja: '下/上に新しい設定を挿入',
187-
'zh-tw': '在下方/上方插入新設定',
188-
de: 'Neue Konfiguration darunter/darüber einfügen',
189-
es: 'Insertar una nueva configuración debajo/arriba',
190-
fr: 'Insérer une nouvelle configuration en dessous/au-dessus',
191-
'pt-br': 'Inserir uma nova configuração abaixo/acima',
192-
ru: 'Вставить новую конфигурацию ниже/выше',
193-
ko: '아래/위에 새 구성 삽입',
194-
it: 'Inserisci una nuova configurazione sotto/sopra',
195-
tr: 'Aşağıya/yukarıya yeni bir yapılandırma ekle',
196-
cs: 'Vložit novou konfiguraci pod/nad',
197-
hu: 'Új konfiguráció beszúrása alá/fölé',
198-
bg: 'Вмъкване на нова конфигурация отдолу/отгоре'
129+
en: 'Insert configuration',
130+
pl: 'Wstaw konfigurację',
131+
'zh-cn': '插入配置',
132+
ja: '設定を挿入',
133+
'zh-tw': '插入設定',
134+
de: 'Konfiguration einfügen',
135+
es: 'Insertar configuración',
136+
fr: 'Insérer une configuration',
137+
'pt-br': 'Inserir configuração',
138+
ru: 'Вставить конфигурацию',
139+
ko: '구성 삽입',
140+
it: 'Inserisci configurazione',
141+
tr: 'Yapılandırma ekle',
142+
cs: 'Vložit konfiguraci',
143+
hu: 'Konfiguráció beszúrása',
144+
bg: 'Вмъкване на конфигурация'
199145
},
200146
'action.run-selected': {
201147
en: 'Run Selected Presets',

‎packages/ui/src/components/editor/panel/Configurations/Configurations.module.scss‎

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,6 @@
33
flex-direction: column;
44
}
55

6-
.missing-config {
7-
padding: 2px 12px 0 12px;
8-
font-weight: 500;
9-
font-style: italic;
10-
}
11-
126
.configurations {
137
display: flex;
148
flex-direction: column;
@@ -59,6 +53,16 @@
5953
}
6054
}
6155

56+
&__icon {
57+
display: flex;
58+
59+
> svg {
60+
fill: var(--vscode-icon-foreground);
61+
width: 16px;
62+
height: 16px;
63+
}
64+
}
65+
6266
&__text {
6367
overflow: hidden;
6468
text-overflow: ellipsis;
@@ -86,23 +90,6 @@
8690
color: var(--cwc-text-color-dimmed);
8791
}
8892

89-
.arrow-animate {
90-
animation: arrow-left-move 2s infinite;
91-
font-weight: 600 !important;
92-
}
93-
94-
@keyframes arrow-left-move {
95-
0% {
96-
transform: translateX(0);
97-
}
98-
50% {
99-
transform: translateX(-8px);
100-
}
101-
100% {
102-
transform: translateX(0);
103-
}
104-
}
105-
10693
.footer {
10794
display: flex;
10895
padding: 10px 12px 12px 12px;

0 commit comments

Comments
 (0)