Commit Graph

1436 Commits

Author SHA1 Message Date
Calcium-Ion
7997a04a68 Merge pull request #1556 from QuantumNous/fix-register-mail-verifycode-waiting-time
fix: 注册时发送邮件验证码没有等待时间
2025-08-12 14:20:09 +08:00
t0ng7u
dc12ec6dfd 🚫 feat(web): add 403 Forbidden page and AdminRoute guard
- Add new Forbidden page at /forbidden (`web/src/pages/Forbidden/index.js`)
  - Use Semi-UI Empty with IllustrationNoAccess (250x250)
  - Update i18n description to: '您无权访问此页面,请联系管理员~'
  - Align visual style with existing 404 page
- Introduce `AdminRoute` in `web/src/helpers/auth.js`
  - Use `UserContext`/localStorage; redirect to `/forbidden` when `!user` or `user.role < 10`
- Protect console/admin routes with `AdminRoute` and register `/forbidden` in `web/src/App.js`
- Update `web/src/i18n/locales/en.json`
  - Add English translation for the new forbidden message
  - Remove legacy "没有权限" entry
- Lint passes; no runtime errors observed
2025-08-12 10:45:21 +08:00
t0ng7u
39c966efdd 🐛 fix: make ModelSelectModal panels collapsible and default to collapsed
- Switch Collapse from controlled (activeKey) to uncontrolled (defaultActiveKey) so user toggling works
- Add a stable key to reset Collapse state when tab/category changes
- Default all panels to collapsed via defaultActiveKey: []
- Preserve Panel itemKey for consistent behavior
- No linter errors introduced

Scope: web/src/components/table/channels/modals/ModelSelectModal.jsx
2025-08-12 10:22:00 +08:00
t0ng7u
03cfc05afd 🍭 ui: change pricing page card view pt-4 to py-4 2025-08-11 19:11:58 +08:00
t0ng7u
fa686207ed 🍭 ui: change pricing page card view p-4 to px-4 2025-08-11 18:32:19 +08:00
t0ng7u
e863be7ec3 ui: Add CSS ellipsis + Tooltip for SelectableButtonGroup; keep Tag intact
- Truncate long labels via pure CSS and always show full text in a Tooltip
- Ensure the right-side Tag is never truncated and remains fully visible
- Simplify implementation: remove overflow detection and ResizeObserver
- Use minimal markup with sbg-button/sbg-inner/sbg-label to enable shrinking
- Add global rules to allow `.semi-button-content` to shrink and ellipsize

Files:
- web/src/components/common/ui/SelectableButtonGroup.jsx
- web/src/index.css

No API changes; visuals improved and code complexity reduced.
2025-08-11 18:27:32 +08:00
t0ng7u
2d4edb3eca 🤓 style(ui): remove the pricing page’s border style to reduce visual clutter 2025-08-11 17:44:12 +08:00
t0ng7u
da17bdb688 💄 style: Use segmented renderer for billing types in Models table; keep Pricing view unchanged
Frontend
- Models table (model management):
  - Render billing types with the same segmented list component (renderLimitedItems) used by tags and endpoints
  - Display quota_types as an array with capped items (maxDisplay: 3) and graceful fallback for unknown types
- Pricing view (unchanged by request):
  - Revert to single-value quota_type rendering and sorter
  - Keep ratio display logic based on quota_type only

Files
- web/src/components/table/models/ModelsColumnDefs.js
- web/src/components/table/model-pricing/view/table/PricingTableColumns.js

Notes
- This commit only adjusts the model management UI rendering; pricing views remain as-is
2025-08-11 15:53:55 +08:00
t0ng7u
4ad8eefaec 🚀 perf: optimize model management APIs, unify pricing types as array, and remove redundancies
Backend
- Add GetBoundChannelsByModelsMap to batch-fetch bound channels via a single JOIN (Distinct), compatible with SQLite/MySQL/PostgreSQL
- Replace per-record enrichment with a single-pass enrichModels to avoid N+1 queries; compute unions for prefix/suffix/contains matches in memory
- Change Model.QuotaType to QuotaTypes []int and expose quota_types in responses
- Add GetModelQuotaTypes for cached O(1) lookups; exact models return a single-element array
- Sort quota_types for stable output order
- Remove unused code: GetModelByName, GetBoundChannels, GetBoundChannelsForModels, FindModelByNameWithRule, buildPrefixes, buildSuffixes
- Clean up redundant comments, keeping concise and readable code

