- Replace blanket console route footer hiding with specific page targeting
- Only hide footer on pages that use CardPro component:
* /console/channel (channels management)
* /console/log (usage logs)
* /console/redemption (redemption codes)
* /console/user (user management)
* /console/token (token management)
* /console/midjourney (midjourney logs)
* /console/task (task logs)
* /console/models (model management)
* /pricing (pricing page)
- Footer now displays on other console pages (dashboard, settings, topup, etc.)
- Improves UI consistency by showing footer where CardPro's internal pagination isn't used
This change ensures footer is only hidden when CardPro component provides its own
pagination/footer functionality, while preserving footer visibility on other pages
that benefit from the global footer navigation.
- Ran: bun run eslint:fix && bun run lint:fix
- Inserted AGPL license header via eslint-plugin-header
- Enforced no-multiple-empty-lines and other lint rules
- Formatted code using Prettier v3 (@so1ve/prettier-config)
- No functional changes; formatting-only baseline across JS/JSX files
- Rename React components/pages/utilities that contain JSX to `.jsx` across `web/src`
- Update import paths and re-exports to match new `.jsx` extensions
- Fix Vite entry by switching `web/index.html` from `/src/index.js` to `/src/index.jsx`
- Verified remaining `.js` files are plain JS (hooks/helpers/constants) and do not require JSX
- No runtime behavior changes; extension and reference alignment only
Context: Resolves the Vite pre-transform error caused by the stale `/src/index.js` entry after migrating to `.jsx`.
- Added unique keys for JSONEditor components to ensure proper re-rendering based on channelId.
- Implemented input reset to clear previous JSON field values when the modal is opened.
- Added support to fetch and render “model prefill groups” in `EditChannelModal.jsx`
- Users can now click a group button to instantly merge that group’s models into the models Select
- Mirrors the prefill-group UX used for tags/endpoints in `EditModelModal.jsx`
Details
- UI/UX:
- Renders one button per model group inside the models field’s extra actions
- Clicking a button merges its items into the selected models (trimmed, deduplicated), updating immediately
- Non-destructive and works alongside existing actions (fill related/all models, fetch upstream, clear, copy)
- API:
- GET `/api/prefill_group?type=model`
- Handles `items` as either an array or a JSON string array for robustness
- If request fails or returns no groups, buttons are simply not shown
- i18n:
- Reuses existing i18n; group names come from backend and are displayed as-is
- Performance:
- Simple set merge; negligible overhead
- Backward compatibility:
- No changes required on the backend or elsewhere; feature is additive
- Testing (manual):
1) Open channel modal (new or edit) and navigate to the Models section
2) Confirm model group buttons render when groups are configured
3) Click a group button → models Select updates with merged models (no duplicates)
4) Verify other actions (fill related/all, fetch upstream, clear, copy) still work
5) Close/reopen modal → state resets as expected
Implementation
- `web/src/components/table/channels/modals/EditChannelModal.jsx`
- Added `modelGroups` state and `fetchModelGroups()` (GET `/api/prefill_group?type=model`)
- Invoked `fetchModelGroups()` when the modal opens
- Rendered group buttons in the models Select `extraText`, merging group items into current selection
Chore
- Verified no new linter errors were introduced.
- Why:
- Avoid introducing `gorm.io/datatypes` for a single field.
- Align with existing pattern (`ChannelInfo`, `Properties`) using `Scanner`/`Valuer`.
- Fix runtime error when drivers return JSON as string.
- What:
- Introduced `JSONValue` (based on `json.RawMessage`) implementing `sql.Scanner` and `driver.Valuer`, with `MarshalJSON`/`UnmarshalJSON` to preserve raw JSON in API.
- Updated `PrefillGroup.Items` to use `JSONValue` with `gorm:"type:json"`.
- Localized comments in `model/prefill_group.go` to Chinese.
- Impact:
- Resolves “unsupported Scan, storing driver.Value type string into type *json.RawMessage”.
- Works with MySQL/Postgres/SQLite whether JSON is returned as `[]byte` or `string`.
- API and DB schema remain unchanged; no `go.mod` changes; lints pass.
Files changed:
- model/prefill_group.go
This commit significantly refactors the `EditModelModal` component to streamline the user interface and enhance usability, aligning it with the interaction patterns found elsewhere in the application.
- **Consolidated Layout:** Merged the "Vendor Information" and "Feature Configuration" sections into a single "Basic Information" card. This simplifies the form, reduces clutter, and makes all settings accessible in one view.
- **Improved Prefill Groups:** Replaced the separate `Select` dropdowns for tag and endpoint groups with a more intuitive button-based system within the `extraText` of the `TagInput` components.
- **Additive Button Logic:** The prefill group buttons now operate in an additive mode. Users can click multiple group buttons to incrementally add tags or endpoints, with duplicates being automatically handled.
- **Clear Functionality:** Added "Clear" buttons for both tags and endpoints, allowing users to easily reset the fields.
- **Code Cleanup:** Removed the unused `endpointOptions` constant and unnecessary icon imports (`Building`, `Settings`) to keep the codebase clean.
Summary
• Introduced standalone `ModelSelectModal.jsx` for selecting channel models
• Fetch-list now opens modal instead of in-place select, keeping EditChannelModal lean
Modal Features
1. Search bar with `IconSearch`, keyboard clear & mobile full-screen support
2. Tab layout (“New Models” / “Existing Models”) displayed next to title, responsive wrapping
3. Models grouped by vendor via `getModelCategories` and rendered inside always-expanded `Collapse` panels
4. Per-category checkbox in panel extra area for bulk select / deselect
5. Footer checkbox for bulk select of all models in current tab, with real-time counter
6. Empty state uses `IllustrationNoResult` / `IllustrationNoResultDark` for visual consistency
7. Accessible header/footer paddings aligned with Semi UI defaults
Fixes & Improvements
• All indeterminate and full-select states handled correctly
• Consistent “selected X / Y” stats synced with active tab, not global list
• All panels now controlled via `activeKey`, ensuring they remain expanded
• Search, vendor grouping, and responsive layout tested across mobile & desktop
These changes modernise the channel model management workflow and prepare the codebase for upcoming upstream-ratio integration.
Summary
• Introduced a unified `selectFilter` helper that matches both `option.value` and `option.label`, ensuring all `<Select>` components support intuitive search (fixes channel “type” dropdown not filtering).
• Replaced all usages of the old `modelSelectFilter` with `selectFilter` in:
• `EditChannelModal.jsx`
• `SettingsPanel.js`
• `EditTokenModal.jsx`
• `EditTagModal.jsx`
• Removed the deprecated `modelSelectFilter` export from `utils.js` (no backward-compat alias).
• Updated documentation comments accordingly.
Why
The old filter only inspected `option.value`, causing searches to fail when `label` carried the meaningful text (e.g., numeric IDs for channel types). The new helper searches both fields, covering all scenarios and unifying the API across the codebase.
Notes
No functional regressions expected; all components have been migrated.
Previously, the "Force Format" switch was displayed for every channel type
although it only applies to OpenAI (type === 1).
This change wraps the switch in a conditional so it renders exclusively when
the selected channel type is OpenAI.
Why:
- Prevents user confusion when configuring non-OpenAI channels
- Keeps the UI clean and context-relevant
Scope:
- web/src/components/table/channels/modals/EditChannelModal.jsx
No backend logic affected.
- Extract channel extra settings into a dedicated Card component for better visual hierarchy
- Replace custom gray background container with consistent Form component styling
- Simplify layout structure by removing complex Row/Col grid layout in favor of native Form component layout
- Unify help text styling by using extraText prop consistently across all form fields
- Move "Settings Documentation" link to card header subtitle for better accessibility
- Improve visual consistency with other setting cards by using matching design patterns
The channel extra settings (force format, thinking content conversion, pass-through body, proxy address, and system prompt) now follow the same design language as other configuration sections, providing a more cohesive user experience.
Affected settings:
- Force Format (OpenAI channels only)
- Thinking Content Conversion
- Pass-through Body
- Proxy Address
- System Prompt