1. 25 Jun, 2025 9 commits
    • 🐛 fix(auth): restore proper state & context destructuring in Login- and Register-forms · dabd9a9a
      Why
      Clicking the “Continue” button on the login page no longer triggered the submission logic. The issue was introduced when `useState`/`useContext` hooks were destructured incorrectly, breaking the setter reference and omitting required values.
      
      What’s changed
      • **LoginForm.js**
        – Re-added setter in `useSearchParams` (`[searchParams, setSearchParams]`).
        – Corrected order of destructuring for `inputs` so `username`/`password` are available after hooks.
        – Switched `useContext` to `[userState, userDispatch]` for consistency.
      
      • **RegisterForm.js**
        – Adopted `[userState, userDispatch]` from `UserContext` to mirror LoginForm and retain full state access.
      
      Outcome
      Login button now successfully invokes `handleSubmit`, and both auth components have consistent, fully-featured hook destructuring, preventing runtime errors and ensuring future state usage is straightforward.
      t0ng7u committed
    • 💫 feat(ui): introduce dispersed blur-ball background to all auth views · 06b7b595
      This commit refreshes the visual design of the authentication pages and aligns them with the Home banner style.
      
      Details
      • LoginForm.js / RegisterForm.js / PasswordResetForm.js / PasswordResetConfirm.js
        – Wrap top-level container with `relative overflow-hidden` to provide a positioning context.
        – Inject two decorative blur balls:
          ▸ Indigo ball on the top-right (`blur-ball-indigo`).
          ▸ Teal ball on the middle-left (`blur-ball-teal`).
        – Disabled the default X-axis transform on the indigo ball to keep the ball anchored to the corner.
        – Removed redundant `mt-[64px]` from the outer container and shifted it to the inner wrapper to maintain vertical rhythm without affecting the background placement.
      
      Result
      The auth screens now feature subtle, non-intrusive atmospheric gradients in the top-right and mid-left corners, offering a cohesive look & feel across the application without obstructing the main content.
      t0ng7u committed
    • 🐛 fix(auth): prevent initial render flicker & clean up state usage · 8fb5cb66
      • LoginForm / RegisterForm now initialise `status` directly from localStorage,
        avoiding a post-mount state update that caused a UI flash between OAuth
        options and email/username forms.
      
      • Move Turnstile configuration into a dedicated effect that depends on
        `status`, ensuring setState is not called during rendering.
      
      • Remove unused `setStatus` setter to resolve ESLint “declared but never read”
        warnings.
      
      • Minor refactors: reorder hooks, de-duplicate navigate/context variables and
        streamline state destructuring for improved readability.
      t0ng7u committed
    • 🔧 fix(xinference): update Document type to 'any' for flexibility · 038202b1
      - Changed the type of `Document` in `XinRerankResponseDocument` from `string` to `any` to accommodate various data types.
      - Updated the `RerankHandler` to handle `Document` as `any`, ensuring proper assignment based on its actual type.
      
      These modifications enhance the handling of document data, allowing for greater versatility in response structures.
      CaIon committed
    • 🎨 style(ui): refactor Tabs in ModelPricing to use native Semi UI styling · 6d2f34a8
      • Removed the custom `renderArrow` helper and its `Dropdown`-based arrow navigation, simplifying the component logic.
      • Switched the `<Tabs>` component to rely on Semi UI’s built-in behaviour (no more `renderArrow` override).
      • Kept `type="card"` and `collapsible` props for consistent visual appearance while still using the default style.
      • Eliminated the now-unused `Dropdown` import.
      
      This cleanup reduces bespoke UI code, makes future maintenance easier, and keeps the interface consistent with the rest of the application.
      t0ng7u committed
    • feat(homepage): enhance banner visuals & UX · 70a4b576
      • Added read-only Base URL input that shows `status.server_address` (fallback `window.location.origin`) and copies value on click.
      • Embedded `ScrollList` as input `suffix`; auto-cycles common endpoints every 3 s and allows manual selection.
      • Introduced `API_ENDPOINTS` array in `web/src/constants/common.constant.js` for centralized endpoint management.
      • Implemented custom CSS to hide ScrollList wheel indicators / scrollbars for a cleaner look.
      • Created two blurred colour spheres behind the banner (`blur-ball-indigo`, `blur-ball-teal`) with light-/dark-mode opacity tweaks and lower vertical placement.
      • Increased letter-spacing for Chinese heading via conditional `tracking-wide` / `md:tracking-wider` classes to improve readability.
      • Misc: updated imports, helper functions, and responsive sizes to keep UI consistent across devices.
      t0ng7u committed
  2. 24 Jun, 2025 6 commits
    • 🚀 feat(auth): support new model API paths in authentication and routing · 04d525e3
      - Updated TokenAuth middleware to handle requests for both `/v1beta/models/` and `/v1/models/`.
      - Adjusted distributor middleware to recognize the new model path.
      - Enhanced relay mode determination to include the new model path.
      - Added route for handling POST requests to `/models/*path`.
      
      These changes ensure compatibility with the new model API structure, improving the overall routing and authentication flow.
      CaIon committed
    • 🔧 style(ui): Inline tag edit action in ChannelsTable · 87e90e52
      • Removed the dropdown menu previously used for tag-level operations.
      • Added a standalone “Edit” button directly after the “Disable All” button, reducing the number of clicks required to edit a tag group.
      • Deleted the now-unused `IconEdit` import and its icon reference.
      
      This streamlines the tag management flow and keeps the UI cleaner and more accessible.
      t0ng7u committed
    • 🎨 style(channels-table): standardize operation component size to `small` · 7a4c213b
      All operation-related UI controls in `ChannelsTable` (buttons, dropdowns,
      switches, inputs, tags, etc.) now explicitly use `size="small"`.
      
      Reasons & benefits:
      - Creates a more compact and consistent look across the table and modals.
      - Improves visual coherence between desktop and mobile views.
      - Purely presentational; no functional logic is affected.
      
      No database changes or API interactions are involved.
      t0ng7u committed
    • 🚀 feat: enhance model testing UI with bulk selection, copy & success-filter buttons (#1288) · 610853e9
      * ChannelsTable
        - Added row-level checkboxes to the model-testing table for multi-selection
        - Implemented cross-page “Select All / Deselect All” via rowSelection.onSelectAll
        - Introduced allSelectingRef to ignore redundant onChange after onSelectAll
        - Added “Copy Selected” button to copy chosen model names (comma-separated) using helpers.copy
        - Added “Select Successful” button to auto-tick all models that passed testing
        - Moved search bar and new action buttons into the modal title for better UX
        - Centralised page size constant MODEL_TABLE_PAGE_SIZE in channel.constants.js
        - Fixed pagination slicing and auto-page-switch logic during batch testing
      
      * channel.constants
        - Exported MODEL_TABLE_PAGE_SIZE (default 10) for unified pagination control
      
      This commit enables users to conveniently copy or filter successful models, fully supports cross-page bulk operations, and resolves previous selection inconsistencies.
      
      Refs: #1288
      t0ng7u committed
  3. 23 Jun, 2025 15 commits
    • fix: ensure table shows correct loading state on first render & during search · 62daf16b
      Frontend (`ChannelsTable.js`)
      1. Initialize `loading` state to `true` so the spinner is visible while the first data request is in-flight.
      2. Set `<Table>` prop `loading={loading || searching}` — the spinner now appears for both the initial load and any subsequent search requests.
      
      Result
      Users immediately see a loading indicator on page entry and whenever a search is running, improving perceived responsiveness.
      t0ng7u committed
    • 🚀 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
  4. 22 Jun, 2025 10 commits