Frontend
- Models table: switch to quota_types, render multiple billing modes ([0], [1], [0,1], future values supported)
- Pricing table: switch to quota_types; ratio display now checks quota_types.includes(0); array rendering for billing tags

Compatibility
- SQL uses standard JOIN/IN/Distinct; works across SQLite/MySQL/PostgreSQL
- Lint passes; no DB schema changes (quota_types is a JSON response field only)

Breaking Change
- API field renamed: quota_type -> quota_types (array). Update clients accordingly.
2025-08-11 14:40:01 +08:00
t0ng7u
c8f7aa76e7 🔍 feat: Show matched model names & counts for non-exact model rules
Summary
-------
1. **Backend**
   • `model/model_meta.go`
     – Add `MatchedModels []string` and `MatchedCount int` (ignored by GORM) to expose matching details in API responses.
   • `controller/model_meta.go`
     – When processing prefix/suffix/contains rules in `fillModelExtra`, collect every matched model name, fill `MatchedModels`, and calculate `MatchedCount`.

2. **Frontend**
   • `web/src/components/table/models/ModelsColumnDefs.js`
     – Import `Tooltip`.
     – Enhance `renderNameRule` to:
       – Display tag text like “前缀 5个模型” for non-exact rules.
       – Show a tooltip listing all matched model names on hover.

Impact
------
Users now see the total number of concrete models aggregated under each prefix/suffix/contains rule and can inspect the exact list via tooltip, improving transparency in model management.
2025-08-10 21:32:18 +08:00
t0ng7u
42d2394585 Merge remote-tracking branch 'origin/alpha' into alpha 2025-08-10 21:14:47 +08:00
t0ng7u
94bd44d0f2 feat: enhance model billing aggregation & UI display for unknown quota type
Summary
-------
1. **Backend**
   • `controller/model_meta.go`
     – For prefix/suffix/contains rules, aggregate endpoints, bound channels, enable groups, and quota types across all matched models.
     – When mixed billing types are detected, return `quota_type = -1` (unknown) instead of defaulting to volume-based.

2. **Frontend**
   • `web/src/helpers/utils.js`
     – `calculateModelPrice` now handles `quota_type = -1`, returning placeholder `'-'`.

   • `web/src/components/table/model-pricing/view/card/PricingCardView.jsx`
     – Billing tag logic updated: displays “按次计费” (times), “按量计费” (volume), or `'-'` for unknown.

   • `web/src/components/table/model-pricing/view/table/PricingTableColumns.js`
     – `renderQuotaType` shows “未知” for unknown billing type.

   • `web/src/components/table/models/ModelsColumnDefs.js`
     – Unified `renderQuotaType` to return `'-'` when type is unknown.

   • `web/src/components/table/model-pricing/modal/components/ModelPricingTable.jsx`
     – Group price table honors unknown billing type; pricing columns show `'-'` and neutral tag color.

3. **Utilities**
   • Added safe fallback colours/tags for unknown billing type across affected components.

Impact
------
• Ensures correct data aggregation for non-exact model matches.
• Prevents UI from implying volume billing when actual type is ambiguous.
• Provides consistent placeholder display (`'-'` or “未知”) across cards, tables and modals.

No breaking API changes; frontend gracefully handles legacy values.
2025-08-10 21:09:49 +08:00
CaIon
7f462a084c feat: Add ChannelOtherSettings to manage additional channel configurations 2025-08-10 20:21:30 +08:00
creamlike1024
b77d64bc9f fix: 注册时发送邮件验证码没有等待时间 2025-08-10 19:15:26 +08:00
t0ng7u
d1d945eaa0 🔠 refactor: refine group label formatting in price info
Summary:
• Updated `helpers/utils.js` to display the “group” label without a colon, ensuring consistent typography with other price elements.

Details:
1. `formatPriceInfo`
   – Changed `{t('分组')}:` to `{t('分组')}` for a cleaner look.
   – Keeps spacing intact between label and selected group name.
