Просмотр исходного кода

🔍 fix(pricing): synchronize search term with sidebar filters & reset behavior

* Add `searchValue` to every dependency array in `usePricingFilterCounts`
  to ensure group/vendor/tag counts and disabled states update dynamically
  while performing fuzzy search.

* Refactor `PricingTopSection` search box into a controlled component:
  - Accept `searchValue` prop and bind it to `Input.value`
  - Extend memo dependencies to include `searchValue`
  This keeps the UI in sync with state changes triggered by `handleChange`.

* Guarantee that `resetPricingFilters` clears the search field by
  leveraging the new controlled input.

As a result, sidebar counters/disabled states now react to search input,
and the “Reset” button fully restores default filters without leaving the
search term visible.
t0ng7u 6 месяцев назад
Родитель
Сommit
63b9457b6c

+ 3 - 1
web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx

@@ -35,6 +35,7 @@ const PricingTopSection = ({
   models,
   filteredModels,
   loading,
+  searchValue,
   t
 }) => {
   const [showFilterModal, setShowFilterModal] = useState(false);
@@ -46,6 +47,7 @@ const PricingTopSection = ({
         <Input
           prefix={<IconSearch />}
           placeholder={t('模糊搜索模型名称')}
+          value={searchValue}
           onCompositionStart={handleCompositionStart}
           onCompositionEnd={handleCompositionEnd}
           onChange={handleChange}
@@ -78,7 +80,7 @@ const PricingTopSection = ({
         </Button>
       )}
     </div>
-  ), [selectedRowKeys, t, handleCompositionStart, handleCompositionEnd, handleChange, copyText, isMobile]);
+  ), [selectedRowKeys, t, handleCompositionStart, handleCompositionEnd, handleChange, copyText, isMobile, searchValue]);
 
   return (
     <>

+ 5 - 12
web/src/hooks/model-pricing/usePricingFilterCounts.js

@@ -104,34 +104,27 @@ export const usePricingFilterCounts = ({
   // 生成不同视图所需的模型集合
   const quotaTypeModels = useMemo(
     () => allModels.filter((m) => matchesFilters(m, ['quota'])),
-    [allModels, filterGroup, filterEndpointType, filterVendor, filterTag]
+    [allModels, filterGroup, filterEndpointType, filterVendor, filterTag, searchValue]
   );
 
   const endpointTypeModels = useMemo(
     () => allModels.filter((m) => matchesFilters(m, ['endpoint'])),
-    [allModels, filterGroup, filterQuotaType, filterVendor, filterTag]
+    [allModels, filterGroup, filterQuotaType, filterVendor, filterTag, searchValue]
   );
 
   const vendorModels = useMemo(
     () => allModels.filter((m) => matchesFilters(m, ['vendor'])),
-    [allModels, filterGroup, filterQuotaType, filterEndpointType, filterTag]
+    [allModels, filterGroup, filterQuotaType, filterEndpointType, filterTag, searchValue]
   );
 
   const tagModels = useMemo(
     () => allModels.filter((m) => matchesFilters(m, ['tag'])),
-    [allModels, filterGroup, filterQuotaType, filterEndpointType, filterVendor]
+    [allModels, filterGroup, filterQuotaType, filterEndpointType, filterVendor, searchValue]
   );
 
   const groupCountModels = useMemo(
     () => allModels.filter((m) => matchesFilters(m, ['group'])),
-    [
-      allModels,
-      filterQuotaType,
-      filterEndpointType,
-      filterVendor,
-      filterTag,
-      searchValue,
-    ]
+    [allModels, filterQuotaType, filterEndpointType, filterVendor, filterTag, searchValue]
   );
 
   return {