-
Notifications
You must be signed in to change notification settings - Fork 627
feat(settings): ui optimize #999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughRefactors multiple settings UI components: header click-to-toggle behavior, padding/layout shifts, dialog and button conversions, MCP settings and marketplace rework, prompt and shortcut UI redesigns, shared Textarea tweak, and a trailing JSON syntax fix in Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant H as Knowledge Header
participant P as Panel (Collapsible)
participant R as Router
U->>H: Click header container
H->>P: toggle isOpen
Note over R,H: Dify only
R-->>H: route subtab == "dify"
H->>P: open
sequenceDiagram
participant U as User
participant M as MCP Settings
participant A as Advanced Collapsible
participant D as Custom Source Dialog
participant N as Registry Service
U->>M: Toggle MCP enable
U->>A: Expand advanced
U->>M: Refresh registry
M->>N: fetch registry
N-->>M: registry info
U->>D: Open custom source
U->>D: Save / Clear / Redetect
D->>N: apply/clear/detect
N-->>D: result
D->>M: Close and update UI
sequenceDiagram
participant U as User
participant DS as Data Settings
participant ID as Import Dialog
participant S as Store/Importer
U->>DS: Click "导入数据"
DS->>ID: open import dialog
U->>ID: choose mode + confirm
ID->>S: trigger import(mode)
S-->>DS: import result
DS->>U: show status
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@codex review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting
| <!-- 导入数据 --> | ||
| <Dialog v-model:open="isImportDialogOpen"> | ||
| <DialogTrigger as-child> | ||
| <Button | ||
| variant="outline" | ||
| @click="syncStore.startBackup" | ||
| :disabled="!syncStore.syncEnabled" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import dialog button triggers backup instead of only opening dialog
The new import button calls syncStore.startBackup even though it is already wrapped in a DialogTrigger. Clicking “Import Data” now launches a backup immediately before the user confirms the import, which is unrelated and can block the import flow (e.g. the button is disabled while a backup runs). The handler should only open the dialog and let the user choose how to import.
Useful? React with 👍 / 👎.
| <Button | ||
| variant="destructive" | ||
| class="w-48" | ||
| @click="syncStore.startBackup" | ||
| :disabled="!syncStore.syncEnabled || syncStore.isBackingUp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reset data trigger erroneously launches backup
The trigger button that opens the reset confirmation dialog now calls syncStore.startBackup. As a result, clicking “Reset Data” starts a backup and may disable the reset controls (isBackingUp), preventing the user from proceeding with the intended reset. The trigger should not perform backup operations; it should simply open the confirmation dialog.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (11)
src/renderer/settings/components/RagflowKnowledgeSettings.vue (1)
21-25: Consider click event propagation on the Switch.The Switch is inside a clickable header area. Clicking the switch will both toggle the switch AND trigger the header's panel toggle, which may not be the intended behavior.
Add
@click.stopto the Switch's wrapper to prevent event bubbling:- <Switch + <Switch + @click.stop :model-value="isRagflowMcpEnabled" :disabled="!mcpStore.mcpEnabled" @update:model-value="toggleRagflowMcpServer" />Alternatively, wrap the Switch in a div with
@click.stop:+ <div @click.stop> <Switch :model-value="isRagflowMcpEnabled" :disabled="!mcpStore.mcpEnabled" @update:model-value="toggleRagflowMcpServer" /> + </div>src/renderer/settings/components/FastGptKnowledgeSettings.vue (2)
52-54: Inconsistent Switch API usage.This Switch uses
:checkedwith@update:checked, while the Switch at lines 21-25 uses:model-valuewith@update:model-value. Use consistent API across the component.Apply this diff to standardize on
model-value:<Switch - :checked="config.enabled === true" + :model-value="config.enabled === true" size="sm" - @update:checked="toggleConfigEnabled(index, $event)" + @update:model-value="toggleConfigEnabled(index, $event)" />
21-25: Consider click event propagation on the Switch.The Switch is inside a clickable header. Clicking it will trigger both the switch toggle AND the header's panel toggle.
Wrap the Switch or its TooltipProvider in a div with
@click.stopto prevent event bubbling:+ <div @click.stop> <TooltipProvider> <Tooltip :delay-duration="200"> <TooltipTrigger> <Switch :model-value="isFastGptMcpEnabled" :disabled="!mcpStore.mcpEnabled" @update:model-value="toggleFastGptMcpServer" /> </TooltipTrigger> <TooltipContent v-if="!mcpStore.mcpEnabled"> <p>{{ t('settings.mcp.enableToAccess') }}</p> </TooltipContent> </Tooltip> </TooltipProvider> + </div>src/renderer/settings/components/DifyKnowledgeSettings.vue (2)
237-239: Move import to the top of the script section.The
useRouteimport is placed after other imports and code, violating typical import organization conventions. All imports should be at the top of the script section.Move the import to line 208 (after other imports):
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@shadcn/components/ui/tooltip' +import { useRoute } from 'vue-router' // 对话框状态 const isDifyConfigDialogOpen = ref(false) // ... rest of code ... const { t } = useI18n() const mcpStore = useMcpStore() const { toast } = useToast() +const route = useRoute() // 对话框状态 const isDifyConfigPanelOpen = ref(false) const isEditing = ref(false) -import { useRoute } from 'vue-router' - -const route = useRoute()
21-25: Consider click event propagation on the Switch.The Switch inside the clickable header may trigger both the switch toggle and the header's panel toggle when clicked.
Wrap the TooltipProvider in a div with
@click.stopto prevent event bubbling:+ <div @click.stop> <TooltipProvider> <Tooltip :delay-duration="200"> <TooltipTrigger> <Switch :model-value="isDifyMcpEnabled" :disabled="!mcpStore.mcpEnabled" @update:model-value="toggleDifyMcpServer" /> </TooltipTrigger> <TooltipContent v-if="!mcpStore.mcpEnabled"> <p>{{ t('settings.mcp.enableToAccess') }}</p> </TooltipContent> </Tooltip> </TooltipProvider> + </div>src/renderer/settings/components/BuiltinKnowledgeSettings.vue (1)
23-27: Consider click event propagation on the Switch.The Switch inside the clickable header may trigger both the switch toggle and the header's panel toggle when clicked.
Wrap the TooltipProvider in a div with
@click.stop:+ <div @click.stop> <TooltipProvider> <Tooltip :delay-duration="200"> <TooltipTrigger> <Switch :model-value="isBuiltinMcpEnabled" :disabled="!mcpStore.mcpEnabled" @update:model-value="toggleBuiltinMcpServer" /> </TooltipTrigger> <TooltipContent v-if="!mcpStore.mcpEnabled"> <p>{{ t('settings.mcp.enableToAccess') }}</p> </TooltipContent> </Tooltip> </TooltipProvider> + </div>src/renderer/settings/components/PromptSetting.vue (1)
286-314: Fix template parse error: unexpected (breaks CI)CI reports an unexpected closing tag at Line 312. To unblock, replace the inner ScrollArea with a simple container (keeps scrolling via overflow-y) or ensure proper pairing. This minimal patch removes the offending closing tag.
Apply this diff:
- <ScrollArea class="flex-1 overflow-hidden"> + <div class="flex-1 overflow-y-auto"> <div class="px-6 py-4 space-y-4"> <!-- 名称 --> <div class="space-y-2"> <Label for="system-prompt-name" class="text-sm font-medium">{{ t('promptSetting.name') }}</Label> <Input id="system-prompt-name" v-model="systemPromptForm.name" :placeholder="t('promptSetting.namePlaceholder')" /> </div> <!-- 内容 --> <div class="space-y-2"> <Label for="system-prompt-content" class="text-sm font-medium">{{ t('promptSetting.promptContent') }}</Label> <Textarea id="system-prompt-content" v-model="systemPromptForm.content" class="w-full h-64" :placeholder="t('promptSetting.contentPlaceholder')" ></Textarea> </div> - </ScrollArea> + </div>If you prefer to keep ScrollArea styling, reintroduce it after fixing the tag pairing locally and re-run formatting to verify the parser accepts it.
src/renderer/settings/components/DisplaySettings.vue (1)
408-411: Type the computed setter parameter (strict TS).Avoid implicit any on
value.-const fontSizeLevel = computed({ - get: () => settingsStore.fontSizeLevel, - set: (value) => settingsStore.updateFontSizeLevel(value) -}) +const fontSizeLevel = computed<number>({ + get: () => settingsStore.fontSizeLevel, + set: (value: number) => settingsStore.updateFontSizeLevel(value) +})src/renderer/settings/components/CommonSettings.vue (3)
16-18: Invalid height utility:h-8!should be!h-8orh-8.Current class won’t take effect.
- <SelectTrigger class="px-3 h-8! text-sm border-border hover:bg-accent"> + <SelectTrigger class="px-3 !h-8 text-sm border-border hover:bg-accent">
165-167: Invalid height utility here as well.Fix the height utility for consistency.
- <SelectTrigger class="h-8! text-sm border-border hover:bg-accent"> + <SelectTrigger class="!h-8 text-sm border-border hover:bg-accent">
176-198: UI clipping risk: multi-line content constrained byh-10.The custom proxy block contains an input and an error row;
h-10will clip or overlap content. Remove fixed height on multi-line containers.- <div v-if="selectedProxyMode === 'custom'" class="flex flex-col gap-2 h-10"> + <div v-if="selectedProxyMode === 'custom'" class="flex flex-col gap-2">
🧹 Nitpick comments (10)
src/renderer/settings/components/PromptSetting.vue (2)
410-416: Use the shared Textarea component for consistencyReplace the native <textarea> with the shadcn Textarea (already imported) to keep styles/behaviors consistent across the app.
Apply this diff:
- <div> - <textarea - v-model="form.content" - class="w-full min-h-48 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 font-mono resize-y" - :placeholder="t('promptSetting.contentPlaceholder')" - ></textarea> + <div> + <Textarea + v-model="form.content" + class="w-full min-h-48 font-mono resize-y" + :placeholder="t('promptSetting.contentPlaceholder')" + /> <p class="text-xs text-muted-foreground mt-2"> {{ t('promptSetting.contentTip', { openBrace: '{', closeBrace: '}' }) }} </p> </div>
22-27: Use English for comments in TS/Vue filesSeveral template comments are Chinese. Please switch comments to English to match repo guidelines.
As per coding guidelines
Also applies to: 48-50, 300-304
src/renderer/settings/components/DisplaySettings.vue (1)
425-429: Logs should be in English.Guideline: use English for logs/comments. Replace the Chinese log.
[coding_guidelines]- console.log('准备切换投屏保护状态:', value) + console.log('Preparing to toggle content protection:', value)src/renderer/settings/components/CommonSettings.vue (2)
70-113: Minor UI consistency: control heights differ.Minus button is h-8, plus button is h-7. Align for consistent tap targets.
- <Button + <Button variant="outline" size="icon" - class="h-8 w-8" + class="h-8 w-8" @click="decreaseWebContentLimit" :disabled="webContentLengthLimit <= 0" > <Icon icon="lucide:minus" class="h-3 w-3" /> </Button> ... - <Button + <Button variant="outline" size="icon" - class="h-7 w-7" + class="h-8 w-8" @click="increaseWebContentLimit" :disabled="webContentLengthLimit >= 10000" >
428-864: Use English for logs and comments.Several logs and comments are in Chinese (e.g., Lines 538, 608, 678, 710, 749, 771). Convert to English to follow project guidelines.
[coding_guidelines]src/renderer/settings/components/McpSettings.vue (4)
217-236: Registry refresh UX: disable trigger and show progress.You already guard with
refreshing; good. Consider also addingaria-busyand a toast only on change to reduce noise.
258-304: Registry validation via HEAD may be unreliable; test endpoint/package choice.
- Many registries don’t support HEAD on package metadata; GET with small response is more robust.
- Using a niche package (
tiny-runtime-injector) risks 404s on mirrors. Prefer ubiquitous packages (e.g.,react,lodash) or a ping endpoint (/-/ping) if supported.- const testPackage = 'tiny-runtime-injector' - const testUrl = `${normalizedRegistry}${testPackage}` + const testPackage = 'react' // ubiquitous package + const testUrl = `${normalizedRegistry}${testPackage}` - const response = await fetch(testUrl, { - method: 'HEAD', + const response = await fetch(testUrl, { + method: 'GET', + headers: { accept: 'application/json' }, signal: AbortSignal.timeout(10000) })Also confirm your runtime supports
AbortSignal.timeout; if not, polyfill withAbortControllerand manual timeout.
318-327: Normalize and persist normalized registry value.After
setCustomNpmRegistry, ensure the stored value has trailing slash to avoid duplicates.- await mcpStore.setCustomNpmRegistry(registry) + await mcpStore.setCustomNpmRegistry(normalizeNpmRegistryUrl(registry))
354-364: Dialog close duplication.
customSourceDialogOpen.value = falseappears in both try and catch; move after the try/catch to DRY.- customSourceDialogOpen.value = false } catch (detectError) { ... - customSourceDialogOpen.value = false } + customSourceDialogOpen.value = falsesrc/renderer/settings/components/DataSettings.vue (1)
240-344: Use English for logs.E.g.,
console.error('重置数据失败:', error)should be English.
[coding_guidelines]- console.error('重置数据失败:', error) + console.error('Failed to reset data:', error)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
resources/model-db/providers.json(1 hunks)src/renderer/settings/components/BuiltinKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/CommonSettings.vue(9 hunks)src/renderer/settings/components/DataSettings.vue(3 hunks)src/renderer/settings/components/DifyKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/DisplaySettings.vue(2 hunks)src/renderer/settings/components/FastGptKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/KnowledgeBaseSettings.vue(1 hunks)src/renderer/settings/components/McpBuiltinMarket.vue(5 hunks)src/renderer/settings/components/McpSettings.vue(5 hunks)src/renderer/settings/components/PromptSetting.vue(8 hunks)src/renderer/settings/components/RagflowKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/ShortcutSettings.vue(2 hunks)src/renderer/src/components/mcp-config/components/McpServerCard.vue(3 hunks)src/renderer/src/components/mcp-config/components/McpServers.vue(2 hunks)src/shadcn/components/ui/textarea/Textarea.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (17)
src/renderer/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/**/*.{vue,ts,js,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
渲染进程代码放在
src/renderer
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**/*.vue
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
Use scoped styles to prevent CSS conflicts between components
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
src/renderer/**/*.{vue,ts}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Implement lazy loading for routes and components.
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.Use Pinia for frontend state management (do not introduce alternative state libraries)
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for all logs and comments
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)
Use PascalCase for TypeScript types and classes
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
src/renderer/{src,shell,floating}/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/components/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Organize UI components by feature within src/renderer/src/
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**
📄 CodeRabbit inference engine (AGENTS.md)
Place Vue 3 app source under src/renderer/src (components, stores, views, i18n, lib)
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**/*.{vue,ts}
📄 CodeRabbit inference engine (AGENTS.md)
All user-facing strings must use vue-i18n ($t/keys) rather than hardcoded literals
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
Prettier style: single quotes, no semicolons, print width 100; run pnpm run format
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vueresources/model-db/providers.jsonsrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Name Vue component files in PascalCase (e.g., ChatInput.vue)
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vue
{build,resources,out,dist}/**
📄 CodeRabbit inference engine (AGENTS.md)
Treat build outputs and assets (build/, resources/, out/, dist/) as generated artifacts; do not hand-edit
Files:
resources/model-db/providers.json
🧠 Learnings (1)
📚 Learning: 2025-07-23T00:45:57.322Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-07-23T00:45:57.322Z
Learning: Applies to src/renderer/**/*.{vue} : Import Icon component from Iconify/Vue.
Applied to files:
src/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/McpSettings.vue
🪛 GitHub Actions: PR Check
src/renderer/settings/components/PromptSetting.vue
[error] 312-312: Vue template syntax error: Unexpected closing tag "ScrollArea" in PromptSetting.vue.
[error] 310-314: HTML / Vue template parse error reported during Prettier check: Unexpected closing tag may indicate a mismatched or missing opening tag.
🔇 Additional comments (9)
resources/model-db/providers.json (1)
39874-39877: Valid JSON fix applied correctly.Trailing comma removal restores proper JSON syntax; no further action needed.
src/renderer/src/components/mcp-config/components/McpServers.vue (1)
262-279: Verify 3-up layout at thesmbreakpointJumping from 1→3 columns as soon as we hit the
smbreakpoint (~640 px) shrinks eachMcpServerCardto ~200 px width. Please double-check on real content (buttons, tags, tool counts) that nothing overflows or wraps awkwardly—if it does, consider keepingsm:grid-cols-2and moving the 3rd column tomd.Also applies to: 294-313
src/renderer/settings/components/McpBuiltinMarket.vue (4)
3-13: LGTM! Clean header restructure.The refactored header with sticky positioning and stacked layout for the title and "powered by" link creates a clearer visual hierarchy. The sticky positioning at the top improves usability when scrolling through market items.
29-41: LGTM! Cleaner styling with proper separation.The simplified styling and addition of the Separator component creates a cleaner, more modern appearance while maintaining clear visual distinction between sections.
72-72: LGTM! Verify the visual appearance.The button variant change to 'outline' for non-installed servers is a reasonable UI optimization. The logic is correct and clear.
Consider verifying the visual appearance of the outline variant to ensure it provides appropriate emphasis for the install action in the context of the market cards.
127-127: LGTM! Proper component import.The Separator import is correctly added and consistent with other shadcn component imports in the file.
src/renderer/src/components/mcp-config/components/McpServerCard.vue (1)
142-142: LGTM: Card layout improvements.The switch to a vertical flex layout with card background and simplified hover effects improves visual hierarchy and aligns with the design system.
src/renderer/settings/components/KnowledgeBaseSettings.vue (1)
2-23: LGTM: Simplified layout and explicit component rendering.The refactor improves code clarity by:
- Removing the complex dialog flow for adding knowledge bases
- Explicitly rendering each knowledge settings component
- Conditionally showing BuiltinKnowledgeSettings based on system support
- Simplifying the header and spacing for better visual hierarchy
These changes make the component more maintainable and easier to understand.
src/shadcn/components/ui/textarea/Textarea.vue (1)
22-27: Textarea component usage looks correctv-model wiring via useVModel and class composition with cn are consistent; no behavior risk spotted.
| <div | ||
| class="flex items-center p-4 hover:bg-accent cursor-default" | ||
| @click="toggleBuiltinConfigPanel" | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix cursor and add accessibility attributes to clickable header.
The header div has cursor-default but is clickable. Add proper cursor style and accessibility attributes.
Apply this diff:
<div
- class="flex items-center p-4 hover:bg-accent cursor-default"
+ class="flex items-center p-4 hover:bg-accent cursor-pointer"
+ role="button"
+ tabindex="0"
@click="toggleBuiltinConfigPanel"
+ @keydown.enter="toggleBuiltinConfigPanel"
+ @keydown.space.prevent="toggleBuiltinConfigPanel"
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-default" | |
| @click="toggleBuiltinConfigPanel" | |
| > | |
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-pointer" | |
| role="button" | |
| tabindex="0" | |
| @click="toggleBuiltinConfigPanel" | |
| @keydown.enter="toggleBuiltinConfigPanel" | |
| @keydown.space.prevent="toggleBuiltinConfigPanel" | |
| > |
🤖 Prompt for AI Agents
In src/renderer/settings/components/BuiltinKnowledgeSettings.vue around lines 3
to 6, the header div is clickable but uses cursor-default and lacks
accessibility attributes; change the cursor to cursor-pointer, add
role="button", tabindex="0", and aria-expanded (bound to the panel open state)
and aria-controls (pointing to the panel ID), and wire a keyboard handler
(keydown for Enter/Space) that invokes the same toggleBuiltinConfigPanel method
so keyboard users can activate the header.
| <Input | ||
| v-model="syncFolderPath" | ||
| :disabled="!syncStore.syncEnabled" | ||
| class="cursor-pointer h-8!" | ||
| @click="syncStore.selectSyncFolder" | ||
| /> | ||
| <Button |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid height utility: h-8! on Input.
Use !h-8 or h-8.
- <Input
+ <Input
v-model="syncFolderPath"
:disabled="!syncStore.syncEnabled"
- class="cursor-pointer h-8!"
+ class="cursor-pointer !h-8"
@click="syncStore.selectSyncFolder"
/>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Input | |
| v-model="syncFolderPath" | |
| :disabled="!syncStore.syncEnabled" | |
| class="cursor-pointer h-8!" | |
| @click="syncStore.selectSyncFolder" | |
| /> | |
| <Button | |
| <Input | |
| v-model="syncFolderPath" | |
| :disabled="!syncStore.syncEnabled" | |
| class="cursor-pointer !h-8" | |
| @click="syncStore.selectSyncFolder" | |
| /> | |
| <Button |
🤖 Prompt for AI Agents
In src/renderer/settings/components/DataSettings.vue around lines 25 to 31, the
Input component uses an invalid Tailwind utility class "h-8!"; replace it with a
valid class like "!h-8" (to force-important) or just "h-8" depending on whether
you need to override other styles, i.e. update the class attribute to use one of
those valid utilities.
| <div | ||
| class="flex items-center p-4 hover:bg-accent cursor-default" | ||
| @click="toggleDifyConfigPanel" | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix cursor and add accessibility attributes to clickable header.
The header div has cursor-default but is clickable. Add proper cursor style and accessibility attributes.
Apply this diff:
<div
- class="flex items-center p-4 hover:bg-accent cursor-default"
+ class="flex items-center p-4 hover:bg-accent cursor-pointer"
+ role="button"
+ tabindex="0"
@click="toggleDifyConfigPanel"
+ @keydown.enter="toggleDifyConfigPanel"
+ @keydown.space.prevent="toggleDifyConfigPanel"
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-default" | |
| @click="toggleDifyConfigPanel" | |
| > | |
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-pointer" | |
| role="button" | |
| tabindex="0" | |
| @click="toggleDifyConfigPanel" | |
| @keydown.enter="toggleDifyConfigPanel" | |
| @keydown.space.prevent="toggleDifyConfigPanel" | |
| > |
🤖 Prompt for AI Agents
In src/renderer/settings/components/DifyKnowledgeSettings.vue around lines 3 to
6, the header div is clickable but uses cursor-default and lacks accessibility
attributes; change the class to use cursor-pointer instead of cursor-default,
add role="button" and tabindex="0", wire keyboard activation by adding
@keydown.enter.prevent="toggleDifyConfigPanel" and
@keydown.space.prevent="toggleDifyConfigPanel", and expose the panel state via
aria-expanded (e.g. :aria-expanded="isDifyConfigPanelOpen" or the component's
equivalent boolean) so screen readers can detect the toggle state.
| <SelectTrigger class="h-8!"> | ||
| <SelectValue :placeholder="t('settings.common.languageSelect')" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid height utility: use !h-8 or h-8 instead of h-8!.
h-8! won’t be parsed by Tailwind (important modifier is prefixed as !h-8). Height won’t apply.
Apply:
- <SelectTrigger class="h-8!">
+ <SelectTrigger class="!h-8">📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <SelectTrigger class="h-8!"> | |
| <SelectValue :placeholder="t('settings.common.languageSelect')" /> | |
| <SelectTrigger class="!h-8"> | |
| <SelectValue :placeholder="t('settings.common.languageSelect')" /> |
🤖 Prompt for AI Agents
In src/renderer/settings/components/DisplaySettings.vue around lines 15 to 16,
the class "h-8!" is an invalid Tailwind utility (the important modifier must be
prefixed), so replace it with either "!h-8" if you need to force the height or
"h-8" if not; update the SelectTrigger class attribute accordingly to use the
correct utility.
| <div | ||
| class="flex items-center p-4 hover:bg-accent cursor-default" | ||
| @click="toggleFastGptConfigPanel" | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix cursor and add accessibility attributes to clickable header.
The header div has cursor-default but is clickable. This provides poor UX and lacks proper accessibility attributes for keyboard navigation.
Apply this diff:
<div
- class="flex items-center p-4 hover:bg-accent cursor-default"
+ class="flex items-center p-4 hover:bg-accent cursor-pointer"
+ role="button"
+ tabindex="0"
@click="toggleFastGptConfigPanel"
+ @keydown.enter="toggleFastGptConfigPanel"
+ @keydown.space.prevent="toggleFastGptConfigPanel"
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-default" | |
| @click="toggleFastGptConfigPanel" | |
| > | |
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-pointer" | |
| role="button" | |
| tabindex="0" | |
| @click="toggleFastGptConfigPanel" | |
| @keydown.enter="toggleFastGptConfigPanel" | |
| @keydown.space.prevent="toggleFastGptConfigPanel" | |
| > |
🤖 Prompt for AI Agents
In src/renderer/settings/components/FastGptKnowledgeSettings.vue around lines 3
to 6, the header div is clickable but uses cursor-default and lacks
keyboard/accessibility attributes; change cursor-default to cursor-pointer, add
role="button" and tabindex="0", add key handlers for Enter and Space (e.g.,
@keydown.enter="toggleFastGptConfigPanel" and
@keydown.space.prevent="toggleFastGptConfigPanel"), and add an aria-expanded
attribute bound to the boolean state that controls the panel (use the existing
panel-open/computed ref or create one) so screen readers and keyboard users can
discover and operate the toggle.
| <div | ||
| class="flex items-center p-4 hover:bg-accent cursor-default" | ||
| @click="toggleRagflowConfigPanel" | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix cursor and add accessibility attributes to clickable header.
The header div has cursor-default but is clickable via @click. This provides poor UX as users won't see a pointer cursor. Additionally, the clickable div lacks proper accessibility attributes.
Apply this diff to fix the cursor style and add accessibility:
<div
- class="flex items-center p-4 hover:bg-accent cursor-default"
+ class="flex items-center p-4 hover:bg-accent cursor-pointer"
+ role="button"
+ tabindex="0"
@click="toggleRagflowConfigPanel"
+ @keydown.enter="toggleRagflowConfigPanel"
+ @keydown.space.prevent="toggleRagflowConfigPanel"
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-default" | |
| @click="toggleRagflowConfigPanel" | |
| > | |
| <div | |
| class="flex items-center p-4 hover:bg-accent cursor-pointer" | |
| role="button" | |
| tabindex="0" | |
| @click="toggleRagflowConfigPanel" | |
| @keydown.enter="toggleRagflowConfigPanel" | |
| @keydown.space.prevent="toggleRagflowConfigPanel" | |
| > |
🤖 Prompt for AI Agents
In src/renderer/settings/components/RagflowKnowledgeSettings.vue around lines 3
to 6, the header div is clickable but uses cursor-default and has no
accessibility attributes; change the class to use cursor-pointer, add
tabindex="0" and role="button", wire keyboard activation by handling Enter and
Space keydown to call the same toggleRagflowConfigPanel handler, and add ARIA
attributes such as :aria-expanded="isRagflowConfigOpen" and
aria-controls="<id-of-panel>" (replace with the panel's id) so screen readers
and keyboard users can recognize and interact with the control.
| <div | ||
| v-if="recordingShortcutId === shortcut.id" | ||
| class="mt-1 text-xs" | ||
| :class="shortcutError ? 'text-destructive' : 'text-muted-foreground'" | ||
| class="ml-auto flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100" | ||
| :class="{ 'opacity-100': recordingShortcutId === shortcut.id }" | ||
| > |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore keyboard-visible controls for edit/clear buttons.
Hiding the action group with opacity-0 and only revealing it on group-hover makes the buttons stay invisible when focused via keyboard, so users tabbing into the control never see what they’re on. Please add group-focus-within:opacity-100 (or equivalent) so focus also reveals the actions.
- <div
- class="ml-auto flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100"
+ <div
+ class="ml-auto flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <div | |
| v-if="recordingShortcutId === shortcut.id" | |
| class="mt-1 text-xs" | |
| :class="shortcutError ? 'text-destructive' : 'text-muted-foreground'" | |
| class="ml-auto flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100" | |
| :class="{ 'opacity-100': recordingShortcutId === shortcut.id }" | |
| > | |
| <div | |
| class="ml-auto flex items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100" | |
| :class="{ 'opacity-100': recordingShortcutId === shortcut.id }" | |
| > |
🤖 Prompt for AI Agents
In src/renderer/settings/components/ShortcutSettings.vue around lines 57 to 60,
the action button group is hidden with opacity-0 and only shown on hover, which
prevents keyboard-focused users from seeing the controls; update the class list
to also reveal the group when focused by keyboard (e.g., add
group-focus-within:opacity-100 or the equivalent focus-related Tailwind class)
so that tabbing into the control toggles opacity to 100 and keyboard users can
access the edit/clear buttons.
| <p | ||
| ref="descriptionRef" | ||
| class="text-xs text-secondary-foreground cursor-pointer overflow-hidden leading-5 break-all mb-2" | ||
| :class="[ | ||
| !isDescriptionExpanded ? 'line-clamp-1' : '', | ||
| needsExpansion ? 'hover:text-foreground transition-colors' : '' | ||
| ]" | ||
| style="min-height: 1rem" | ||
| @click="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)" | ||
| > | ||
| {{ fullDescription }} | ||
| </p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add accessibility attributes to clickable description.
The description paragraph is clickable when needsExpansion is true, but it lacks proper accessibility attributes for keyboard navigation and screen readers.
Apply this diff:
<p
ref="descriptionRef"
class="text-xs text-secondary-foreground cursor-pointer overflow-hidden leading-5 break-all mb-2"
:class="[
!isDescriptionExpanded ? 'line-clamp-1' : '',
needsExpansion ? 'hover:text-foreground transition-colors' : ''
]"
style="min-height: 1rem"
+ :role="needsExpansion ? 'button' : undefined"
+ :tabindex="needsExpansion ? 0 : undefined"
+ :aria-expanded="needsExpansion ? isDescriptionExpanded : undefined"
@click="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)"
+ @keydown.enter="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)"
+ @keydown.space.prevent="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)"
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <p | |
| ref="descriptionRef" | |
| class="text-xs text-secondary-foreground cursor-pointer overflow-hidden leading-5 break-all mb-2" | |
| :class="[ | |
| !isDescriptionExpanded ? 'line-clamp-1' : '', | |
| needsExpansion ? 'hover:text-foreground transition-colors' : '' | |
| ]" | |
| style="min-height: 1rem" | |
| @click="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)" | |
| > | |
| {{ fullDescription }} | |
| </p> | |
| <p | |
| ref="descriptionRef" | |
| class="text-xs text-secondary-foreground cursor-pointer overflow-hidden leading-5 break-all mb-2" | |
| :class="[ | |
| !isDescriptionExpanded ? 'line-clamp-1' : '', | |
| needsExpansion ? 'hover:text-foreground transition-colors' : '' | |
| ]" | |
| style="min-height: 1rem" | |
| :role="needsExpansion ? 'button' : undefined" | |
| :tabindex="needsExpansion ? 0 : undefined" | |
| :aria-expanded="needsExpansion ? isDescriptionExpanded : undefined" | |
| @click="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)" | |
| @keydown.enter="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)" | |
| @keydown.space.prevent="needsExpansion && (isDescriptionExpanded = !isDescriptionExpanded)" | |
| > | |
| {{ fullDescription }} | |
| </p> |
🤖 Prompt for AI Agents
In src/renderer/src/components/mcp-config/components/McpServerCard.vue around
lines 198 to 209, the description <p> is clickable when needsExpansion is true
but lacks accessibility attributes and keyboard handlers; add role="button" and
tabindex="0" when needsExpansion is true, set aria-expanded to the boolean
isDescriptionExpanded, add an @keydown handler (or specific @keydown.enter and
@keydown.space) that toggles isDescriptionExpanded when needsExpansion is true
(and preventDefault for Space), and include a concise aria-label or
aria-labelledby so screen readers know this control expands/collapses the
description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (5)
src/renderer/settings/components/DifyKnowledgeSettings.vue (1)
237-237: Move import to the top of the script section.The
useRouteimport is placed after other code (line 237). According to coding guidelines and best practices, all imports should be grouped at the top of the script section for better readability and consistency.Apply this diff to move the import:
import { useToast } from '@/components/use-toast' import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@shadcn/components/ui/tooltip' +import { useRoute } from 'vue-router' // 对话框状态 const isDifyConfigDialogOpen = ref(false) ... const { t } = useI18n() const mcpStore = useMcpStore() const { toast } = useToast() +const route = useRoute() // 对话框状态 const isDifyConfigPanelOpen = ref(false) const isEditing = ref(false) -import { useRoute } from 'vue-router' - -const route = useRoute()src/renderer/settings/components/FastGptKnowledgeSettings.vue (1)
3-36: Stop propagation on the FastGPT switch.
In src/renderer/settings/components/FastGptKnowledgeSettings.vue, add@click.stopto the<Switch>so toggling the MCP server won’t also triggertoggleFastGptConfigPanel.src/renderer/settings/components/CommonSettings.vue (1)
16-18: Replaceh-8!with a valid Tailwind class.
h-8!never matches Tailwind output, so both SelectTriggers render at default height. Swap to!h-8(orh-8) to restore sizing.Also applies to: 165-169
src/renderer/settings/components/PromptSetting.vue (2)
1222-1237: Localizable text: replace hardcoded strings with i18n keysToast descriptions contain hardcoded text ('错误:', '文件读取失败'). All user-facing strings must use vue-i18n.
Apply this diff (adjust keys to match your i18n schema):
- toast({ - title: t('promptSetting.importFailed'), - description: `错误: ${errorMessage}`, - variant: 'destructive' - }) + toast({ + title: t('promptSetting.importFailed'), + description: t('promptSetting.importErrorWithMessage', { message: errorMessage }), + variant: 'destructive' + })- toast({ - title: t('promptSetting.importFailed'), - description: '文件读取失败', - variant: 'destructive' - }) + toast({ + title: t('promptSetting.importFailed'), + description: t('promptSetting.fileReadFailed'), + variant: 'destructive' + })As per coding guidelines
976-982: Fix non-reactive Set mutations (expand/collapse not updating UI reliably)Mutating a Set inside a ref doesn’t trigger reactivity. Reassign a new Set after mutation.
Apply this diff:
-const toggleShowMore = (promptId: string) => { - if (expandedPrompts.value.has(promptId)) { - expandedPrompts.value.delete(promptId) - } else { - expandedPrompts.value.add(promptId) - } -} +const toggleShowMore = (promptId: string) => { + const next = new Set(expandedPrompts.value) + next.has(promptId) ? next.delete(promptId) : next.add(promptId) + expandedPrompts.value = next +}
♻️ Duplicate comments (5)
src/renderer/settings/components/BuiltinKnowledgeSettings.vue (1)
3-38: Same event propagation concern as FastGptKnowledgeSettings.vue.This component has the same pattern where interactive children (Switch on lines 23-27) are inside a clickable header container. The review comment on FastGptKnowledgeSettings.vue applies here as well.
src/renderer/settings/components/DifyKnowledgeSettings.vue (1)
3-36: Same event propagation concern as FastGptKnowledgeSettings.vue.This component has the same pattern where interactive children (Switch on lines 21-25) are inside a clickable header container. The review comment on FastGptKnowledgeSettings.vue applies here as well.
src/renderer/settings/components/RagflowKnowledgeSettings.vue (1)
3-36: Same event propagation concern as FastGptKnowledgeSettings.vue.This component has the same pattern where interactive children (Switch on lines 21-25) are inside a clickable header container. The review comment on FastGptKnowledgeSettings.vue applies here as well.
src/renderer/settings/components/DataSettings.vue (2)
73-81: Remove backup side effect from import trigger.Clicking the import trigger still fires
syncStore.startBackup, so the user is forced into a backup before the dialog even opens—exactly the regression called out earlier. Drop that handler; let the dialog drive backup/import flow.
125-133: Don’t launch backup when opening the reset dialog.The reset trigger again invokes
syncStore.startBackup, which blocks the confirmation flow (isBackingUp) and repeats the previously flagged bug. The trigger must only open the dialog.
🧹 Nitpick comments (4)
src/renderer/settings/components/McpBuiltinMarket.vue (1)
40-40: LGTM! Proper Separator usage enhances visual hierarchy.The Separator component is correctly imported and used to provide clear visual separation between the help text and content sections.
Optional: Consider grouping UI component imports together for better organization:
import { Button } from '@shadcn/components/ui/button' import { Input } from '@shadcn/components/ui/input' +import { Separator } from '@shadcn/components/ui/separator' import { usePresenter } from '@/composables/usePresenter' import { useToast } from '@/components/use-toast' -import { Separator } from '@shadcn/components/ui/separator'Also applies to: 127-127
src/renderer/settings/components/PromptSetting.vue (2)
411-417: Unify editors: replace raw textarea with shared Textarea componentFor consistency and styling parity, use the shared Textarea here as elsewhere in this file.
Apply this diff:
- <div> - <textarea - v-model="form.content" - class="w-full min-h-48 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 font-mono resize-y" - :placeholder="t('promptSetting.contentPlaceholder')" - ></textarea> + <div> + <Textarea + v-model="form.content" + class="w-full min-h-48 font-mono resize-y" + :placeholder="t('promptSetting.contentPlaceholder')" + ></Textarea>As per coding guidelines
4-4: Comments language consistencyInline comments are in Chinese. The repo guidelines require English for all logs and comments in Vue/TS files. Consider updating comments in this component for consistency.
As per coding guidelines
Also applies to: 48-49, 422-423, 508-510, 594-599
src/renderer/settings/components/McpSettings.vue (1)
267-304: Improve custom registry validation robustness (HEAD→GET fallback + clearer errors)Some registries/CORS proxies reject HEAD. Fall back to GET if HEAD fails or returns a non-OK status.
Apply this diff:
- const response = await fetch(testUrl, { - method: 'HEAD', - signal: AbortSignal.timeout(10000) - }) - if (!response.ok) { - throw new Error(`HTTP ${response.status}`) - } - return true + const controller = new AbortController() + const signal = AbortSignal.timeout(10000) + let response: Response | null = null + try { + response = await fetch(testUrl, { method: 'HEAD', signal }) + } catch {} + if (!response || !response.ok) { + // Fallback to GET (some registries do not support HEAD or block it via CORS) + response = await fetch(testUrl, { + method: 'GET', + headers: { accept: 'application/json' }, + signal + }) + if (!response.ok) throw new Error(`HTTP ${response.status}`) + } + return true
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
resources/model-db/providers.json(1 hunks)src/renderer/settings/components/BuiltinKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/CommonSettings.vue(9 hunks)src/renderer/settings/components/DataSettings.vue(3 hunks)src/renderer/settings/components/DifyKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/DisplaySettings.vue(2 hunks)src/renderer/settings/components/FastGptKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/KnowledgeBaseSettings.vue(1 hunks)src/renderer/settings/components/McpBuiltinMarket.vue(5 hunks)src/renderer/settings/components/McpSettings.vue(5 hunks)src/renderer/settings/components/PromptSetting.vue(8 hunks)src/renderer/settings/components/RagflowKnowledgeSettings.vue(2 hunks)src/renderer/settings/components/ShortcutSettings.vue(2 hunks)src/renderer/src/components/mcp-config/components/McpServerCard.vue(3 hunks)src/renderer/src/components/mcp-config/components/McpServers.vue(2 hunks)src/shadcn/components/ui/textarea/Textarea.vue(1 hunks)
🧰 Additional context used
📓 Path-based instructions (17)
src/renderer/**/*.{vue,ts,js,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
渲染进程代码放在
src/renderer
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
src/renderer/**/*.{vue,ts}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Implement lazy loading for routes and components.
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.Use Pinia for frontend state management (do not introduce alternative state libraries)
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for all logs and comments
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)
Use PascalCase for TypeScript types and classes
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
Prettier style: single quotes, no semicolons, print width 100; run pnpm run format
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vueresources/model-db/providers.jsonsrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/shadcn/components/ui/textarea/Textarea.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Name Vue component files in PascalCase (e.g., ChatInput.vue)
Files:
src/renderer/settings/components/BuiltinKnowledgeSettings.vuesrc/renderer/settings/components/RagflowKnowledgeSettings.vuesrc/renderer/settings/components/FastGptKnowledgeSettings.vuesrc/renderer/settings/components/CommonSettings.vuesrc/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vuesrc/renderer/settings/components/DisplaySettings.vuesrc/renderer/settings/components/DifyKnowledgeSettings.vuesrc/renderer/settings/components/McpBuiltinMarket.vuesrc/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/McpSettings.vuesrc/renderer/settings/components/PromptSetting.vuesrc/renderer/settings/components/ShortcutSettings.vue
{build,resources,out,dist}/**
📄 CodeRabbit inference engine (AGENTS.md)
Treat build outputs and assets (build/, resources/, out/, dist/) as generated artifacts; do not hand-edit
Files:
resources/model-db/providers.json
src/renderer/src/**/*
📄 CodeRabbit inference engine (.cursor/rules/i18n.mdc)
src/renderer/src/**/*: All user-facing strings must use i18n keys (avoid hardcoded user-visible text in code)
Use the 'vue-i18n' framework for all internationalization in the renderer
Ensure all user-visible text in the renderer uses the translation system
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
src/renderer/src/**/*.{vue,ts,tsx,js,jsx}: Use the Composition API for better code organization and reusability
Implement proper state management with Pinia
Utilize Vue Router for navigation and route management
Leverage Vue's built-in reactivity system for efficient data handling
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**/*.vue
📄 CodeRabbit inference engine (.cursor/rules/vue-best-practices.mdc)
Use scoped styles to prevent CSS conflicts between components
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/{src,shell,floating}/**/*.vue
📄 CodeRabbit inference engine (CLAUDE.md)
src/renderer/{src,shell,floating}/**/*.vue: Use Vue 3 Composition API for all components
All user-facing strings must use i18n keys via vue-i18n (no hard-coded UI strings)
Use Tailwind CSS utilities and ensure styles are scoped in Vue components
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/components/**/*
📄 CodeRabbit inference engine (CLAUDE.md)
Organize UI components by feature within src/renderer/src/
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**
📄 CodeRabbit inference engine (AGENTS.md)
Place Vue 3 app source under src/renderer/src (components, stores, views, i18n, lib)
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
src/renderer/src/**/*.{vue,ts}
📄 CodeRabbit inference engine (AGENTS.md)
All user-facing strings must use vue-i18n ($t/keys) rather than hardcoded literals
Files:
src/renderer/src/components/mcp-config/components/McpServers.vuesrc/renderer/src/components/mcp-config/components/McpServerCard.vue
🧠 Learnings (1)
📚 Learning: 2025-07-23T00:45:57.322Z
Learnt from: CR
PR: ThinkInAIXYZ/deepchat#0
File: .cursor/rules/vue-shadcn.mdc:0-0
Timestamp: 2025-07-23T00:45:57.322Z
Learning: Applies to src/renderer/**/*.{vue} : Import Icon component from Iconify/Vue.
Applied to files:
src/renderer/settings/components/KnowledgeBaseSettings.vuesrc/renderer/settings/components/McpSettings.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (7)
src/renderer/settings/components/McpBuiltinMarket.vue (3)
3-13: LGTM! Well-executed header refactor.The sticky header with compact vertical layout improves UX during scrolling while maintaining clear visual hierarchy. The
z-10z-index and flexbox alignment are appropriate.
29-29: LGTM! Styling simplification improves visual clarity.Removing the border and background styling streamlines the help text presentation while maintaining proper spacing.
72-72: LGTM! Improved visual feedback for installation state.The conditional button variant (
outlinefor available,secondaryfor installed) enhances UX by providing clearer visual distinction between installation states, complementing the existing disabled state.src/renderer/settings/components/KnowledgeBaseSettings.vue (1)
2-23: LGTM! Clean UI simplification.The layout adjustments (increased padding and gaps) and simplified header improve visual clarity and align with the broader UI optimization goals of this PR. The removal of the add-knowledge dialog flow streamlines the interface.
src/shadcn/components/ui/textarea/Textarea.vue (1)
22-27: LGTM on the Textarea refactorReordering and class tweak look fine; behavior remains intact.
src/renderer/src/components/mcp-config/components/McpServers.vue (1)
262-280: Grid layout update looks goodIncreasing columns improves density; no logic affected.
Also applies to: 294-313
src/renderer/src/components/mcp-config/components/McpServerCard.vue (1)
142-155: Card refactor is cohesiveHeader simplification, description clamp, and footer controls align with the new design; events/props preserved.
Also applies to: 198-209, 233-239, 241-277
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/renderer/settings/components/DataSettings.vue (2)
28-28: Fix invalid Tailwind utility.The Input uses
h-8!which is invalid syntax. Use!h-8(important) orh-8instead.As per coding guidelines.
75-75: Import button triggers backup instead of opening dialog.The Import button (inside
DialogTrigger) callssyncStore.startBackup, which starts a backup operation before the user confirms the import. Remove the@clickhandler so the button only opens the import dialog.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/renderer/settings/components/CommonSettings.vue(10 hunks)src/renderer/settings/components/DataSettings.vue(3 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
src/renderer/**/*.{vue,ts,js,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/project-structure.mdc)
渲染进程代码放在
src/renderer
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
src/renderer/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,tsx,vue}: Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
Use TypeScript for all code; prefer types over interfaces.
Avoid enums; use const objects instead.
Use arrow functions for methods and computed properties.
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
src/renderer/**/*.{vue,ts}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
Implement lazy loading for routes and components.
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
src/renderer/**/*.{ts,vue}
📄 CodeRabbit inference engine (.cursor/rules/vue-shadcn.mdc)
src/renderer/**/*.{ts,vue}: Use useFetch and useAsyncData for data fetching.
Implement SEO best practices using Nuxt's useHead and useSeoMeta.Use Pinia for frontend state management (do not introduce alternative state libraries)
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
**/*.{ts,tsx,js,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Use English for all logs and comments
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (CLAUDE.md)
Enable and adhere to strict TypeScript typing (avoid implicit any, prefer precise types)
Use PascalCase for TypeScript types and classes
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
**/*.{ts,tsx,js,jsx,vue,css,scss,md,json,yml,yaml}
📄 CodeRabbit inference engine (AGENTS.md)
Prettier style: single quotes, no semicolons, print width 100; run pnpm run format
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,vue}: Use OxLint for JS/TS code; keep lint clean
Use camelCase for variables and functions
Use SCREAMING_SNAKE_CASE for constants
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
src/renderer/**/*.vue
📄 CodeRabbit inference engine (AGENTS.md)
Name Vue component files in PascalCase (e.g., ChatInput.vue)
Files:
src/renderer/settings/components/DataSettings.vuesrc/renderer/settings/components/CommonSettings.vue
🔇 Additional comments (3)
src/renderer/settings/components/CommonSettings.vue (1)
2-3: LGTM: Padding reorganization aligns with component consistency.The outer
ScrollAreapadding removal and inner container padding allocation matches the layout pattern applied across other settings components in this PR.src/renderer/settings/components/DataSettings.vue (2)
2-3: LGTM: Padding reorganization is consistent.The padding shift from
ScrollAreato the inner container aligns with the unified layout approach used across settings components in this PR.
127-127: Reset button disabled state references backup operation.The Reset button's
disabledattribute checkssyncStore.isBackingUp, which is semantically unrelated to reset operations. If the intent is to prevent concurrent operations, consider adding a dedicatedisResettingflag in the store, or verify thatisBackingUpis intentionally used to gate all data operations.
| <Dialog v-model:open="isLoggingDialogOpen" @update:open="cancelLoggingChange"> | ||
| <DialogTrigger as-child> | ||
| <Button class="w-36" variant="outline" :dir="langStore.dir" @click="openLogFolder"> | ||
| <Icon icon="lucide:external-link" class="w-4 h-4 text-muted-foreground" /> | ||
| <span class="text-sm font-medium">{{ t('settings.common.openLogFolder') }}</span> | ||
| </Button> | ||
| </DialogFooter> | ||
| </DialogContent> | ||
| </Dialog> | ||
| </DialogTrigger> | ||
| <DialogContent> | ||
| <DialogHeader> | ||
| <DialogTitle>{{ t('settings.common.loggingDialogTitle') }}</DialogTitle> | ||
| <DialogDescription> | ||
| <div class="space-y-2"> | ||
| <p> | ||
| {{ | ||
| newLoggingValue | ||
| ? t('settings.common.loggingEnableDesc') | ||
| : t('settings.common.loggingDisableDesc') | ||
| }} | ||
| </p> | ||
| <p>{{ t('settings.common.loggingRestartNotice') }}</p> | ||
| </div> | ||
| </DialogDescription> | ||
| </DialogHeader> | ||
| <DialogFooter> | ||
| <Button variant="outline" @click="cancelLoggingChange">{{ | ||
| t('common.cancel') | ||
| }}</Button> | ||
| <Button @click="confirmLoggingChange">{{ t('common.confirm') }}</Button> | ||
| </DialogFooter> | ||
| </DialogContent> | ||
| </Dialog> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DialogTrigger wraps the wrong button.
The DialogTrigger (line 273) wraps the "Open Log Folder" button (lines 274-277), but the Dialog content (lines 279-301) contains the logging enable/disable confirmation. This means clicking "Open Log Folder" would show the logging confirmation dialog instead of opening the folder.
The logging confirmation dialog should be triggered by the logging Switch (lines 227-232) via the handleLoggingChange handler, not by the log folder button. The log folder button should directly call openLogFolder without being wrapped in a DialogTrigger.
Apply this diff to fix the structure:
- <div class="flex flex-row gap-3">
- <!-- 日志开关确认对话框 -->
- <Dialog v-model:open="isLoggingDialogOpen" @update:open="cancelLoggingChange">
- <DialogTrigger as-child>
- <Button class="w-36" variant="outline" :dir="langStore.dir" @click="openLogFolder">
- <Icon icon="lucide:external-link" class="w-4 h-4 text-muted-foreground" />
- <span class="text-sm font-medium">{{ t('settings.common.openLogFolder') }}</span>
- </Button>
- </DialogTrigger>
- <DialogContent>
- <DialogHeader>
- <DialogTitle>{{ t('settings.common.loggingDialogTitle') }}</DialogTitle>
- <DialogDescription>
- <div class="space-y-2">
- <p>
- {{
- newLoggingValue
- ? t('settings.common.loggingEnableDesc')
- : t('settings.common.loggingDisableDesc')
- }}
- </p>
- <p>{{ t('settings.common.loggingRestartNotice') }}</p>
- </div>
- </DialogDescription>
- </DialogHeader>
- <DialogFooter>
- <Button variant="outline" @click="cancelLoggingChange">{{
- t('common.cancel')
- }}</Button>
- <Button @click="confirmLoggingChange">{{ t('common.confirm') }}</Button>
- </DialogFooter>
- </DialogContent>
- </Dialog>
- </div>
+ <div class="flex flex-row gap-3">
+ <Button class="w-36" variant="outline" :dir="langStore.dir" @click="openLogFolder">
+ <Icon icon="lucide:external-link" class="w-4 h-4 text-muted-foreground" />
+ <span class="text-sm font-medium">{{ t('settings.common.openLogFolder') }}</span>
+ </Button>
+ </div>
+
+ <!-- 日志开关确认对话框 -->
+ <Dialog v-model:open="isLoggingDialogOpen" @update:open="cancelLoggingChange">
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>{{ t('settings.common.loggingDialogTitle') }}</DialogTitle>
+ <DialogDescription>
+ <div class="space-y-2">
+ <p>
+ {{
+ newLoggingValue
+ ? t('settings.common.loggingEnableDesc')
+ : t('settings.common.loggingDisableDesc')
+ }}
+ </p>
+ <p>{{ t('settings.common.loggingRestartNotice') }}</p>
+ </div>
+ </DialogDescription>
+ </DialogHeader>
+ <DialogFooter>
+ <Button variant="outline" @click="cancelLoggingChange">{{
+ t('common.cancel')
+ }}</Button>
+ <Button @click="confirmLoggingChange">{{ t('common.confirm') }}</Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Dialog v-model:open="isLoggingDialogOpen" @update:open="cancelLoggingChange"> | |
| <DialogTrigger as-child> | |
| <Button class="w-36" variant="outline" :dir="langStore.dir" @click="openLogFolder"> | |
| <Icon icon="lucide:external-link" class="w-4 h-4 text-muted-foreground" /> | |
| <span class="text-sm font-medium">{{ t('settings.common.openLogFolder') }}</span> | |
| </Button> | |
| </DialogFooter> | |
| </DialogContent> | |
| </Dialog> | |
| </DialogTrigger> | |
| <DialogContent> | |
| <DialogHeader> | |
| <DialogTitle>{{ t('settings.common.loggingDialogTitle') }}</DialogTitle> | |
| <DialogDescription> | |
| <div class="space-y-2"> | |
| <p> | |
| {{ | |
| newLoggingValue | |
| ? t('settings.common.loggingEnableDesc') | |
| : t('settings.common.loggingDisableDesc') | |
| }} | |
| </p> | |
| <p>{{ t('settings.common.loggingRestartNotice') }}</p> | |
| </div> | |
| </DialogDescription> | |
| </DialogHeader> | |
| <DialogFooter> | |
| <Button variant="outline" @click="cancelLoggingChange">{{ | |
| t('common.cancel') | |
| }}</Button> | |
| <Button @click="confirmLoggingChange">{{ t('common.confirm') }}</Button> | |
| </DialogFooter> | |
| </DialogContent> | |
| </Dialog> | |
| <div class="flex flex-row gap-3"> | |
| <Button class="w-36" variant="outline" :dir="langStore.dir" @click="openLogFolder"> | |
| <Icon icon="lucide:external-link" class="w-4 h-4 text-muted-foreground" /> | |
| <span class="text-sm font-medium">{{ t('settings.common.openLogFolder') }}</span> | |
| </Button> | |
| </div> | |
| <!-- 日志开关确认对话框 --> | |
| <Dialog v-model:open="isLoggingDialogOpen" @update:open="cancelLoggingChange"> | |
| <DialogContent> | |
| <DialogHeader> | |
| <DialogTitle>{{ t('settings.common.loggingDialogTitle') }}</DialogTitle> | |
| <DialogDescription> | |
| <div class="space-y-2"> | |
| <p> | |
| {{ | |
| newLoggingValue | |
| ? t('settings.common.loggingEnableDesc') | |
| : t('settings.common.loggingDisableDesc') | |
| }} | |
| </p> | |
| <p>{{ t('settings.common.loggingRestartNotice') }}</p> | |
| </div> | |
| </DialogDescription> | |
| </DialogHeader> | |
| <DialogFooter> | |
| <Button variant="outline" @click="cancelLoggingChange">{{ | |
| t('common.cancel') | |
| }}</Button> | |
| <Button @click="confirmLoggingChange">{{ t('common.confirm') }}</Button> | |
| </DialogFooter> | |
| </DialogContent> | |
| </Dialog> |
Summary by CodeRabbit
New Features
Refactor
Style
Chores