2. No functional impact; purely visual polish.
2025-08-10 17:17:49 +08:00
t0ng7u
dbde044213 📱 style: Hide vendor introduction on mobile devices
Summary:
• Updated `PricingTopSection.jsx` to conditionally render `PricingVendorIntroWithSkeleton` only when `isMobile` is false.

Details:
1. Wrapped vendor-intro block in `!isMobile` check, preventing unnecessary content on small screens.
2. Kept desktop experience unchanged; no impact on other features.
3. Lint check passed with no new issues.

Result:
Cleaner mobile UI with improved performance and visual focus.
2025-08-10 14:10:50 +08:00
t0ng7u
870132a5cb feat: Add tag-based filtering & refactor filter counts logic
Overview:
• Introduced a new “Model Tag” filter across pricing screens
• Refactored `usePricingFilterCounts` to eliminate duplicated logic
• Improved tag handling to be case-insensitive and deduplicated
• Extended utilities to reset & persist the new filter

Details:
1. Added `filterTag` state to `useModelPricingData` and integrated it into all filtering paths.
2. Created reusable `PricingTags` component using `SelectableButtonGroup`.
3. Incorporated tag filter into `PricingSidebar` and mobile `PricingFilterModal`, including reset support.
4. Enhanced `resetPricingFilters` (helpers/utils) to restore tag filter defaults.
5. Refactored `usePricingFilterCounts.js`:
   • Centralized predicate `matchesFilters` to remove redundancy
   • Normalized tag parsing via `normalizeTags` helper
   • Memoized model subsets with concise filter calls
6. Updated lints – zero errors after refactor.

Result:
Users can now filter models by custom tags with consistent UX, and internal logic is cleaner, faster, and easier to extend.
2025-08-10 14:05:25 +08:00
t0ng7u
ffa898c52d 🐛 fix(PricingCardView): hide placeholder dash when no custom tags
Previously, the card view displayed a “-” whenever a model had no custom tags,
because `renderLimitedItems` returned a dash for an empty array.
Now the function is only invoked when `customTags.length > 0`, removing the
unwanted placeholder and keeping the UI clean.

File affected:
- web/src/components/table/model-pricing/view/card/PricingCardView.jsx
2025-08-10 13:45:16 +08:00
t0ng7u
cdf27d60be fix: prevent model name flicker when closing SideSheet
- Delay clearing selectedModel until SideSheet close animation completes
- Prevents brief display of 'AI/Unknown Model' text during closing transition
- Improves user experience by eliminating visual flicker
- Uses 300ms timeout matching Semi UI default animation duration
2025-08-10 13:41:19 +08:00
CaIon
1cc81deb69 feat: Enhance EditChannelModal with JSONEditor key updates and input reset
- 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.
2025-08-10 12:22:18 +08:00
Calcium-Ion
f942361f7b Merge pull request #1496 from Bliod-Cook/feat-linuxdo-minumum-trust-level
feat: allow admin to restrict the minimum linuxdo trust level to register
2025-08-10 10:27:40 +08:00
Calcium-Ion
d6b03d4760 Merge pull request #1541 from QuantumNous/fluent-read
feat: added "流畅阅读" (FluentRead) as a new chat provider option.
2025-08-10 10:26:22 +08:00
t0ng7u
cb75e25a1a feat: Add model icon support across backend and UI; prefer model icon over vendor; add icon column in Models table
Backend:
- Model: Add `icon` field to `model.Model` (gorm: varchar(128)); auto-migrated via GORM.
- Pricing API: Extend `model.Pricing` with `icon` and populate from model meta in `GetPricing()`.

Frontend:
- EditModelModal: Add `icon` input (with @lobehub/icons helper link); wire into init/load/submit flows.
- ModelHeader / PricingCardView: Prefer rendering `model.icon`; fallback to `vendor_icon`; final fallback to initials avatar.
- Models table: Add leading “Icon” column, rendering `model.icon` or `vendor` icon via `getLobeHubIcon`.

Notes:
- Backward-compatible. Existing data without `icon` remain unaffected.
- No manual SQL needed; column is added by AutoMigrate.

