Feat/provider: add provider create and edit router & adjust some styles#122
Feat/provider: add provider create and edit router & adjust some styles#122Bowl42 merged 8 commits intoawsl-project:mainfrom
Conversation
…cross multiple components - Updated import statements to use consistent single quotes. - Reformatted code for better readability, including consistent spacing and line breaks. - Enhanced the structure of function parameters for clarity. - Improved the handling of conditional rendering and state management in provider components. - Cleaned up comments and ensured they are relevant and concise.
📝 WalkthroughWalkthrough在侧边栏引入新的可复用导航项组件 Changes
Sequence Diagram(s)sequenceDiagram
participant User as 用户
participant UI as 浏览器 UI
participant Dnd as DndContext
participant Sort as SortableContext
participant Row as ProviderRow
participant Overlay as DragOverlay
User->>UI: 按下并开始拖拽某项
UI->>Dnd: 通知开始拖拽(activeId)
Dnd->>Sort: 标记活跃项,提供排序策略
Sort->>Row: 渲染可拖拽行(包含 drag handle)
Dnd->>Overlay: 显示拖动预览(ProviderRow 内容)
User->>UI: 在目标位置释放鼠标
UI->>Dnd: 触发 drop/重排 事件
Dnd->>Sort: 更新项顺序并触发重渲染
Sort->>Row: 重新排列列表
Dnd->>Overlay: 隐藏预览
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 分钟 Possibly related PRs
Suggested reviewers
诗句
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🔇 Additional comments (3)
✏️ Tip: You can disable this entire section by setting 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 |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
web/src/components/layout/nav-proxy-status.tsx (1)
61-88: 图标按钮缺少可访问性标签
该按钮只有图标,屏幕阅读器难以理解用途;title不一定被读取。建议补充aria-label(可结合 copied 状态)。♿️ 建议补充无障碍标签
<button type="button" onClick={handleCopy} className="shrink-0 text-muted-foreground relative w-4 h-4 cursor-pointer hover:text-foreground transition-colors" title={`Click to copy: ${fullUrl}`} + aria-label={copied ? t('proxy.copied') : t('proxy.clickToCopy')} >web/src/components/routes/ClientTypeRoutesContent.tsx (1)
183-224: 搜索过滤下拖拽会写入错误排序
items已被searchQuery过滤,但拖拽时仍用过滤后的顺序计算position并写回,隐藏项保留旧位置,可能产生重复/错乱排序。建议在过滤时禁用拖拽,或基于未过滤列表计算并写回完整顺序。🧭 示例:过滤时阻止位置写回(避免错乱)
+ const isFiltering = !!searchQuery.trim(); + const handleDragEnd = (event: DragEndEvent) => { + if (isFiltering) { + setActiveId(null); + return; + } const { active, over } = event; setActiveId(null);Also applies to: 243-290
🤖 Fix all issues with AI agents
In `@web/src/index.css`:
- Around line 290-297: Update the sizing rules for html, body, and `#root` to
avoid clipping and improve compatibility: replace height: 100svh with
min-height: 100svh on these selectors (or at least on `#root`) so content can
grow, and add a fallback for older browsers by keeping/adding a vh-based
fallback before the svh declaration (or use an `@supports` check for svh). Ensure
the change targets the existing selectors (html, body, `#root`) and that the
fallback order places the broader-supported value first followed by the svh
value so browsers that don't support svh will use the fallback.
In `@web/src/pages/providers/components/kiro-provider-view.tsx`:
- Line 1: 在 kiro-provider-view.tsx 中防止旧的异步配额响应覆盖新数据:为 fetchQuota/refresh
逻辑引入一个请求序号或 AbortController(例如 currentRequestIdRef 或
abortControllerRef),在每次触发拉取(包括 useEffect 和点击 Refresh 的处理函数)先递增序号或创建并替换
AbortController,然后在响应到达时只在序号匹配或未被中止时调用 setQuota/setLoading
等状态更新;另外在组件卸载或新请求发起时取消先前请求以避免竞态(定位到触发拉取的 useEffect 和 refresh handler,如
fetchQuota/loadQuota/handleRefresh)。
🧹 Nitpick comments (1)
web/src/pages/providers/components/antigravity-token-import.tsx (1)
290-327: Token 模式按钮与 OAuth 按钮样式保持一致。两个按钮的样式模式完全相同,这很好地保持了 UI 一致性。
考虑将重复的按钮样式逻辑提取为可复用组件或配置对象,以减少代码重复并便于后续维护。
♻️ 可选:提取模式选择按钮组件
// 可以考虑提取为独立组件 interface ModeButtonProps { mode: ImportMode; currentMode: ImportMode; onClick: () => void; icon: React.ReactNode; title: string; description: string; } function ModeButton({ mode, currentMode, onClick, icon, title, description }: ModeButtonProps) { const isActive = mode === currentMode; return ( <button onClick={onClick} className={cn( 'relative group p-4 rounded-xl border-2 transition-all duration-200 text-left', isActive ? 'border-primary bg-primary/10 shadow-md' : 'border-border hover:border-primary/30 bg-secondary/50 hover:bg-secondary', )} > {/* ... 共用布局逻辑 */} </button> ); }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
web/src/components/layout/app-layout.tsxweb/src/components/layout/app-sidebar/animated-nav-item.tsxweb/src/components/layout/app-sidebar/client-routes-items.tsxweb/src/components/layout/app-sidebar/index.tsxweb/src/components/layout/app-sidebar/requests-nav-item.tsxweb/src/components/layout/index.tsweb/src/components/layout/nav-proxy-status.tsxweb/src/components/routes/ClientTypeRoutesContent.tsxweb/src/components/ui/button.tsxweb/src/components/ui/model-input.tsxweb/src/components/ui/tabs.tsxweb/src/contexts/antigravity-quotas-context.tsxweb/src/hooks/queries/use-aggregated-stats.tsweb/src/hooks/queries/use-usage-stats.tsweb/src/index.cssweb/src/lib/transport/types.tsweb/src/pages/client-routes/components/provider-row.tsxweb/src/pages/model-mappings/index.tsxweb/src/pages/providers/components/antigravity-provider-view.tsxweb/src/pages/providers/components/antigravity-token-import.tsxweb/src/pages/providers/components/custom-config-step.tsxweb/src/pages/providers/components/kiro-provider-view.tsxweb/src/pages/providers/components/provider-edit-flow.tsxweb/src/pages/providers/components/provider-row.tsxweb/src/pages/providers/index.tsxweb/src/pages/requests/index.tsxweb/src/pages/stats/index.tsx
🧰 Additional context used
🧬 Code graph analysis (15)
web/src/components/ui/tabs.tsx (1)
web/src/lib/utils.ts (1)
cn(8-10)
web/src/contexts/antigravity-quotas-context.tsx (2)
web/src/lib/transport/types.ts (1)
AntigravityQuotaData(338-343)web/src/lib/transport/index.ts (1)
AntigravityQuotaData(46-46)
web/src/lib/transport/types.ts (3)
internal/domain/model.go (1)
ModelMappingScope(535-535)web/src/lib/transport/index.ts (2)
StatsGranularity(68-68)UsageStatsFilter(67-67)internal/repository/interfaces.go (1)
UsageStatsFilter(141-151)
web/src/hooks/queries/use-usage-stats.ts (3)
web/src/lib/transport/types.ts (1)
UsageStatsFilter(562-572)web/src/lib/transport/index.ts (1)
UsageStatsFilter(67-67)internal/repository/interfaces.go (1)
UsageStatsFilter(141-151)
web/src/pages/providers/components/provider-edit-flow.tsx (6)
web/src/lib/transport/types.ts (1)
Provider(43-53)internal/repository/sqlite/models.go (2)
Provider(115-122)Provider(124-124)web/src/lib/transport/index.ts (1)
Provider(9-9)web/src/hooks/queries/use-settings.ts (4)
useModelMappings(55-60)useCreateModelMapping(62-71)useUpdateModelMapping(73-83)useDeleteModelMapping(85-94)web/src/components/ui/model-input.tsx (1)
ModelInput(177-427)web/src/components/ui/button.tsx (1)
Button(58-58)
web/src/components/layout/app-sidebar/animated-nav-item.tsx (3)
web/src/components/ui/sidebar.tsx (3)
SidebarMenuItem(688-688)SidebarMenuButton(687-687)SidebarMenuBadge(686-686)web/src/lib/utils.ts (1)
cn(8-10)web/src/components/ui/streaming-badge.tsx (1)
StreamingBadge(27-81)
web/src/components/layout/app-sidebar/requests-nav-item.tsx (2)
web/src/hooks/use-streaming.ts (1)
useStreamingRequests(29-114)web/src/components/layout/app-sidebar/animated-nav-item.tsx (1)
AnimatedNavItem(28-60)
web/src/components/routes/ClientTypeRoutesContent.tsx (3)
web/src/hooks/queries/use-providers.ts (1)
useProviderStats(78-86)web/src/pages/client-routes/components/provider-row.tsx (1)
ProviderRowContent(180-496)web/src/components/icons/client-icons.tsx (1)
getClientName(51-53)
web/src/components/layout/app-sidebar/client-routes-items.tsx (2)
web/src/components/icons/client-icons.tsx (2)
getClientName(51-53)ClientIcon(65-100)web/src/components/layout/app-sidebar/animated-nav-item.tsx (1)
AnimatedNavItem(28-60)
web/src/pages/providers/components/kiro-provider-view.tsx (3)
web/src/hooks/queries/index.ts (4)
useModelMappings(91-91)useCreateModelMapping(92-92)useUpdateModelMapping(93-93)useDeleteModelMapping(94-94)web/src/hooks/queries/use-settings.ts (4)
useModelMappings(55-60)useCreateModelMapping(62-71)useUpdateModelMapping(73-83)useDeleteModelMapping(85-94)web/src/lib/transport/types.ts (1)
KiroQuotaData(431-442)
web/src/pages/requests/index.tsx (2)
web/src/components/ui/button.tsx (1)
Button(58-58)web/src/components/ui/index.ts (1)
Button(2-2)
web/src/components/layout/app-sidebar/index.tsx (1)
web/src/components/ui/sidebar.tsx (1)
Sidebar(674-674)
web/src/pages/providers/components/custom-config-step.tsx (1)
web/src/pages/providers/context/provider-form-context.tsx (1)
useProviderForm(95-101)
web/src/pages/providers/components/antigravity-provider-view.tsx (2)
web/src/hooks/queries/index.ts (4)
useModelMappings(91-91)useCreateModelMapping(92-92)useUpdateModelMapping(93-93)useDeleteModelMapping(94-94)web/src/hooks/queries/use-settings.ts (4)
useModelMappings(55-60)useCreateModelMapping(62-71)useUpdateModelMapping(73-83)useDeleteModelMapping(85-94)
web/src/pages/providers/components/antigravity-token-import.tsx (1)
web/src/lib/utils.ts (1)
cn(8-10)
🔇 Additional comments (38)
web/src/components/ui/model-input.tsx (1)
71-75: 格式化调整合理,未改变行为。
仅为可读性改动,无需进一步修改。web/src/hooks/queries/use-usage-stats.ts (1)
126-140: LGTM!仅添加了尾随逗号,这是一个纯格式化更改,有助于未来添加新参数时保持更简洁的 diff。类型定义
Omit<UsageStatsFilter, 'granularity' | 'start' | 'end'>正确地排除了由 preset 自动设置的字段。web/src/pages/providers/components/antigravity-token-import.tsx (1)
251-288: OAuth 模式按钮样式更新看起来不错。样式更改与新的 primary/secondary 调色板保持一致。
size-10工具类是w-10 h-10的有效简写形式,使代码更简洁。web/src/pages/client-routes/components/provider-row.tsx (1)
356-358: 格式调整无功能影响,LGTM。
仅为排版换行/缩进调整,渲染与数据逻辑保持一致。web/src/pages/model-mappings/index.tsx (1)
144-144: 语法格式统一,行为不变。
仅增加参数括号,可读性更好且不影响逻辑。web/src/hooks/queries/use-aggregated-stats.ts (1)
8-13: 仅为类型导入排版优化,LGTM。
不影响运行时与类型语义。web/src/components/ui/button.tsx (1)
6-7: 基础样式微调无逻辑影响。
移除阴影类仅影响视觉一致性,其他变体行为未变。web/src/components/ui/tabs.tsx (2)
11-11: 间距调整为纯样式改动,LGTM。
仅提升容器内元素间距,不影响交互逻辑。
67-67: 内容区样式简化可行。
移除 min-h-0 属于布局策略调整,无功能风险。web/src/lib/transport/types.ts (4)
384-395: 注释与排版对齐,类型结构不变。
接口字段未变更,仅格式化。
530-541: 注释/对齐调整,无语义变化。
字段与类型保持一致。
554-559: 格式化变更,LGTM。
统计字段语义不变。
564-565: 仅注释与排版调整。
过滤器字段定义未变。Also applies to: 571-571
web/src/contexts/antigravity-quotas-context.tsx (1)
23-26: 格式化改进,LGTM!参数解构和函数签名的多行格式化提升了代码可读性,逻辑保持不变。
Also applies to: 49-51
web/src/pages/providers/components/custom-config-step.tsx (2)
14-23: 格式化改进,LGTM!
useProviderForm的解构赋值改为多行格式,提高了可读性。
191-195: 数组操作格式化,LGTM!新增和删除 mapping 的数组操作逻辑保持不变,多行格式更清晰。
Also applies to: 243-246
web/src/index.css (1)
611-615: 按钮交互体验优化,LGTM!为
button和[role='button']元素全局添加cursor: pointer是一个良好的 UX 改进,确保所有可点击按钮都有一致的鼠标指针样式。web/src/pages/providers/components/antigravity-provider-view.tsx (3)
1-32: 导入语句格式化,LGTM!导入语句的格式调整保持了一致性,无功能变化。
131-162: Hook 调用和状态管理格式化,LGTM!
ProviderModelMappings组件中的 hook 调用和状态管理代码格式化改进,逻辑保持不变。
199-212: onChange 回调格式化,LGTM!
onChange处理器的参数加上括号(pattern) =>和(target) =>,符合一致的代码风格。web/src/pages/providers/index.tsx (1)
37-43: 过滤逻辑简化,LGTM!将多行 return 语句压缩为单行布尔表达式,逻辑保持不变,代码更简洁。
web/src/pages/requests/index.tsx (2)
126-140: Flex 布局修复,LGTM!添加
min-h-0是修复 flex 容器中滚动行为的正确做法。在 flex 布局中,子元素默认不会收缩到内容尺寸以下,min-h-0允许元素收缩并启用正确的overflow-auto滚动行为。
208-228: 分页栏样式简化,LGTM!分页栏使用
py-2替代固定高度更灵活,按钮样式简化后依赖 Button 组件的默认样式,保持一致性。web/src/components/layout/app-sidebar/animated-nav-item.tsx (1)
1-59: 组件封装清晰,复用性好
Active 判定、跑马灯与 StreamingBadge 集中处理,便于在侧边栏保持一致。web/src/components/routes/ClientTypeRoutesContent.tsx (2)
59-61: 状态与搜索过滤逻辑清晰
activeId/providerStats接入与过滤条件调整保持可读性。Also applies to: 110-114, 137-139
292-365: “可用 Provider”卡片布局一致性不错
卡片化列表、禁用态与颜色处理清晰。web/src/pages/providers/components/provider-edit-flow.tsx (2)
45-177: Model Mapping 创建/更新字段补全,流程完整
新增providerType/priority/isEnabled并重置输入,逻辑清楚。
181-267: 支持模型增删流程简洁
去重、清空输入与按钮禁用逻辑合理。web/src/pages/providers/components/kiro-provider-view.tsx (1)
126-258: Model Mapping 区块实现清晰
与自定义 provider 的处理一致,状态与禁用逻辑明确。web/src/pages/providers/components/provider-row.tsx (1)
188-192: 仅格式调整,渲染逻辑不变
该段改动不影响行为。web/src/pages/stats/index.tsx (3)
144-148: 聚合函数参数与依赖同步到位。新增
timeConfig入参并同步到useMemo依赖,避免图表使用过期时间配置,处理得当。Also applies to: 335-337
403-405: 图表与卡片样式调整整体一致。右侧 Y 轴、Tooltip 金额格式、刷新按钮动画与 SummaryCard 副标题展示都比较一致,UI 表现更清晰。
Also applies to: 501-509, 523-549, 554-625, 687-689
355-380:totalDurationMs在类型定义中是必需字段,不存在缺失风险。根据类型定义 (
web/src/lib/transport/types.ts:541),UsageStats.totalDurationMs被定义为totalDurationMs: number(必需,非可选),TypeScript 类型系统会强制确保该字段存在。现有的守卫条件totals.totalDurationMs > 0已足以防止计算中出现 NaN。无需添加额外的空值检查。Likely an incorrect or invalid review comment.
web/src/components/layout/app-sidebar/index.tsx (1)
19-19: Sidebar 边框样式收敛得不错。增加
className="border-border"有助于统一边框色,逻辑未变,OK。web/src/components/layout/app-sidebar/requests-nav-item.tsx (1)
15-23: 改用 AnimatedNavItem 后更统一。
isActive处理了/requests/*,并保留 streamingCount/tooltip,行为一致。web/src/components/layout/index.ts (1)
2-2: 导出名变更已验证完成,全仓库无遗留引用。全仓库搜索已确认:
- ✅ 无任何
SidebarNav的引用残留- ✅
AppSidebar已在app-layout.tsx中正确导入并使用- ✅ 导出迁移完整且正确
web/src/components/layout/app-layout.tsx (1)
16-23: 此项目使用 Tailwind CSS v4,其中重要性修饰符的正确语法是后缀形式(h-svh!),而非前缀形式(!h-svh)。代码库中已广泛一致地使用后缀风格,包括size-8!、p-2!和hover:bg-sidebar-accent/50!等,h-svh!和min-h-0!的用法正确无误。Likely an incorrect or invalid review comment.
web/src/components/layout/app-sidebar/client-routes-items.tsx (1)
22-30: 当前实现是正确的,不需要修改。应用中并未定义
/routes/${clientType}下的嵌套路由。路由配置仅包括两条路由:
/routes- 全局路由页面/routes/:clientType- 特定客户端类型的路由页面由于不存在
/routes/claude/detail这样的子路由,精确匹配pathname ===/routes/${clientType}` 的实现是正确的。Likely an incorrect or invalid review comment.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| html, | ||
| body { | ||
| body, | ||
| #root { | ||
| width: 100%; | ||
| height: 100%; | ||
| height: 100svh; | ||
| margin: 0; | ||
| padding: 0; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
CSS 100svh browser support 2025 viewport height
💡 Result:
Short answer
- 100svh is a CSS viewport unit equal to 100% of the "small viewport height" (viewport when browser UI like address/tool bars is expanded). Use it as height:100svh. [1][2]
Browser support (summary as of Jan 18, 2026)
- Widely supported in modern desktop and mobile browsers (Safari, Firefox, Chromium-based browsers) but some older engines, in-app/embedded browsers, or very old browser versions may not support it or may require experimental flags. Check live support for specific targets. [1][2][3]
Caveats and recommendations
- Use min-height:100svh rather than height:100svh for content that must not be clipped. [2]
- Some in-app or embedded webviews (messenger apps, some third‑party iOS wrappers) may ignore svh — test those environments. [7]
- Provide fallbacks (e.g., height:100vh before height:100svh) or use an
@supportscheck; a community polyfill exists if you need broader compatibility. [4][2]
Useful refs
- MDN (viewport-percentage units, svh/lvh/dvh). [1]
- Article explaining svh/lvh/dvh and usage caveats. [2]
- Browser support summary / compatibility table. [3]
- Polyfill repo for large/small/dynamic viewport units. [4]
If you want, I can fetch the current live caniuse/support matrix for particular browser versions or produce a small cross‑browser CSS snippet with fallbacks and @supports.
考虑使用 min-height 替代 height,并添加兼容性回退
将 #root 添加到尺寸规则中并使用 100svh 是一个好的改进,能更好地处理移动端浏览器的动态 UI(如地址栏收缩)。但以下几点需要注意:
- height vs min-height:建议将
height: 100svh改为min-height: 100svh,避免内容被裁剪。 - 兼容性回退:
100svh在某些旧版浏览器和内嵌网页浏览器中支持不完整。建议添加回退方案:或使用height: 100vh; height: 100svh;
@supports检查。 - 内嵌浏览器测试:某些应用内嵌网页(如 Messenger、某些 iOS 包装器)可能不支持
svh,建议在这些环境中测试。
🤖 Prompt for AI Agents
In `@web/src/index.css` around lines 290 - 297, Update the sizing rules for html,
body, and `#root` to avoid clipping and improve compatibility: replace height:
100svh with min-height: 100svh on these selectors (or at least on `#root`) so
content can grow, and add a fallback for older browsers by keeping/adding a
vh-based fallback before the svh declaration (or use an `@supports` check for
svh). Ensure the change targets the existing selectors (html, body, `#root`) and
that the fallback order places the broader-supported value first followed by the
svh value so browsers that don't support svh will use the fallback.
| @@ -1,4 +1,4 @@ | |||
| import { useState, useEffect, useMemo } from 'react' | |||
| import { useState, useEffect, useMemo } from 'react'; | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "kiro-provider-view.tsx" -type fRepository: awsl-project/maxx
Length of output: 120
🏁 Script executed:
wc -l ./web/src/pages/providers/components/kiro-provider-view.tsxRepository: awsl-project/maxx
Length of output: 124
🏁 Script executed:
cat -n ./web/src/pages/providers/components/kiro-provider-view.tsx | head -20Repository: awsl-project/maxx
Length of output: 721
🏁 Script executed:
cat -n ./web/src/pages/providers/components/kiro-provider-view.tsx | sed -n '250,290p'Repository: awsl-project/maxx
Length of output: 1682
🏁 Script executed:
cat -n ./web/src/pages/providers/components/kiro-provider-view.tsx | sed -n '283,320p'Repository: awsl-project/maxx
Length of output: 1924
🏁 Script executed:
cat -n ./web/src/pages/providers/components/kiro-provider-view.tsx | sed -n '320,380p'Repository: awsl-project/maxx
Length of output: 3255
🏁 Script executed:
cat -n ./web/src/pages/providers/components/kiro-provider-view.tsx | sed -n '359,366p'Repository: awsl-project/maxx
Length of output: 469
🏁 Script executed:
cat -n ./web/src/pages/providers/components/kiro-provider-view.tsx | sed -n '261,281p'Repository: awsl-project/maxx
Length of output: 918
防止异步配额拉取中的旧响应覆盖新数据
快速切换 provider 或连续点击 Refresh 时,旧请求返回可能覆盖新数据。建议用请求序号或 AbortController 抑制过期响应。
💡 示例:用请求序号防止过期响应
-import { useState, useEffect, useMemo } from 'react';
+import { useState, useEffect, useMemo, useRef } from 'react';
export function KiroProviderView({ provider, onDelete, onClose }: KiroProviderViewProps) {
const [quota, setQuota] = useState<KiroQuotaData | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
+ const requestIdRef = useRef(0);
const fetchQuota = async () => {
+ const requestId = ++requestIdRef.current;
setLoading(true);
setError(null);
try {
const data = await getTransport().getKiroProviderQuota(provider.id);
- setQuota(data);
+ if (requestIdRef.current === requestId) {
+ setQuota(data);
+ }
} catch (err) {
- setError(err instanceof Error ? err.message : 'Failed to fetch quota');
+ if (requestIdRef.current === requestId) {
+ setError(err instanceof Error ? err.message : 'Failed to fetch quota');
+ }
} finally {
- setLoading(false);
+ if (requestIdRef.current === requestId) {
+ setLoading(false);
+ }
}
};
useEffect(() => {
fetchQuota();
+ return () => {
+ requestIdRef.current += 1;
+ };
}, [provider.id]); // eslint-disable-line react-hooks/exhaustive-deps🤖 Prompt for AI Agents
In `@web/src/pages/providers/components/kiro-provider-view.tsx` at line 1, 在
kiro-provider-view.tsx 中防止旧的异步配额响应覆盖新数据:为 fetchQuota/refresh 逻辑引入一个请求序号或
AbortController(例如 currentRequestIdRef 或 abortControllerRef),在每次触发拉取(包括
useEffect 和点击 Refresh 的处理函数)先递增序号或创建并替换 AbortController,然后在响应到达时只在序号匹配或未被中止时调用
setQuota/setLoading 等状态更新;另外在组件卸载或新请求发起时取消先前请求以避免竞态(定位到触发拉取的 useEffect 和 refresh
handler,如 fetchQuota/loadQuota/handleRefresh)。
Summary by CodeRabbit
版本更新说明
新功能
用户界面改进
样式优化
✏️ Tip: You can customize this high-level summary in your review settings.