Skip to content

Commit c1599bb

Browse files
committed
Implement setup progress tracking to display a warning indicator on the settings button when configurations are missing, and refactor the button into a reusable component
1 parent 888c429 commit c1599bb

18 files changed

Lines changed: 281 additions & 96 deletions

File tree

‎apps/editor/src/views/i18n/translations.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ export const translations = {
1212
'settings.sidebar.intelligent-update': 'Intelligent Update',
1313
'settings.sidebar.prune-context': 'Prune Context',
1414
'settings.sidebar.commit-messages': 'Commit Messages',
15-
'settings.sidebar.voice-input': 'Voice Input'
15+
'settings.sidebar.voice-input': 'Voice Input',
16+
'settings.action.add-new': 'Add New...',
17+
'settings.message.missing-configuration': 'Missing configuration.'
1618
},
1719
pl: {
1820
'panel.header.settings': 'Ustawienia',
1921
'panel.header.prompt-type': 'Typ promptu',
20-
'settings.sidebar.settings': 'Ustawienia'
22+
'settings.sidebar.settings': 'Ustawienia',
23+
'settings.action.add-new': 'Dodaj nowy...',
24+
'settings.message.missing-configuration': 'Brak konfiguracji.'
2125
},
2226
'zh-cn': {
2327
'panel.header.settings': '设置',

‎apps/editor/src/views/panel/backend/panel-provider.ts‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ import { dictionary } from '@shared/constants/dictionary'
118118
import { DEFAULT_CONTEXT_SIZE_WARNING_THRESHOLD } from '@/constants/values'
119119
import { upsert_configuration } from '../../utils/upsert-configuration'
120120
import { delete_configuration } from '../../utils/delete-configuration'
121+
import { ModelProvidersManager } from '@/services/model-providers-manager'
121122

122123
export class PanelProvider implements vscode.WebviewViewProvider {
123124
private _webview_view: vscode.WebviewView | undefined
@@ -190,6 +191,40 @@ export class PanelProvider implements vscode.WebviewViewProvider {
190191
})
191192
}
192193