Affected files:
- model/model_meta.go
- model/pricing.go
- web/src/components/table/models/modals/EditModelModal.jsx
- web/src/components/table/model-pricing/modal/components/ModelHeader.jsx
- web/src/components/table/model-pricing/view/card/PricingCardView.jsx
- web/src/components/table/models/ModelsColumnDefs.js
2025-08-10 01:38:59 +08:00
t0ng7u
9572e16dcb feat: Support dot‑chained props for LobeHub icons
- render.js: Enhance getLobeHubIcon to parse dot‑chained props, e.g.:
  - OpenAI.Avatar.type={'platform'}
  - OpenRouter.Avatar.shape={'square'}
  - Parses booleans/numbers/strings and {…} wrappers; keeps the 2nd arg `size` unless overridden by chain props. Backward compatible.
- EditVendorModal.jsx: Update UI copy — simplify placeholder; document chain‑parameter examples in extra text with doc link.
- en.json: Fix invalid escape sequences in the new i18n string to satisfy linter.

No behavioral changes outside icon rendering; lints pass.
2025-08-10 01:18:36 +08:00
t0ng7u
459fce196f 🍎 chore: modify pagination pageSizeOpts 2025-08-10 00:58:17 +08:00
t0ng7u
ada434fb20 🎨 refactor: MultiKeyManageModal: cleaner stats UI, remove chart, integrate toolbar/pagination, and improve UX
- Replace custom dots with Semi Badge types (success/danger/warning); add compact Progress bars
- Remove pie chart and related deps/config; move total key count and mode tags into the modal title
- Rework header using Row/Col; three equal stat cards (enabled/manual-disabled/auto-disabled)
- Integrate toolbar into Table title; wrap content with Card; use Table’s native empty state
- Make “Enable All” conditional (hidden when all keys are enabled), mirroring “Disable All”
- Unify numeric typography (current/total same size) for better readability
- Default page size set to 10; fallback to 10 when backend page_size is absent; page-size options: 10/20/50/100
- Cleanup imports and dead code (remove VChart and pie-spec logic)
- Minor spacing polish (extra bottom margin before table), no footer buttons
2025-08-10 00:55:18 +08:00
t0ng7u
0727353afa 💄 style(ui): replace inline gradients with reusable pastel blur balls; improve dark mode
- Introduce a global CSS utility `with-pastel-balls` in `web/src/index.css`, rendering pastel “blur balls” via ::before with CSS variables (`--pb1..--pb4`, `--pb-opacity`, `--pb-blur`) for easy theming.
- Apply the utility to pricing header cards and skeletons:
  - `web/src/components/table/model-pricing/layout/header/PricingVendorIntro.jsx`
  - `web/src/components/table/model-pricing/layout/header/PricingVendorIntroSkeleton.jsx`
- Remove per-component inline `linear-gradient(...)` backgrounds and redundant absolute-positioned decoration nodes to reduce duplication.
- Dark mode:
  - Keep the same pastel palette (pink/lavender/mint/peach).
  - Increase visibility with `--pb-opacity: 0.36`, `--pb-blur: 65px`, and `mix-blend-mode: screen`.
- No functional logic changes; UI-only. Lint passes.

Affected files:
- web/src/index.css
- web/src/components/table/model-pricing/layout/header/PricingVendorIntro.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntroSkeleton.jsx
2025-08-09 21:40:32 +08:00
CaIon
fd2ff2a973 feat: update Fluent Read link handling in sidebar to improve chat item filtering 2025-08-09 21:06:25 +08:00
CaIon
a47fc5a76b feat: enhance JSON marshaling for Message and skip Fluent Read links in chat items 2025-08-09 20:58:28 +08:00
CaIon
8639699d49 feat: improve FluentRead notification handling and user prompts 2025-08-09 18:37:08 +08:00
CaIon
55dbdba636 feat: add FluentRead support in chat configuration 2025-08-09 18:26:45 +08:00
CaIon
24860fdc05 feat: update channel label to indicate deprecation and suggest alternative 2025-08-09 17:51:54 +08:00
CaIon
919eacd907 Merge remote-tracking branch 'origin/alpha' into alpha 2025-08-09 17:02:20 +08:00
CaIon
4cec55c9a4 feat: enhance TokensPage and useTokensData to support Fluent integration and notifications 2025-08-09 17:02:06 +08:00
t0ng7u
aa8ec92976 🧹 Refactor: remove redundant code and simplify renderers
- Users table (UsersColumnDefs.js):
  - Remove unused quota calculations from the status renderer
  - Keep status Tag minimal; tooltip shows request count only
  - No functional changes

