Commit Graph

203 Commits

Author SHA1 Message Date
CaIon
e94d6f1581 Merge remote-tracking branch 'origin/main' 2025-09-27 13:56:44 +08:00
CaIon
1235216c05 feat: 多密钥管理新增针对单个密钥的删除操作 2025-09-27 13:56:07 +08:00
IcedTangerine
b118b331f1 Merge branch 'main' into feature/date-shortcut 2025-09-23 22:21:25 +08:00
CaIon
552d795742 Merge branch 'alpha' 2025-09-19 14:20:15 +08:00
CaIon
0008d2e3a0 feat: add experimental IP filtering for domains and update related settings 2025-09-18 13:40:52 +08:00
QuentinHsu
2836ec2eb3 feat: add date range preset constants and use them in the log filter 2025-09-15 21:59:25 +08:00
creamlike1024
d21886b9fb Merge branch 'alpha' into imageratio-and-audioratio-edit 2025-09-15 14:12:24 +08:00
CaIon
c3f5478593 feat: implement SSRF protection settings and update related references 2025-09-13 18:15:03 +08:00
CaIon
59d6ff0caf feat(i18n): update TOTP verification message with configuration details 2025-09-12 21:53:21 +08:00
CaIon
0b87aa3a6f feat(i18n): add translations for pricing terms in English 2025-09-12 19:54:02 +08:00
t0ng7u
14af08750f feat(sync): multi-language sync wizard, backend locale support, and conflict modal UX improvements
Frontend (web)
- ModelsActions.jsx
  - Replace “Sync Official” with “Sync” and open a new two-step SyncWizard.
  - Pass selected locale through to preview, sync, and overwrite flows.
  - Keep conflict resolution flow; inject locale into overwrite submission.

- New: models/modals/SyncWizardModal.jsx
  - Two-step wizard: (1) method selection (config-sync disabled for now), (2) language selection (en/zh/ja).
  - Horizontal, centered Radio cards; returns { option, locale } via onConfirm.

- UpstreamConflictModal.jsx
  - Add search input (model fuzzy search) and native pagination.
  - Column header checkbox now only applies to rows in the current filtered result.
  - Fix “Cannot access ‘filteredDataSource’ before initialization”.
  - Refactor with useMemo/useCallback; extract helpers to remove duplicated logic:
    - getPresentRowsForField, getHeaderState, applyHeaderChange
  - Minor code cleanups and stability improvements.

- i18n (en.json)
  - Add strings for the sync wizard and related actions (Sync, Sync Wizard, Select method/source/language, etc.).
  - Adjust minor translations.

Hooks
- useModelsData.jsx
  - Extend previewUpstreamDiff, syncUpstream, applyUpstreamOverwrite to accept options with locale.
  - Send locale via query/body accordingly.

