- 26 Jun, 2025 5 commits
-
-
🐛 Previously, the table did not enter the loading state after performing actions such as deleting, enabling, or disabling a redemption code. This caused a brief period where the UI appeared unresponsive while awaiting the backend response. Changes made: • Added `setLoading(true)` at the beginning of `loadRedemptions` to activate the loading spinner whenever data is (re)fetched. • Added an explanatory code comment to clarify the intent. This improves user experience by clearly indicating that the system is processing and prevents confusion during data refresh operations.
t0ng7u committed -
🎁 SUMMARY • Re-implemented `web/src/pages/Redemption/EditRedemption.js` with Semi Form components, removing legacy local-state handling. • Added `formApiRef` for centralized control; external “Submit” button now triggers `formApi.submitForm()`. • Replaced `Input/AutoComplete/DatePicker` etc. with `<Form.*>` fields, leveraging built-in validation & accessibility. • Field validations: – `name` (create only), `quota`, `count` → required with localized messages. • Expiration-time flow: – Default value `null` (no more 1970-01-01). – When loading data, convert 0 → null, timestamp → Date. – On submit, Date → unix seconds; empty → 0. • Responsive grid layout (`Row/Col`) for tidy alignment. • Added helpful `showClear` & full-width styling for inputs; quota presets retained. • Cleaned unused imports & handlers; fixed linter issues. RESULT The Redemption form now benefits from higher performance, clearer validation, and a cleaner codebase consistent with Semi Design best practices.
t0ng7u committed -
✨ SUMMARY • Re-implemented `EditToken.js` with Semi Form components, eliminating manual state handling and reducing re-renders. • Added grid-based layout; “Expiration Time” selector now sits inline with quick-set buttons for consistent alignment on desktop & mobile. • Introduced dedicated “Quota”, “Access”, “Model Limits”, and “Group” cards for clearer field grouping. • Reworked model-limit interaction: single multi-select list replaces checkbox toggle; backend flag `model_limits_enabled` is now inferred automatically. • Applied required validation rules to critical fields (`name`, `remain_quota`, `group`, `expired_time`, `tokenCount`) with localized messages. • Enabled dynamic option loading for models & groups; default auto-group honoured. • Added unlimited-quota switch, quota presets, and helpful extraText/tooltips. • Removed obsolete `handleInputChange` & `setUnlimitedQuota` helpers; formApi now manages all data flow. • Cleaned imports (e.g., dropped unused `IconUserGroup`), fixed linter errors, and updated submit logic to use `formApi.submitForm()`. RESULT The token creation/editing experience is faster, more accessible, and easier to maintain, fully aligned with Semi Design best practices.
t0ng7u committed -
🎨 t0ng7u committed -
🎨 Summary • Replaced gradient header blocks with compact, neutral headers wrapped in `Avatar` across the following pages: - Channel / EditChannel.js - Channel / EditTagModal.js - Redemption / EditRedemption.js - Token / EditToken.js - User / EditUser.js - User / AddUser.js Details 1. Added `Avatar` import and substituted raw icon elements, assigning semantic colors (`blue`, `green`, `purple`, `orange`, etc.) and consistent 16 px icons for a cleaner look. 2. Removed gradient backgrounds, decorative “blur-ball” shapes, and extra paddings from header containers to achieve a tight, flat design. 3. Stripped all `size="large"` attributes from `Button`, `Input`, `Select`, `DatePicker`, `AutoComplete`, and `Avatar` components, allowing default sizing for better visual density. 4. Eliminated redundant `bodyStyle` background overrides in some `SideSheet` components. 5. No business logic touched; all changes are purely presentational. Result The editing and creation dialogs now share a unified, compact style consistent with the latest design language, improving readability and user experience without altering functionality.
t0ng7u committed
-
- 25 Jun, 2025 11 commits
-
-
🔒 • Add conditional rendering (`!status.self_use_mode_enabled`) to LoginForm • Suppress “Don't have an account? Register” CTA in self-hosted scenarios • Keeps UI clean and prevents unintended user sign-ups under self-use mode • No impact on regular multi-user deployments
t0ng7u committed -
🐛 Login Form used to display the message “未登录或登录已过期,请重新登录” twice because the `useEffect` that inspects the `expired` query parameter was re-executed on every re-render (e.g. language change or React StrictMode’s double-mount in development). ### What's changed • **LoginForm.js** – `useEffect` that shows the toast now has an empty dependency array so it runs only once on initial mount. • Reviewed **PasswordResetConfirm.js**, **PasswordResetForm.js** and **RegisterForm.js** and confirmed they do not contain the same issue; no changes were required. ### Impact Users now see the “session expired” notification exactly once, removing confusion and improving the overall UX.
t0ng7u committed -
t0ng7u committed
-
🐛 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 -
💫 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 -
🐛 • 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 -
🍭 t0ng7u committed -
🔧 - 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 -
🎨 • 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 -
t0ng7u committed
-
✨ • 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
-
- 24 Jun, 2025 6 commits
-
-
🚀 - 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 -
t0ng7u committed
-
🔧 • 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 -
🔧 CaIon committed -
🎨 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 -
🚀 * 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
-
- 23 Jun, 2025 15 commits
-
-
✨ 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 -
🚀 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 -
✨ 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 -
💄 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 -
🐛 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 -
🐛 • 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 #1292t0ng7u committed -
🎨 * 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 pull request #1290 from JoeyLearnsToCode/feat-copy-models
同語 committed -
🚀 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 #1289t0ng7u committed -
t0ng7u committed
-
🚀 🚀 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 -
🐛 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 -
JoeyLearnsToCode committed
-
🎛 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
-
- 22 Jun, 2025 3 commits