1. 23 Jun, 2025 14 commits
    • 🚀 feat: Align search API with channel listing & fix sorting toggle · d19ab54e
      1. Backend
         • `controller/channel.go`
           – Added pagination (`p`, `page_size`) support to `SearchChannels`.
           – Added independent `type` filter (keeps `type_counts` unaffected).
           – Returned `total`, `type_counts` to match `/api/channel/` response.
      
      2. Frontend
         • `ChannelsTable.js`
           – `loadChannels` / `searchChannels` now pass `p`, `page_size`, `id_sort`, `type`, `status` correctly.
           – Pagination, page-size selector and type tabs work for both normal list and search mode.
           – Switch for “ID sort” calls proper API and keeps UI state in sync.
           – Removed unnecessary `normalize` helper; `getFormValues` back to concise form.
      
      Result
      • Search mode and normal listing now share identical pagination and filtering behavior.
      • Type tabs show correct counts even after searching.
      • “ID Sort” toggle no longer inverses actual behaviour.
      t0ng7u committed
    • fix(channels-table): preserve group filter when switching type or status tabs · 8f0f0c0d
      Refactors `ChannelsTable.js` to ensure that the selected group filter is **never lost** when:
      
      1. Cycling between channel-type tabs.
      2. Changing the status dropdown (all / enabled / disabled).
      
      Key points:
      
      • `loadChannels` now detects active search filters (keyword / group / model) and transparently delegates to `searchChannels`, guaranteeing all parameters are sent in every request.
      • `searchChannels` accepts optional `typeKey` and `statusF` arguments, enabling reuse without code duplication.
      • Loading state handling is unified; no extra renders or side effects were introduced, keeping UI performance intact.
      • Duplicate logic removed and responsibilities clearly separated for easier future maintenance.
      t0ng7u committed
    • Revert "🐛 fix: preserve group filter when switching channel type/status" · 9bf32ef5
      This reverts commit 4949d986.
      t0ng7u committed
    • 💄 i18n: shorten channel search placeholder and update i18n · 9469c497
      Replaced the verbose placeholder “Search channel ID, name, key and API address ...”
      with a concise version “Channel ID, name, key, API address” in
      `ChannelsTable.js` and synchronized the corresponding i18n entries.
      
      This improves readability and keeps UI text consistent across languages.
      t0ng7u committed
    • 🐛 fix: preserve group filter when switching channel type/status · 4949d986
      Ensure that the selected "group" filter (and other form search values) persist across
      type tab changes, status filter updates, pagination, and page-size changes.
      
      Changes include:
      • loadChannels: added `searchParams` argument and now appends keyword, group and model
        query strings to API calls.
      • refresh / page handlers / type tabs / status Select: now pass current form values
        to loadChannels, keeping filters intact.
      • searchChannels: maintains active type and status filters when issuing search requests.
      • Form.Select (searchGroup): triggers loadChannels when only group filter is active,
        preventing parameter loss.
      • Minor cleanup and comment adjustments.
      t0ng7u committed
    • 🐛 fix(channel): remove duplicate model names in “Edit Channel” model dropdown (#1292) · 949d4625
      • Unify the Select option structure as `{ key, label, value }`; add missing `key` to prevent duplicated rendering by Semi-UI.
      • Trim and deduplicate the `models` array via `Set` inside `handleInputChange`, ensuring state always contains unique values.
      • In the options-merging `useEffect`, use a `Map` keyed by `value` (after `trim`) to guarantee a unique `optionList` when combining backend data with currently selected models.
      • Apply the same structure and de-duplication when:
        – Fetching models from `/api/channel/models`
        – Adding custom models (`addCustomModels`)
        – Fetching upstream model lists (`fetchUpstreamModelList`)
      • Replace obsolete `text` field with `label` in custom option objects for consistency.
      
      No backend changes are required; the fix is entirely front-end.
      
      Closes #1292
      t0ng7u committed
    • 🎨 feat(EditChannel): improve model selection UX, clipboard feedback & rounded styling (#1290) · fc2e2c1a
      * Added a dedicated effect to merge origin and selected models, ensuring selected items always remain in the dropdown list.
      * Enhanced “Copy all models” button:
        * Shows info message when list is empty.
        * Displays success / error notification based on copy result.
      * Unified UI look-and-feel by applying `!rounded-lg` class to inputs, selects, banners and buttons.
      * i18n: added English translations for new prompts
        - "No models to copy"
        - "Model list copied to clipboard"
        - "Copy failed"
      t0ng7u committed
    • 🧬merge: Add a button to copy the selected model in the channel (#1290) · e7506ee9
      Merge pull request #1290 from JoeyLearnsToCode/feat-copy-models
      同語 committed
    • 🚀 feat: add enabled/disabled channel filtering & optimize type-based pagination (#1289) · 13fd901d
      WHAT’S NEW
      • Backend
        – Introduced `parseStatusFilter` helper to normalize `status` query across handlers.
        – `GET /api/channel` & `GET /api/channel/search` now accept `status=enabled|disabled` to return only enabled or disabled channels.
        – Tag-mode branch respects both `statusFilter` and `typeFilter`; SQL paths trimmed to one query + one lightweight `GROUP BY` for `type_counts`.
      
      • Frontend (`ChannelsTable.js`)
        – Added “Status Filter” `<Select>` (All / Enabled / Disabled) with localStorage persistence.
        – All data-loading and search requests now always append `type` (when not “all”) and `status` params, so filtering & pagination are handled entirely server-side.
        – Removed client-side post-filtering for type, preventing short pages and reducing CPU work.
        – Tabs’ type counts stay in sync via backend-provided `type_counts`.
      
      IMPROVEMENTS
      • Eliminated duplicated status-parsing logic; single source of truth eases future extension.
      • Reduced redundant queries, improved consistency of counts in UI.
      • Secured key leakage with `Omit("key")` unchanged; no perf regressions observed.
      
      Closes #1289
      t0ng7u committed
    • 🚀 chore(ui): Refactor UpstreamRatioSync with conflict-modal component,… · 0ac7406d
      🚀 chore(ui): Refactor UpstreamRatioSync with conflict-modal component, performance hooks & cleanup (#1286)
      
      WHAT’S NEW
      • Extracted reusable ConflictConfirmModal for clearer JSX hierarchy
      • Added detailed conflict detection & confirmation flow before syncing options
      • Refactored state-heavy callbacks (`selectValue`, `performSync`) with `useCallback` to avoid unnecessary renders
      • Introduced build-time constants (later removed unused export) and unified helper utilities
      • Ensured final ratios are rebuilt accurately before API `PUT`, fixing “value not updated” bug
      • Enhanced UI hints: warning icon on conflict, multiline billing info, mobile-friendly modal size
      • General code cleanup: removed dead variables, adopted early returns, improved comments
      
      WHY
      Improves maintainability, user clarity when billing-type collisions occur, and guarantees data consistency after synchronisation.
      t0ng7u committed
    • 🐛 fix(ratio-sync): reset pagination when filter/search changes · ef9c5b3a
      Add a `useEffect` hook in `UpstreamRatioSync.js` to automatically set
      `currentPage` to `1` whenever `ratioTypeFilter` or `searchKeyword`
      updates.
      This prevents the table from appearing empty when users switch to the
      “model_price” (fixed price) filter or perform a new search while on a
      later page.
      
      Additional changes:
      - Import `useEffect` from React.
      
      This enhancement delivers a smoother UX by ensuring the first page of
      results is always shown after any filtering action.
      t0ng7u committed
    • 🎛️ feat(web): add “Conflict Rates” filter & highlight in Model Settings Visual Editor (#1286) · f73da57a
      Introduce the ability to quickly locate models with conflicting billing configurations.
      
      Key points
      • Added `hasConflict` flag to detect models that define both a fixed price (`ModelPrice`) and any ratio (`ModelRatio` or `CompletionRatio`).
      • Added “Show Only Conflict Rates” `Checkbox` to toolbar; filtering logic now supports keyword + conflict filtering.
      • Display a red `Tag` beside the model name when a conflict is detected for immediate visual feedback.
      • Kept `hasConflict` state in sync during add, update and delete operations.
      • Imported `Checkbox` and `Tag` from **@douyinfe/semi-ui**.
      • Minor UI tweaks (circle tag style, margin) for consistency.
      
      This enhancement helps administrators swiftly identify and resolve incompatible pricing rules, addressing the need discussed in issue #1286.
      t0ng7u committed
  2. 22 Jun, 2025 13 commits
  3. 21 Jun, 2025 13 commits