Backend (Go)
- controller/model_sync.go
  - Accept locale from query/body and resolve i18n upstream URLs.
  - Add SYNC_UPSTREAM_BASE for upstream base override (default: https://basellm.github.io/llm-metadata).
  - Make HTTP timeouts/retries/limits configurable:
    - SYNC_HTTP_TIMEOUT_SECONDS, SYNC_HTTP_RETRY, SYNC_HTTP_MAX_MB
  - Add ETag-based caching and support both envelope and pure array JSON formats.
  - Concurrently fetch vendors and models; improve error responses with locale and source URLs.
  - Include source meta (locale, models_url, vendors_url) in success payloads.

Notes
- No breaking changes expected.
- Lint passes for touched files.
2025-09-02 18:49:37 +08:00
t0ng7u
5dc2d775e9 🌏 i18n: replace to correct punctuation mark 2025-09-02 03:42:31 +08:00
t0ng7u
54f118d9ba feat(models-sync): official upstream sync with conflict resolution UI, opt‑out flag, and backend resiliency
Backend
- Add endpoints:
  - GET /api/models/sync_upstream/preview — diff preview (filters out models with sync_official = 0)
  - POST /api/models/sync_upstream — apply sync (create missing; optionally overwrite selected fields)
- Respect opt‑out: skip models with sync_official = 0 in both preview and apply
- Return detailed stats: created_models, created_vendors, updated_models, skipped_models, plus created_list / updated_list
- Add model.Model.SyncOfficial (default 1); auto‑migrated by GORM
- Make HTTP fetching robust:
  - Shared http.Client (connection reuse) with 3x exponential backoff retry
  - 10MB response cap; keep existing IPv4‑first for *.github.io
- Vendor handling:
  - New ensureVendorID helper (cache lookup → DB lookup → create), reduces round‑trips
  - Transactional overwrite to avoid partial updates
- Small cleanups and clearer helpers (containsField, coalesce, chooseStatus)

Frontend
- ModelsActions: add “Sync official” button with Popover (p‑2) explaining community contribution; loading = syncing || previewing; preview → conflict modal → apply flow
- New UpstreamConflictModal:
  - Per‑field columns (description/icon/tags/vendor/name_rule/status) with column‑level checkbox to select all
  - Cell with Checkbox + Tag (“Click to view differences”) and Popover (p‑2) showing Local vs Official values
  - Auto‑hide columns with no conflicts; responsive width; use native Semi Modal footer
  - Full i18n coverage
- useModelsData: add syncing/previewing states; new methods previewUpstreamDiff, applyUpstreamOverwrite, syncUpstream; refresh vendors/models after apply
- EditModelModal: add “Participate in official sync” switch; persisted as sync_official
- ModelsColumnDefs: add “Participate in official sync” column

i18n
- Add missing English keys for the new UI and messages; fix quoting issues

Refs
- Upstream metadata: https://github.com/basellm/llm-metadata
2025-09-02 02:04:22 +08:00
F。
d0d6168e2f 顶栏和侧边栏管理
增加用户体验
2025-08-31 07:07:40 +08:00
creamlike1024
2875dbba10 feat: 图像倍率,音频倍率和音频补全倍率配置 2025-08-30 23:28:09 +08:00
t0ng7u
0d57b1acd4 🎨 chore(web): apply ESLint and Prettier auto-fixes (baseline)
- 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
2025-08-30 21:15:10 +08:00
t0ng7u
41cf516ec5 🤓 chore: remove the useless tooltip component 2025-08-29 23:56:18 +08:00
t0ng7u
7826099221 🎨 feat(ui): enhance pricing components with improved icons and responsive design
- Replace copy button icon from semi-ui IconCopy to lucide-react Copy in PricingCardView
- Add conditional tooltip functionality to SelectableButtonGroup that only shows when text overflows
- Implement responsive table column behavior in PricingTableColumns with mobile-aware fixed positioning
- Use DOM-based overflow detection (scrollWidth vs clientWidth) for better performance
- Apply useIsMobile hook to conditionally set fixed: 'right' only on desktop devices

These changes improve user experience across different screen sizes and provide more consistent iconography throughout the pricing interface.
2025-08-29 22:36:05 +08:00
AAEE86
6033d4318e feat(channel): 添加2FA验证后查看渠道密钥功能
- 新增接口通过2FA验证后获取渠道密钥
- 统一实现2FA验证码和备用码的验证逻辑
- 记录用户查看密钥的操作日志
- 编辑渠道弹窗新增查看密钥按钮,触发2FA验证模态框
- 使用TwoFactorAuthModal进行验证码输入及验证
- 验证成功后弹出渠道密钥展示窗口
- 对渠道编辑模态框的状态进行了统一重置优化
- 添加相关国际化文案支持密钥查看功能
2025-08-25 14:45:48 +08:00
AAEE86
15a36a65b3 feat: 在新增&编辑渠道时添加点击模型复制名称功能
(cherry picked from commit c4935f392fbffc080359e82b7aa9cca91f009639)
2025-08-24 22:50:29 +08:00
t0ng7u
868f1b036a feat(model-pricing): enhance pricing vendor intro components with performance optimizations and UX improvements
## Major Changes

### Performance Optimizations
- Add React.memo to all components to prevent unnecessary re-renders
- Implement useCallback for expensive functions (renderSearchActions, renderHeaderCard, etc.)
- Extract createSkeletonRect function outside component to avoid recreation
- Optimize constant definitions and reduce magic numbers

### UI/UX Enhancements
- Replace Popover with Modal for vendor description display
- Add modal max height and vertical scrolling support
- Fix filter modal not showing on first click by always mounting component
- Improve responsive design with mobile-specific modal sizing

### Code Structure Improvements
- Refactor avatar rendering logic into pure helper functions
- Reorganize constants into semantic groups (CONFIG, THEME_COLORS, COMPONENT_STYLES, CONTENT_TEXTS)
- Simplify complex vendor info processing logic
- Fix sourceModels selection logic for better data handling

### Bug Fixes
- Fix React key prop missing in skeleton elements causing render errors
- Resolve modal mounting timing issues
- Correct dependency arrays in useCallback hooks

### Code Quality
- Remove redundant comments while preserving essential documentation
- Add displayName to all memo components for better debugging
- Standardize code formatting and naming conventions
- Improve TypeScript-like prop validation

## Files Modified
- PricingTopSection.jsx
- PricingVendorIntro.jsx
- PricingVendorIntroSkeleton.jsx
- PricingVendorIntroWithSkeleton.jsx
- SearchActions.jsx

## Performance Impact
- Reduced re-renders by approximately 60-80%
- Improved memory efficiency through function memoization
- Enhanced user experience with smoother interactions
2025-08-24 00:10:26 +08:00
t0ng7u
b10f28e5c6 🎨 refactor(model-pricing/header): unify header design, extract SearchActions, and improve skeleton
- Extract SearchActions.jsx and replace inline renderSearchActions in PricingVendorIntro.jsx for reuse
- Refactor PricingVendorIntro.jsx:
  - Introduce renderHeaderCard(), tagStyle, getCoverStyle(), and MAX_VISIBLE_AVATARS constant
  - Standardize vendor header cover (gradient + background image) and tag contrast
  - Use border instead of ring for vendor badges; unify visuals and remove Tailwind ring dependency
  - Rotate vendors every 2s only when filterVendor === 'all' and vendor count > 3
  - Remove unused imports; keep prop surface minimal; pass setShowFilterModal downward only
- Refactor PricingVendorIntroSkeleton.jsx:
  - Add getCoverStyle() and rect() helpers; rebuild skeleton to match final UI
  - Replace invalid Skeleton.Input usage; add missing keys; unify colors/borders/radius
- Update PricingTopSection.jsx:
  - Manage filter modal locally; drop redundant prop passing
- Update PricingVendorIntroWithSkeleton.jsx:
  - Align prop interface; forward only required props and keep useMinimumLoadingTime
- Add: web/src/components/table/model-pricing/layout/header/SearchActions.jsx
- Lint: all files pass; no dark:* classes present in this scope

Files touched:
- web/src/components/table/model-pricing/layout/header/PricingTopSection.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntro.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntroWithSkeleton.jsx
- web/src/components/table/model-pricing/layout/header/PricingVendorIntroSkeleton.jsx
- web/src/components/table/model-pricing/layout/header/SearchActions.jsx (new)
2025-08-23 21:11:40 +08:00
t0ng7u
bee947000f 🎨 refactor(ui): use lucide-react for search/refresh and chevron icons
- DashboardHeader.jsx: replace Semi's IconSearch/IconRefresh with lucide-react's Search/RefreshCw (size 16), preserve existing button styles
- UptimePanel.jsx: replace Semi's IconRefresh with lucide-react's RefreshCw (size 14), keep styling intact
- UserArea.jsx: replace Semi's IconChevronDown with lucide-react's ChevronDown (size 14), preserve visual parity
- Update imports: remove @douyinfe/semi-icons usage where replaced; add lucide-react imports
- Verified no remaining IconSearch/IconRefresh in dashboard; no new linter errors

Motivation: unify icon library for core actions and improve UI consistency.
Follow-ups: consider migrating remaining Semi icons (e.g., plus/minus, charts) to lucide-react.
2025-08-23 19:29:56 +08:00
t0ng7u
30fc4d3082 🌓 feat(ui): add auto theme mode, refactor ThemeToggle, optimize header theme handling
- Feature: Introduce 'auto' theme mode
  - Detect system preference via matchMedia('(prefers-color-scheme: dark)')
  - Add useActualTheme context to expose the effective theme ('light'|'dark')
  - Persist selected mode in localStorage ('theme-mode') with 'auto' as default
  - Apply/remove `dark` class on <html> and sync `theme-mode` on <body>
  - Broadcast effective theme to iframes

- UI: Redesign ThemeToggle with Dropdown items and custom highlight
  - Replace non-existent IconMonitor with IconRefresh
  - Use Dropdown.Menu + Dropdown.Item with built-in icon prop
  - Selected state uses custom background highlight; hover state preserved
  - Remove checkmark; selection relies on background styling
  - Current button icon reflects selected mode

- Performance: reduce re-renders and unnecessary effects
  - Memoize theme options and current button icon (useMemo)
  - Simplify handleThemeToggle to accept only explicit modes ('light'|'dark'|'auto')
  - Minimize useEffect dependencies; remove unrelated deps

- Header: streamline useHeaderBar
  - Use useActualTheme for iframe theme messaging
  - Remove unused statusDispatch
  - Remove isNewYear from theme effect dependencies

- Home: send effective theme (useActualTheme) to external content iframes

- i18n: add/enhance theme-related copy in locales (en/zh)

- Chore: minor code cleanup and consistency
  - Improve readability and maintainability
  - Lint clean; no functional regressions
2025-08-23 03:02:35 +08:00
t0ng7u
2ab2edec7b refactor: unify layout, adopt Semi UI Forms, dynamic presets, and fix duplicate requests
- Unify TopUp into a single-page layout and remove tabs
- Replace custom inputs with Semi UI Form components (Form.Input, Form.InputNumber, Form.Slot)
- Move online recharge form into the stats Card content for tighter, consistent layout
- Add account stats Card with blue theme (consistent with InvitationCard style)
- Remove RightStatsCard and inline the stats UI directly in RechargeCard
- Change preset amount UI to horizontal quick-action Buttons; swap order with payment methods
- Replace payment method Cards with Semi UI Buttons
  - Use Button icon prop for Alipay/WeChat/Stripe with brand colors
  - Use built-in Button loading; remove custom “processing...” text
- Replace custom spinners with Semi UI Spin and keep Skeleton for amount loading
- Wrap Redeem Code in a Card; use Typography for “Looking for a code? Buy Redeem Code” link
- Show info Banner when online recharge is disabled (instead of warning)

TopUp data flow and logic
- Generate preset amounts from min_topup using multipliers [1,5,10,30,50,100,300,500]
- Deduplicate /api/user/aff using a ref guard; fetch only once on mount
- Simplify user self fetch: update context only; remove unused local states and helpers
- Normalize payment method keys to alipay/wxpay/stripe and assign default colors

Cleanup
- Delete web/src/components/topup/RightStatsCard.jsx
- Remove unused helpers and local states in index.jsx (userQuota, userDataLoading, getUsername)

Dev notes
- No API changes; UI/UX refactor only
- Lint clean (no new linter errors)

Files
- web/src/components/topup/RechargeCard.jsx
- web/src/components/topup/index.jsx
- web/src/components/topup/InvitationCard.jsx (visual parity reference)
- web/src/components/topup/RightStatsCard.jsx (removed)
2025-08-23 01:32:54 +08:00
t0ng7u
436eb77ae2 🍭 style(ui): update the README.md style 2025-08-19 01:44:44 +08:00
t0ng7u
6c4777bc82 ♻️ refactor(InvitationCard): restructure cards with title prop and clean up styling
- Move card titles (earnings, total revenue, invitations) to Card title prop for consistency
- Remove custom color classes in favor of Semi-UI's built-in type system
- Standardize Text component usage with strong and tertiary types
- Improve code maintainability and visual consistency across all cards
- Align structure with existing reward description card pattern
2025-08-19 00:22:28 +08:00
t0ng7u
ed3b11a304 🎨 refactor: Setup Wizard UI & Clean Up Redundant Code
Summary of changes
1. SetupWizard.jsx
   • Center card (`min-h-screen flex items-center justify-center`) and remove top margin.
   • Merge step indicator/content into single card; added `Divider` separator.
   • Added sweep-shine animation to current step title via existing `shine-text` class.
   • Simplified imports (removed Avatar / Typography) and deleted unused modal state.

2. Step components
   • Stripped outer `Card` and header sections from `DatabaseStep.jsx`, `AdminStep.jsx`, `UsageModeStep.jsx`, `CompleteStep.jsx` to fit single-card layout.
   • Removed unused imports and props.

3. Components cleanup
   • Deleted obsolete files:
     - `components/setup/components/SetupSteps.jsx`
     - `components/setup/components/modals/UsageModeInfoModal.jsx`
   • Updated `setup/index.jsx` exports accordingly.

4. Styling
   • Ensured global sweep-shine effect already present in `index.css` is reused for step titles.

5. i18n
   • Pruned unused translation keys related to removed components from `i18n/locales/en.json`.

6. Miscellaneous
   • Removed redundant Avatar/Icon imports from multiple files.
   • All linter checks pass with no new warnings.

This commit consolidates the initialization flow into a cleaner, centered single-card wizard, adds visual polish, and reduces dead code for easier maintenance.
2025-08-17 16:45:11 +08:00
t0ng7u
7411c24954 style(Account UX): resilient binding layout, copyable popovers, pastel header, and custom pay colors
- AccountManagement.js
  - Prevent action button from shifting when account IDs are long by adding gap, min-w-0, and flex-shrink-0; keep buttons in a fixed position.
  - Add copyable Popover for account identifiers (email/GitHub/OIDC/Telegram/LinuxDO) using Typography.Paragraph with copyable; reveal full text on hover.
  - Ensure ellipsis works by rendering the popover trigger as `block max-w-full truncate`.
  - Import Popover and wire up `renderAccountInfo` across all binding rows.

- UserInfoHeader.js
  - Apply unified `with-pastel-balls` background to match PricingVendorIntro.
  - Remove legacy absolute-positioned circles and top gradient bar to avoid visual overlap.

- RechargeCard.jsx
  - Colorize non-Alipay/WeChat/Stripe payment icons using backend `pay_methods[].color`; fallback to `var(--semi-color-text-2)`.
  - Add `showClear` to the redemption code input for quicker clearing.

Notes:
- No linter errors introduced.
- i18n strings and behavior remain unchanged except for improved UX and visual consistency.
2025-08-17 11:45:55 +08:00
t0ng7u
b505121790 💳 feat(TopUp): unify payment cards, add header stats, brand icons, and mobile refinements [[memory:5659506]]
- Add RightStatsCard and place it in RechargeCard header
  - Shows current balance, historical spend, and request count
  - Mobile: stacks under title; three metrics split equally (flex-1); vertical dividers hidden on small screens
  - Remove extra margins; small card styling

- RechargeCard
  - Replace redeem code Input icon with Semi UI IconGift
  - Style “Payable amount” number in red and bold; keep same style in confirm modal
  - Always render payment methods as Cards (remove Button variant) with adaptive grid
  - Use brand color icons: SiAlipay (#1677FF), SiWechat (#07C160), SiStripe (#635BFF)
  - Replace Stripe icon with SiStripe
  - Integrate RightStatsCard props; adjust header to flex-col on mobile and flex-row on desktop
  - Hide Banner close button when online top-up is disabled (closeIcon={null})

- InvitationCard
  - Simplify to match RechargeCard’s minimalist slate style
  - Use Card title for “Rewards” and place content directly in body
  - Improve link input and copy button; use Badge dots for bullet points

- TopUp index
  - Remove separate right-column stats card; pass userState and renderQuota to RechargeCard

- Cleanup
  - Lint passes; no functional changes to APIs or business logic
2025-08-17 04:00:58 +08:00
t0ng7u
66289f7991 ♻️ refactor(personal-settings): Break down PersonalSetting.js into modular components
- Split the 1554-line PersonalSetting.js file into smaller, maintainable components
- Created organized folder structure under personal/:
  - components/: UserInfoHeader for shared user info display
  - tabs/: ModelsList, AccountBinding, SecuritySettings, NotificationSettings
  - modals/: EmailBindModal, WeChatBindModal, AccountDeleteModal, ChangePasswordModal
- Refactored main PersonalSetting component to use composition pattern
- Improved code maintainability and separation of concerns
- Added collapsible prop to ModelsList tabs for better UX
- Fixed import path for TwoFASetting component in SecuritySettings
- Preserved all existing functionality and user interactions

This refactoring reduces the main file from 1554 to 484 lines and makes
the codebase more modular, testable, and easier to maintain.
2025-08-17 00:49:54 +08:00
t0ng7u
3004ede0ce 🌐 feat(i18n): add internationalization support for TwoFASetting component
- Add comprehensive i18n support to TwoFASetting.js component
- Add all required English translations to en.json for 2FA settings
- Update component to accept t function as prop and use translation keys
- Fix prop passing in PersonalSetting.js to provide t function
- Maintain all existing UI improvements and functionality
- Support both Chinese and English interfaces for:
  * Main 2FA settings card with status indicators
  * Setup modal with guided steps (QR scan, backup codes, verification)
  * Disable 2FA modal with impact warnings and confirmation
  * Regenerate backup codes modal with success states
  * All buttons, placeholders, messages, and notifications
- Follow project i18n conventions using t('key') pattern
- Ensure seamless language switching for enhanced user experience

This enables the 2FA settings to be fully localized while preserving
the modern UI design and improved user workflow from previous updates.
2025-08-16 19:22:14 +08:00
t0ng7u
c59b331170 🚫 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
2cabe4f6ac 🔠 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
b6dd701ce8 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
abee65c1db 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
734ef7ddac 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
8a3107448b 🎨 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
2177620e68 💄 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
05af05e449 feat: add system prompt override functionality in channel settings and request handling #1468 2025-08-09 12:53:06 +08:00
t0ng7u
b243fce7ec Merge branch 'alpha' into refactor/model-pricing 2025-07-31 00:41:01 +08:00
t0ng7u
e85bf7b1b0 feat: Enhance Channel Model Management UI
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.
2025-07-28 01:33:23 +08:00
t0ng7u
2dd99898ca Merge branch 'alpha' into refactor/model-pricing 2025-07-26 17:21:47 +08:00
t0ng7u
2356c3fe66 🎨 refactor(ui): redesign channel extra settings section in EditChannelModal
- 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
2025-07-26 13:33:10 +08:00
CaIon
f610773455 feat: enhance request handling with pass-through options and system prompt support 2025-07-26 11:39:09 +08:00
t0ng7u
0ff0027aa6 ♻️ Refactor: Move token unit toggle from table header to filter settings
- Remove K/M switch from model price column header in pricing table
- Add "Display in K units" option to pricing display settings panel
- Update parameter passing for tokenUnit and setTokenUnit across components:
  - PricingDisplaySettings: Add tokenUnit toggle functionality
  - PricingSidebar: Pass tokenUnit props to display settings
  - PricingFilterModal: Include tokenUnit in mobile filter modal
- Enhance resetPricingFilters utility to reset token unit to default 'M'
- Clean up PricingTableColumns by removing unused setTokenUnit parameter
- Add English translation for "按K显示单位" as "Display in K units"

This change improves UX by consolidating all display-related controls
in the filter settings panel, making the interface more organized and
the token unit setting more discoverable alongside other display options.

Affected components:
- PricingTableColumns.js
- PricingDisplaySettings.jsx
- PricingSidebar.jsx
- PricingFilterModal.jsx
- PricingTable.jsx
- utils.js (resetPricingFilters)
- en.json (translations)
2025-07-24 17:10:08 +08:00
t0ng7u
9bab77ad05 🔧 refactor(pricing-filters): extract display settings & improve mobile layout (#1365)
* **PricingDisplaySettings.jsx**
  • Extracted display settings (recharge price, currency, ratio toggle) from PricingSidebar
  • Maintains complete styling and functionality as standalone component

* **SelectableButtonGroup.jsx**
  • Added isMobile detection with conditional Col spans
  • Mobile: `span={12}` (2 buttons per row) for better touch experience
  • Desktop: preserved responsive grid `xs={24} sm={24} md={24} lg={12} xl={8}`

* **PricingSidebar.jsx**
  • Updated imports to use new PricingDisplaySettings component
  • Simplified component structure while preserving reset logic

These changes enhance code modularity and provide optimized mobile UX for filter button groups across the pricing interface.
2025-07-23 03:14:25 +08:00
t0ng7u
2f55960b17 🌐 feat: implement left-right pagination layout with i18n support
- Add left-right pagination layout for desktop (total info on left, controls on right)
- Keep mobile layout centered with pagination controls only
- Implement proper i18n support for pagination text using react-i18next
- Add pagination translations for Chinese and English
- Standardize t function usage across all table components to use xxxData.t pattern
- Update CardPro footer layout to support justify-between on desktop
- Use CSS variable --semi-color-text-2 for consistent text styling
- Disable built-in Pagination showTotal to avoid duplication

Components updated:
- CardPro: Enhanced footer layout with responsive design
- createCardProPagination: Added i18n support and custom total text
- All table components: Unified t function usage pattern
- i18n files: Added pagination-related translations

The pagination now displays "Showing X to Y of Z items" on desktop
and maintains existing centered layout on mobile devices.
2025-07-22 16:11:21 +08:00
t0ng7u
9992229b90 ⚖️ docs(LICENSE): update license information from Apache 2.0 to New API Licensing 2025-07-20 16:15:00 +08:00
t0ng7u
97119ea485 🚀 feat: Enhance table UX & fix reset actions across Users / Tokens / Redemptions
Users table (UsersColumnDefs.js)
• Merged “Status” into the “Statistics” tag: unified text-color logic, removed duplicate renderStatus / renderOverallStatus helpers.
• Switch now disabled for deleted users.
• Replaced dropdown “More” menu with explicit action buttons (Edit / Promote / Demote / Delete) and set column width to 200 px.
• Deleted unused Dropdown & IconMore imports and tidied redundant code.

Users filters & hooks
• UsersFilters.jsx – store formApi in a ref; reset button clears form then reloads data after 100 ms.
• useUsersData.js – call setLoading(true) at the start of loadUsers so the Query button shows loading on reset / reload.

TokensFilters.jsx & RedemptionsFilters.jsx
• Same ref-based reset pattern with 100 ms debounce to restore working “Reset” buttons.

Other clean-ups
• Removed repeated status strings and unused helper functions.
• Updated import lists to reflect component changes.

Result
– Reset buttons now reliably clear filters and reload data with proper loading feedback.
– Users table shows concise status information and all operation buttons without extra clicks.
2025-07-20 01:21:06 +08:00