194+
public async send_setup_progress() {
195+
const providers_manager = new ModelProvidersManager(this.context)
196+
const [
197+
providers,
198+
edit_context,
199+
intelligent_update,
200+
prune_context,
201+
code_at_cursor,
202+
voice_input,
203+
commit_messages
204+
] = await Promise.all([
205+
providers_manager.get_providers(),
206+
providers_manager.get_edit_context_tool_configs(),
207+
providers_manager.get_intelligent_update_tool_configs(),
208+
providers_manager.get_prune_context_tool_configs(),
209+
providers_manager.get_code_completions_tool_configs(),
210+
providers_manager.get_voice_input_tool_configs(),
211+
providers_manager.get_commit_messages_tool_configs()
212+
])
213+
214+
this.send_message({
215+
command: 'SETUP_PROGRESS',
216+
setup_progress: {
217+
has_model_provider: providers.length > 0,
218+
has_configuration_for_edit_context: edit_context.length > 0,
219+
has_configuration_for_intelligent_update: intelligent_update.length > 0,
220+
has_configuration_for_prune_context: prune_context.length > 0,
221+
has_configuration_for_code_at_cursor: code_at_cursor.length > 0,
222+
has_configuration_for_voice_input: voice_input.length > 0,
223+
has_configuration_for_commit_messages: commit_messages.length > 0
224+
}
225+
})
226+
}
227+
193228
public send_currently_open_file_text() {
194229
const active_editor = vscode.window.activeTextEditor
195230
this.send_message({
@@ -317,6 +352,22 @@ export class PanelProvider implements vscode.WebviewViewProvider {
317352
handle_get_api_tool_configurations(this)
318353
}
319354

355+
const setup_progress_keys = [
356+
'codeWebChat.modelProviders',
357+
'codeWebChat.configurationsForEditContext',
358+
'codeWebChat.configurationsForCodeAtCursor',
359+
'codeWebChat.configurationsForPruneContext',
360+
'codeWebChat.configurationsForIntelligentUpdate',
361+
'codeWebChat.configurationsForCommitMessages',
362+
'codeWebChat.configurationsForVoiceInput'
363+
]
364+
365+
if (
366+
setup_progress_keys.some((key) => event.affectsConfiguration(key))
367+
) {
368+
this.send_setup_progress()
369+
}
370+
320371
if (event.affectsConfiguration('codeWebChat.isTimelineCollapsed')) {
321372
handle_get_collapsed_states(this)
322373
}
@@ -796,6 +847,8 @@ export class PanelProvider implements vscode.WebviewViewProvider {
796847
await handle_paste_url(this, message)
797848
} else if (message.command == 'SET_RECORDING_STATE') {
798849
await handle_voice_input(this, message)
850+
} else if (message.command == 'GET_SETUP_PROGRESS') {
851+
await this.send_setup_progress()
799852
}
800853
} catch (error: any) {
801854
Logger.error({

‎apps/editor/src/views/panel/frontend/Home/Home.module.scss‎

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,6 @@
3333
letter-spacing: 1px;
3434
padding-top: 1px;
3535
}
36-
37-
&__settings {
38-
display: flex;
39-
align-items: center;
40-
justify-content: center;
41-
gap: 4px;
42-
cursor: pointer;
43-
text-decoration: none;
44-
background: none;
45-
border: none;
46-
border-radius: 5px;
47-
padding: 1px 0 1px 5px;
48-
49-
&:hover {
50-
background-color: var(--vscode-toolbar-hoverBackground);
51-
}
52-
53-
&__icon-wrapper {
54-
display: flex;
55-
align-items: center;
56-
justify-content: center;
57-
--size: 20px;
58-
width: var(--size);
59-
height: var(--size);
60-
color: var(--vscode-icon-foreground);
61-
}
62-
}
6336
}
6437

6538
.content {

‎apps/editor/src/views/panel/frontend/Home/Home.tsx‎

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import { Timeline } from '@ui/components/editor/panel/Timeline'
55
import { ModeButton } from '@ui/components/editor/panel/ModeButton'
66
import cn from 'classnames'
77
import { post_message } from '../utils/post_message'
8-
import { Checkpoint, FrontendMessage } from '@/views/panel/types/messages'
8+
import {
9+
Checkpoint,
10+
FrontendMessage,
11+
SetupProgress
12+
} from '@/views/panel/types/messages'
913
import { Responses as UiResponses } from '@ui/components/editor/panel/Responses'
1014
import { ResponseHistoryItem } from '@shared/types/response-history-item'
1115
import { Separator } from '@ui/components/editor/panel/Separator'
@@ -16,6 +20,7 @@ import { Tasks } from '@ui/components/editor/panel/Tasks'
1620
import { Task } from '@shared/types/task'
1721
import { use_tasks } from './hooks/use-tasks'
1822
import { use_timeline_scroll } from './hooks/use-timeline-scroll'
23+
import { SettingsButton } from '@ui/components/editor/panel/SettingsButton'
1924

2025
type Props = {
2126
vscode: any
@@ -42,6 +47,7 @@ type Props = {
4247
on_tasks_change: (root: string, tasks: Task[]) => void
4348
on_task_delete: (root: string, timestamp: number) => void
4449
on_task_forward: (text: string) => void
50+
setup_progress?: SetupProgress
4551
}
4652

4753
export const Home: React.FC<Props> = (props) => {
@@ -92,6 +98,10 @@ export const Home: React.FC<Props> = (props) => {
9298
} as FrontendMessage)
9399
}
94100

101+
const has_incomplete_setup = props.setup_progress
102+
? Object.values(props.setup_progress).some((v) => !v)
103+
: false
104+
95105
return (
96106
<>
97107
<div className={styles.header}>
@@ -101,16 +111,11 @@ export const Home: React.FC<Props> = (props) => {
101111
</div>
102112
<span className={styles['header__text']}>Home</span>
103113
</div>
104-
<button
105-
className={styles['header__settings']}
106-
onClick={handle_settings_click}
107-
title={t('panel.header.settings')}
108-
>
109-
<span>{t('panel.header.settings')}</span>
110-
<span className={styles['header__settings__icon-wrapper']}>
111-
<span className={cn('codicon', 'codicon-settings-gear')} />
112-
</span>
113-
</button>
114+
<SettingsButton
115+
on_click={handle_settings_click}
116+
label={t('panel.header.settings')}
117+
show_warning_icon={has_incomplete_setup}
118+
/>
114119
</div>
115120

116121
<Scrollable

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
ApiToolConfigurationsMessage,
1010
PresetsMessage,
1111
FrontendMessage,
12-
SelectionState
12+
SelectionState,
13+
SetupProgress
1314
} from '@/views/panel/types/messages'
1415
import { ApiToolConfiguration } from '@/views/panel/types/messages'
1516
import { post_message } from '../utils/post_message'
@@ -72,6 +73,7 @@ type Props = {
7273
is_recording: boolean
7374
on_recording_started: () => void
7475
on_recording_finished: () => void
76+
setup_progress?: SetupProgress
7577
}
7678

7779
export const Main: React.FC<Props> = (props) => {
@@ -855,6 +857,7 @@ export const Main: React.FC<Props> = (props) => {
855857
is_recording={props.is_recording}
856858
on_recording_started={props.on_recording_started}
857859
on_recording_finished={props.on_recording_finished}
860+
setup_progress={props.setup_progress}
858861
/>
859862
)
860863
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { use_last_choice_button_title } from './hooks/use-last-choice-button-tit
1616
import { ContextUtilisation as UiContextUtilisation } from '@ui/components/editor/panel/ContextUtilisation'
1717
import { Header } from './components/Header'
1818
import { use_invocation_counts } from './hooks/use-invocation-counts'
19-
import { SelectionState } from '@/views/panel/types/messages'
19+
import { SelectionState, SetupProgress } from '@/views/panel/types/messages'
2020

2121
type Props = {
2222
scroll_reset_key: number
@@ -113,6 +113,7 @@ type Props = {
113113
is_recording: boolean
114114
on_recording_started: () => void
115115
on_recording_finished: () => void
116+
setup_progress?: SetupProgress
116117
}
117118

118119
export const MainView: React.FC<Props> = (props) => {
@@ -193,6 +194,7 @@ export const MainView: React.FC<Props> = (props) => {
193194
on_api_prompt_type_change={props.on_api_prompt_type_change}
194195
on_quick_action_click={props.on_quick_action_click}
195196
are_keyboard_shortcuts_disabled={props.are_keyboard_shortcuts_disabled}
197+
setup_progress={props.setup_progress}
196198
/>
197199
<Scrollable scroll_to_top_key={props.scroll_reset_key}>
198200
<UiSeparator height={4} />

‎apps/editor/src/views/panel/frontend/Main/MainView/components/Header/Header.module.scss‎

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,5 @@
5151
width: 100%;
5252
height: 24px;
5353
}
54-
55-
&__settings {
56-
display: flex;
57-
align-items: center;
58-
justify-content: center;
59-
flex-shrink: 0;
60-
--size: 20px;
61-
width: var(--size);
62-
height: var(--size);
63-
color: var(--vscode-icon-foreground);
64-
cursor: pointer;
65-
text-decoration: none;
66-
background: none;
67-
border: none;
68-
padding: 0;
69-
border-radius: 5px;
70-
71-
&:hover {
72-
background-color: var(--vscode-toolbar-hoverBackground);
73-
}
74-
}
7554
}
7655
}

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useRef, useCallback } from 'react'
2-
import cn from 'classnames'
32
import { MODE, Mode } from '@/views/panel/types/main-view-mode'
43
import { use_is_narrow_viewport, use_is_mac } from '@shared/hooks'
54
import { ApiPromptType, WebPromptType } from '@shared/types/prompt-types'
@@ -10,8 +9,10 @@ import {
109
api_prompt_type_labels,
1110
web_prompt_type_labels
1211
} from '../../prompt-type-labels'
12+
import { SettingsButton as UiSettingsButton } from '@ui/components/editor/panel/SettingsButton'
1313
import { use_keyboard_shortcuts } from './hooks/use-keyboard-shortcuts'
1414
import { use_translation } from '@/views/i18n/use-translation'
15+
import { SetupProgress } from '@/views/panel/types/messages'
1516

1617
type Props = {
1718
mode: Mode
@@ -23,6 +24,7 @@ type Props = {
2324
on_api_prompt_type_change: (prompt_type: ApiPromptType) => void
2425
on_quick_action_click: (command: string) => void
2526
are_keyboard_shortcuts_disabled: boolean
27+
setup_progress?: SetupProgress
2628
}
2729

2830
export const Header: React.FC<Props> = (props) => {
@@ -50,6 +52,10 @@ export const Header: React.FC<Props> = (props) => {
5052
is_disabled: props.are_keyboard_shortcuts_disabled
5153
})
5254

55+
const has_incomplete_setup = props.setup_progress
56+
? Object.values(props.setup_progress).some((v) => !v)
57+
: false
58+
5359
return (
5460
<div className={styles.header} ref={header_ref}>
5561
<div className={styles.header__left} ref={header_left_ref}>
@@ -118,13 +124,11 @@ export const Header: React.FC<Props> = (props) => {
118124
)}
119125
</div>
120126

121-
<button
122-
className={styles['header__right__settings']}
123-
onClick={() => props.on_quick_action_click('codeWebChat.settings')}
127+
<UiSettingsButton
128+
on_click={() => props.on_quick_action_click('codeWebChat.settings')}
124129
title="Settings"
125-
>
126-
<span className={cn('codicon', 'codicon-settings-gear')} />
127-
</button>
130+
show_warning_icon={has_incomplete_setup}
131+
/>
128132
</div>
129133
</div>
130134
)

‎apps/editor/src/views/panel/frontend/Panel.tsx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ export const Panel = () => {
107107
handle_open_document,
108108
handle_paste_url,
109109
is_recording,
110-
handle_set_recording_state
110+
handle_set_recording_state,
111+
setup_progress
111112
} = use_panel(vscode)
112113

113114
const [checkpoint_to_edit, set_checkpoint_to_edit] = useState<
@@ -319,6 +320,7 @@ export const Panel = () => {
319320
is_recording={is_recording}
320321
on_recording_started={() => handle_set_recording_state(true)}
321322
on_recording_finished={() => handle_set_recording_state(false)}
323+
setup_progress={setup_progress}
322324
/>
323325
</div>
324326
<div
@@ -396,6 +398,7 @@ export const Panel = () => {
396398
on_tasks_change={handle_tasks_change}
397399
on_task_delete={handle_task_delete}
398400
on_task_forward={handle_task_forward}
401+
setup_progress={setup_progress}
399402
/>
400403
</div>
401404
</Layout>

‎apps/editor/src/views/panel/frontend/hooks/use-panel.ts‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { Preset } from '@shared/types/preset'
33
import {
44
BackendMessage,
55
FrontendMessage,
6-
SelectionState
6+
SelectionState,
7+
SetupProgress
78
} from '../../types/messages'
89
import { Checkpoint } from '../../types/messages'
910
import { Mode, MODE } from '../../types/main-view-mode'
@@ -115,6 +116,7 @@ export const use_panel = (vscode: any) => {
115116
] = useState<string>('')
116117
const [fix_all_automatically, set_fix_all_automatically] = useState(false)
117118
const [is_recording, set_is_recording] = useState(false)
119+
const [setup_progress, set_setup_progress] = useState<SetupProgress>()
118120

119121
const handle_instructions_change = (
120122
value: string,
@@ -393,6 +395,8 @@ export const use_panel = (vscode: any) => {
393395
set_prune_context_instructions_prefix(message.prefix)
394396
} else if (message.command == 'RECORDING_STATE') {
395397
set_is_recording(message.is_recording)
398+
} else if (message.command == 'SETUP_PROGRESS') {
399+
set_setup_progress(message.setup_progress)
396400
}
397401
}
398402
window.addEventListener('message', handle_message)
@@ -415,7 +419,8 @@ export const use_panel = (vscode: any) => {
415419
{ command: 'REQUEST_CURRENTLY_OPEN_FILE_TEXT' },
416420
{ command: 'REQUEST_CAN_UNDO' },
417421
{ command: 'GET_TASKS' },
418-
{ command: 'GET_PRUNE_CONTEXT_INSTRUCTIONS_PREFIX' }
422+
{ command: 'GET_PRUNE_CONTEXT_INSTRUCTIONS_PREFIX' },
423+
{ command: 'GET_SETUP_PROGRESS' }
419424
]
420425
initial_messages.forEach((message) => post_message(vscode, message))
421426

@@ -629,6 +634,7 @@ export const use_panel = (vscode: any) => {
629634
handle_open_document,
630635
handle_paste_url,
631636
is_recording,
632-
handle_set_recording_state
637+
handle_set_recording_state,
638+
setup_progress
633639
}
634640
}

0 commit comments

Comments
 (0)