- Tokens table (TokensColumnDefs.js):
  - Simplify chats menu parsing from localStorage; remove redundant flags/loops
  - Remove unused variables and console statements
  - Keep error handling via showError; preserve existing operations behavior

- General:
  - Codebase tidying only; no UI/logic changes beyond cleanup
  - Lint passes successfully
2025-08-09 16:51:09 +08:00
t0ng7u
44da9c9a28 style(ui): Replace switches with buttons; add quota column with Popover; cleanup
- Tokens/Users tables:
  - Replaced status Switch with explicit Enable/Disable buttons in the operation column
  - Unified button styles with Channels/Models (Disable: danger + small; Enable: default + small)
  - Status column now shows a small Tag only; standardized labels (Enabled/Disabled/etc.); removed usage info

- New "Remaining/Total Quota" column:
  - Wrapped in a white Tag; shows Remaining/Total with a progress bar
  - Replaced Tooltip with Popover; contents use Typography.Paragraph with copyable values
  - Copyable content excludes percentages (only numeric quota values are copied)
  - Added padding to Popover content for better readability

- Tokens specifics:
  - For unlimited quota, show a white Tag "Unlimited quota" with a Popover that displays copyable "Used quota"

- Cleanup:
  - Removed Switch imports/handlers and unused code paths
  - Eliminated console logs and redundant flags; simplified chats parsing
  - Removed quota calculations from status renderers

Files:
- web/src/components/table/tokens/TokensColumnDefs.js
- web/src/components/table/users/UsersColumnDefs.js
2025-08-09 16:47:14 +08:00
t0ng7u
a5cbef1a61 style(JSONEditor): add AGPL-3.0 license header, clean imports & refine Banner UI
* Added full GNU Affero General Public License v3 header at the top of `JSONEditor.js`.
* Removed unused `IconCode` and `IconRefresh` imports to eliminate dead code.
* Set `closeIcon={null}` and applied `!rounded-md` class for `Banner`, improving visual consistency and preventing unintended dismissal.
* Normalized whitespace and line-breaks for better readability and lint compliance.
2025-08-09 14:08:28 +08:00
同語
ae22ba593a feat: optimized JSONEditor in duplicate key handling
Merge pull request #1534 from HynoR/feat/je
2025-08-09 13:22:16 +08:00
CaIon
2a804b6c02 feat: add system prompt override functionality in channel settings and request handling #1468 2025-08-09 12:53:06 +08:00
Calcium-Ion
ec28671aed Merge pull request #1429 from feitianbubu/pr/video-preview-modal
feat: add video preview modal
2025-08-09 11:37:19 +08:00
Calcium-Ion
2efc133997 Merge pull request #1465 from fangzhengjin/alpha
fix: 当OIDC的AuthUrl带有param时,跳转参数拼接错误
2025-08-09 11:34:55 +08:00
t0ng7u
2fc0d7b2a7 📱 feat(ui): enhance mobile pagination in PricingCardView
* Integrate `useIsMobile` hook to detect mobile devices.
* Pagination now automatically:
  * sets `size="small"` on mobile screens
  * enables `showQuickJumper` for quicker navigation on small screens
* Desktop behaviour remains unchanged.
2025-08-09 10:14:35 +08:00
t0ng7u
3a9e394814 feat: Extend endpoint templates to cover all native endpoints
This commit updates the quick-fill endpoint templates used in the model and pre-fill group editors:

• `EditModelModal.jsx`
• `EditPrefillGroupModal.jsx`

Key changes
1. Added missing default endpoints defined in `common/endpoint_defaults.go`.
   - `openai-response`
   - `gemini`
   - `jina-rerank`
2. Ensured each template entry includes both `path` and `method` for clarity.

Benefits
• Provides one-click access to every built-in upstream endpoint, reducing manual input.
• Keeps the UI definitions in sync with backend defaults, preventing mismatch errors.
2025-08-09 09:33:13 +08:00
t0ng7u
3d9d3da1ae 🔧 fix(pricing): synchronize group ratio in Table & Card views with sidebar selection
Problem
Choosing a different token-group in the pricing sidebar only updated the filter but did **not** refresh the displayed group ratio in both the Table (`@table/`) and Card (`@card/`) views. The callback used by the sidebar changed `filterGroup` yet left `selectedGroup` untouched, so ratio columns/cards kept showing the previous value.

