Browse Source

🔍 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 11 tháng trước cách đây
mục cha
commit
b6c353ec14

+ 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 {