Solution
• `PricingSidebar.jsx`
  – Accept new prop `handleGroupClick` (from `useModelPricingData`).
  – Forward this callback to `PricingGroups` (`setFilterGroup={handleGroupClick}`) while retaining `setFilterGroup` for reset logic.
  – Keeps both `filterGroup` filtering and `selectedGroup` state in sync via the single unified handler.

Result
Switching groups in the sidebar now simultaneously updates:
1. the model list filtering, and
2. the ratio information shown in both pricing Table and Card views.

No UI/UX regression; linter passes.
2025-08-09 08:58:36 +08:00
t0ng7u
8abd764eca 🎨 chore(sidebar): swap “Channel Management” and “Model Management” positions in admin menu
The sidebar’s admin section now displays “Channel Management” before “Model Management” to better reflect common user workflows and improve navigation clarity.

Details:
• Updated `web/src/components/layout/SiderBar.js`
  – Re-ordered items in `adminItems` array so `channel` precedes `models`.
• No logic or route changes; this is purely a UI ordering adjustment.

This change enhances usability for administrators by presenting frequently accessed channel settings first.
2025-08-09 08:50:39 +08:00
HynoR
2471367c92 feat: optimized Json Visual Editor(JSONEditor) when detected duplicate key 2025-08-08 19:00:02 +08:00
t0ng7u
c6bb1dcc0e 🔧 refactor(pricing): render “auto” routing chain only when relevant & remove unused prop
Changes
1. ModelPricingTable.jsx
   • Compute `autoChain` as the intersection of `autoGroups` and the model’s `enable_groups` (order preserved).
   • Display the chain banner only when `autoChain.length > 0`; banner shows the reduced path (e.g. `a → c → e`).
   • Dropped obsolete `selectedGroup` prop; all callers updated.

2. ModelDetailSideSheet.jsx / PricingPage.jsx
   • Removed forwarding of deleted `selectedGroup` prop.

Outcome
– “Auto group routing” appears only for models that actually participate in the chain, avoiding empty or irrelevant banners.
– Codebase simplified by eliminating an unused prop.
2025-08-08 15:11:31 +08:00
t0ng7u
1690b05629 🚀 feat(pricing): clarify “auto” group routing chain and exclude it from price table
Detailed changes
Backend
• `controller/pricing.go` now includes `auto_groups` in `/api/pricing` response, sourced from `setting.AutoGroups`.

Frontend
• `useModelPricingData.js`
  – Parses `auto_groups` and exposes `autoGroups` state.
• `PricingPage.jsx` → `ModelDetailSideSheet.jsx` → `ModelPricingTable.jsx`
  – Thread `autoGroups` through component tree.
• `ModelPricingTable.jsx`
  – Removes deprecated `getGroupDescription` / `Tooltip`.
  – Filters out `auto` when building price table rows.
  – Renders a descriptive banner: “auto 分组调用链路 → auto → group1 → …”, clarifying fallback order without showing prices.
• Minor i18n tweak: adds `auto分组调用链路` key for the banner text.

Why
Users were confused by the “auto” tag appearing alongside regular groups with no price.
This change:
1. Makes the routing chain explicit.
2. Keeps the pricing table focused on billable groups.

No breaking API changes; existing clients can ignore the new `auto_groups` field.
2025-08-08 14:49:55 +08:00
t0ng7u
d0fb54fbfe feat(web): add model prefill group quick-add buttons to channel models selector
- 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.
2025-08-08 04:48:18 +08:00
t0ng7u
346b869d60 💄 ui: adjust column layout in pricing table
- Move model price column to fixed right position
- Convert endpoint types column from fixed to regular column
- Reorder columns: endpoint types now appears before ratio column
- Improve table layout and user experience for pricing data viewing

Changes made to web/src/components/table/model-pricing/view/table/PricingTableColumns.js:
* Removed `fixed: 'right'` from endpointColumn
* Added `fixed: 'right'` to priceColumn
* Updated column order in the columns array
2025-08-08 04:41:46 +08:00