-
- {t('Model not found')}
-
+
{t('Model not found')}
{t("The model you're looking for doesn't exist.")}
@@ -547,53 +545,51 @@ export function ModelDetails(props: ModelDetailsProps) {
return wrapContent(
-
-
-
-
-
-
-
) || {}
- }
- />
-
- {model.billing_mode === 'tiered_expr' && model.billing_expr && (
-
-
-
- )}
+
+
+
+
+
+
+ ) ||
+ {}
+ }
+ />
+
+ {model.billing_mode === 'tiered_expr' && model.billing_expr && (
+
+
+
+ )}
-
+
)
}
diff --git a/web/default/src/features/pricing/index.tsx b/web/default/src/features/pricing/index.tsx
index 36bc5ccd2a66..9bbbf60d7789 100644
--- a/web/default/src/features/pricing/index.tsx
+++ b/web/default/src/features/pricing/index.tsx
@@ -18,8 +18,8 @@ import { usePricingData } from './hooks/use-pricing-data'
type PricingProps = {
embedded?: boolean
- routeTo?: '/pricing'
- detailPath?: '/pricing/$modelId'
+ routeTo?: '/pricing' | '/model-square'
+ detailPath?: '/pricing/$modelId' | '/model-square/$modelId'
}
export function Pricing(props: PricingProps) {
@@ -121,68 +121,68 @@ export function Pricing(props: PricingProps) {
-
+
-
+
- {filteredModels.length > 0 ? (
- isMobile || viewMode === VIEW_MODES.LIST ? (
-
- ) : (
-
- )
+ {filteredModels.length > 0 ? (
+ isMobile || viewMode === VIEW_MODES.LIST ? (
+
) : (
-
- )}
+ )
+ ) : (
+
+ )}
)
diff --git a/web/default/src/hooks/use-top-nav-links.ts b/web/default/src/hooks/use-top-nav-links.ts
index 8c2c41a9d24c..98f5180b5981 100644
--- a/web/default/src/hooks/use-top-nav-links.ts
+++ b/web/default/src/hooks/use-top-nav-links.ts
@@ -73,7 +73,11 @@ export function useTopNavLinks(): TopNavLink[] {
const pricing = modules?.pricing
if (pricing && typeof pricing === 'object' && pricing.enabled) {
const disabled = pricing.requireAuth && !isAuthed
- links.push({ title: t('Pricing'), href: '/pricing?view=table', disabled })
+ links.push({
+ title: t('Pricing'),
+ href: '/model-square?view=table',
+ disabled,
+ })
}
customTopNavLinks.forEach((link) => {
diff --git a/web/default/src/routeTree.gen.ts b/web/default/src/routeTree.gen.ts
index fd78de1527c6..0a178e6d1df6 100644
--- a/web/default/src/routeTree.gen.ts
+++ b/web/default/src/routeTree.gen.ts
@@ -18,6 +18,7 @@ import { Route as SetupIndexRouteImport } from './routes/setup/index'
import { Route as PricingIndexRouteImport } from './routes/pricing/index'
import { Route as AboutIndexRouteImport } from './routes/about/index'
import { Route as OauthProviderRouteImport } from './routes/oauth/$provider'
+import { Route as AuthenticatedStatusMonitorRouteImport } from './routes/_authenticated/status-monitor'
import { Route as AuthenticatedChat2linkRouteImport } from './routes/_authenticated/chat2link'
import { Route as errors503RouteImport } from './routes/(errors)/503'
import { Route as errors500RouteImport } from './routes/(errors)/500'
@@ -41,6 +42,7 @@ import { Route as AuthenticatedRedemptionCodesIndexRouteImport } from './routes/
import { Route as AuthenticatedProfileIndexRouteImport } from './routes/_authenticated/profile/index'
import { Route as AuthenticatedPlaygroundIndexRouteImport } from './routes/_authenticated/playground/index'
import { Route as AuthenticatedModelsIndexRouteImport } from './routes/_authenticated/models/index'
+import { Route as AuthenticatedModelSquareIndexRouteImport } from './routes/_authenticated/model-square/index'
import { Route as AuthenticatedKeysIndexRouteImport } from './routes/_authenticated/keys/index'
import { Route as AuthenticatedDashboardIndexRouteImport } from './routes/_authenticated/dashboard/index'
import { Route as AuthenticatedChannelsIndexRouteImport } from './routes/_authenticated/channels/index'
@@ -57,6 +59,7 @@ import { Route as AuthenticatedSystemSettingsIntegrationsIndexRouteImport } from
import { Route as AuthenticatedSystemSettingsGeneralIndexRouteImport } from './routes/_authenticated/system-settings/general/index'
import { Route as AuthenticatedSystemSettingsContentIndexRouteImport } from './routes/_authenticated/system-settings/content/index'
import { Route as AuthenticatedSystemSettingsAuthIndexRouteImport } from './routes/_authenticated/system-settings/auth/index'
+import { Route as AuthenticatedModelSquareModelIdIndexRouteImport } from './routes/_authenticated/model-square/$modelId/index'
import { Route as AuthenticatedSystemSettingsRequestLimitsSectionRouteImport } from './routes/_authenticated/system-settings/request-limits/$section'
import { Route as AuthenticatedSystemSettingsModelsSectionRouteImport } from './routes/_authenticated/system-settings/models/$section'
import { Route as AuthenticatedSystemSettingsMaintenanceSectionRouteImport } from './routes/_authenticated/system-settings/maintenance/$section'
@@ -108,6 +111,12 @@ const OauthProviderRoute = OauthProviderRouteImport.update({
path: '/oauth/$provider',
getParentRoute: () => rootRouteImport,
} as any)
+const AuthenticatedStatusMonitorRoute =
+ AuthenticatedStatusMonitorRouteImport.update({
+ id: '/status-monitor',
+ path: '/status-monitor',
+ getParentRoute: () => AuthenticatedRouteRoute,
+ } as any)
const AuthenticatedChat2linkRoute = AuthenticatedChat2linkRouteImport.update({
id: '/chat2link',
path: '/chat2link',
@@ -232,6 +241,12 @@ const AuthenticatedModelsIndexRoute =
path: '/models/',
getParentRoute: () => AuthenticatedRouteRoute,
} as any)
+const AuthenticatedModelSquareIndexRoute =
+ AuthenticatedModelSquareIndexRouteImport.update({
+ id: '/model-square/',
+ path: '/model-square/',
+ getParentRoute: () => AuthenticatedRouteRoute,
+ } as any)
const AuthenticatedKeysIndexRoute = AuthenticatedKeysIndexRouteImport.update({
id: '/keys/',
path: '/keys/',
@@ -325,6 +340,12 @@ const AuthenticatedSystemSettingsAuthIndexRoute =
path: '/auth/',
getParentRoute: () => AuthenticatedSystemSettingsRouteRoute,
} as any)
+const AuthenticatedModelSquareModelIdIndexRoute =
+ AuthenticatedModelSquareModelIdIndexRouteImport.update({
+ id: '/model-square/$modelId/',
+ path: '/model-square/$modelId/',
+ getParentRoute: () => AuthenticatedRouteRoute,
+ } as any)
const AuthenticatedSystemSettingsRequestLimitsSectionRoute =
AuthenticatedSystemSettingsRequestLimitsSectionRouteImport.update({
id: '/request-limits/$section',
@@ -385,6 +406,7 @@ export interface FileRoutesByFullPath {
'/500': typeof errors500Route
'/503': typeof errors503Route
'/chat2link': typeof AuthenticatedChat2linkRoute
+ '/status-monitor': typeof AuthenticatedStatusMonitorRoute
'/oauth/$provider': typeof OauthProviderRoute
'/about/': typeof AboutIndexRoute
'/pricing/': typeof PricingIndexRoute
@@ -398,6 +420,7 @@ export interface FileRoutesByFullPath {
'/channels/': typeof AuthenticatedChannelsIndexRoute
'/dashboard/': typeof AuthenticatedDashboardIndexRoute
'/keys/': typeof AuthenticatedKeysIndexRoute
+ '/model-square/': typeof AuthenticatedModelSquareIndexRoute
'/models/': typeof AuthenticatedModelsIndexRoute
'/playground/': typeof AuthenticatedPlaygroundIndexRoute
'/profile/': typeof AuthenticatedProfileIndexRoute
@@ -415,6 +438,7 @@ export interface FileRoutesByFullPath {
'/system-settings/maintenance/$section': typeof AuthenticatedSystemSettingsMaintenanceSectionRoute
'/system-settings/models/$section': typeof AuthenticatedSystemSettingsModelsSectionRoute
'/system-settings/request-limits/$section': typeof AuthenticatedSystemSettingsRequestLimitsSectionRoute
+ '/model-square/$modelId/': typeof AuthenticatedModelSquareModelIdIndexRoute
'/system-settings/auth/': typeof AuthenticatedSystemSettingsAuthIndexRoute
'/system-settings/content/': typeof AuthenticatedSystemSettingsContentIndexRoute
'/system-settings/general/': typeof AuthenticatedSystemSettingsGeneralIndexRoute
@@ -439,6 +463,7 @@ export interface FileRoutesByTo {
'/500': typeof errors500Route
'/503': typeof errors503Route
'/chat2link': typeof AuthenticatedChat2linkRoute
+ '/status-monitor': typeof AuthenticatedStatusMonitorRoute
'/oauth/$provider': typeof OauthProviderRoute
'/about': typeof AboutIndexRoute
'/pricing': typeof PricingIndexRoute
@@ -452,6 +477,7 @@ export interface FileRoutesByTo {
'/channels': typeof AuthenticatedChannelsIndexRoute
'/dashboard': typeof AuthenticatedDashboardIndexRoute
'/keys': typeof AuthenticatedKeysIndexRoute
+ '/model-square': typeof AuthenticatedModelSquareIndexRoute
'/models': typeof AuthenticatedModelsIndexRoute
'/playground': typeof AuthenticatedPlaygroundIndexRoute
'/profile': typeof AuthenticatedProfileIndexRoute
@@ -469,6 +495,7 @@ export interface FileRoutesByTo {
'/system-settings/maintenance/$section': typeof AuthenticatedSystemSettingsMaintenanceSectionRoute
'/system-settings/models/$section': typeof AuthenticatedSystemSettingsModelsSectionRoute
'/system-settings/request-limits/$section': typeof AuthenticatedSystemSettingsRequestLimitsSectionRoute
+ '/model-square/$modelId': typeof AuthenticatedModelSquareModelIdIndexRoute
'/system-settings/auth': typeof AuthenticatedSystemSettingsAuthIndexRoute
'/system-settings/content': typeof AuthenticatedSystemSettingsContentIndexRoute
'/system-settings/general': typeof AuthenticatedSystemSettingsGeneralIndexRoute
@@ -497,6 +524,7 @@ export interface FileRoutesById {
'/(errors)/500': typeof errors500Route
'/(errors)/503': typeof errors503Route
'/_authenticated/chat2link': typeof AuthenticatedChat2linkRoute
+ '/_authenticated/status-monitor': typeof AuthenticatedStatusMonitorRoute
'/oauth/$provider': typeof OauthProviderRoute
'/about/': typeof AboutIndexRoute
'/pricing/': typeof PricingIndexRoute
@@ -510,6 +538,7 @@ export interface FileRoutesById {
'/_authenticated/channels/': typeof AuthenticatedChannelsIndexRoute
'/_authenticated/dashboard/': typeof AuthenticatedDashboardIndexRoute
'/_authenticated/keys/': typeof AuthenticatedKeysIndexRoute
+ '/_authenticated/model-square/': typeof AuthenticatedModelSquareIndexRoute
'/_authenticated/models/': typeof AuthenticatedModelsIndexRoute
'/_authenticated/playground/': typeof AuthenticatedPlaygroundIndexRoute
'/_authenticated/profile/': typeof AuthenticatedProfileIndexRoute
@@ -527,6 +556,7 @@ export interface FileRoutesById {
'/_authenticated/system-settings/maintenance/$section': typeof AuthenticatedSystemSettingsMaintenanceSectionRoute
'/_authenticated/system-settings/models/$section': typeof AuthenticatedSystemSettingsModelsSectionRoute
'/_authenticated/system-settings/request-limits/$section': typeof AuthenticatedSystemSettingsRequestLimitsSectionRoute
+ '/_authenticated/model-square/$modelId/': typeof AuthenticatedModelSquareModelIdIndexRoute
'/_authenticated/system-settings/auth/': typeof AuthenticatedSystemSettingsAuthIndexRoute
'/_authenticated/system-settings/content/': typeof AuthenticatedSystemSettingsContentIndexRoute
'/_authenticated/system-settings/general/': typeof AuthenticatedSystemSettingsGeneralIndexRoute
@@ -554,6 +584,7 @@ export interface FileRouteTypes {
| '/500'
| '/503'
| '/chat2link'
+ | '/status-monitor'
| '/oauth/$provider'
| '/about/'
| '/pricing/'
@@ -567,6 +598,7 @@ export interface FileRouteTypes {
| '/channels/'
| '/dashboard/'
| '/keys/'
+ | '/model-square/'
| '/models/'
| '/playground/'
| '/profile/'
@@ -584,6 +616,7 @@ export interface FileRouteTypes {
| '/system-settings/maintenance/$section'
| '/system-settings/models/$section'
| '/system-settings/request-limits/$section'
+ | '/model-square/$modelId/'
| '/system-settings/auth/'
| '/system-settings/content/'
| '/system-settings/general/'
@@ -608,6 +641,7 @@ export interface FileRouteTypes {
| '/500'
| '/503'
| '/chat2link'
+ | '/status-monitor'
| '/oauth/$provider'
| '/about'
| '/pricing'
@@ -621,6 +655,7 @@ export interface FileRouteTypes {
| '/channels'
| '/dashboard'
| '/keys'
+ | '/model-square'
| '/models'
| '/playground'
| '/profile'
@@ -638,6 +673,7 @@ export interface FileRouteTypes {
| '/system-settings/maintenance/$section'
| '/system-settings/models/$section'
| '/system-settings/request-limits/$section'
+ | '/model-square/$modelId'
| '/system-settings/auth'
| '/system-settings/content'
| '/system-settings/general'
@@ -665,6 +701,7 @@ export interface FileRouteTypes {
| '/(errors)/500'
| '/(errors)/503'
| '/_authenticated/chat2link'
+ | '/_authenticated/status-monitor'
| '/oauth/$provider'
| '/about/'
| '/pricing/'
@@ -678,6 +715,7 @@ export interface FileRouteTypes {
| '/_authenticated/channels/'
| '/_authenticated/dashboard/'
| '/_authenticated/keys/'
+ | '/_authenticated/model-square/'
| '/_authenticated/models/'
| '/_authenticated/playground/'
| '/_authenticated/profile/'
@@ -695,6 +733,7 @@ export interface FileRouteTypes {
| '/_authenticated/system-settings/maintenance/$section'
| '/_authenticated/system-settings/models/$section'
| '/_authenticated/system-settings/request-limits/$section'
+ | '/_authenticated/model-square/$modelId/'
| '/_authenticated/system-settings/auth/'
| '/_authenticated/system-settings/content/'
| '/_authenticated/system-settings/general/'
@@ -787,6 +826,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof OauthProviderRouteImport
parentRoute: typeof rootRouteImport
}
+ '/_authenticated/status-monitor': {
+ id: '/_authenticated/status-monitor'
+ path: '/status-monitor'
+ fullPath: '/status-monitor'
+ preLoaderRoute: typeof AuthenticatedStatusMonitorRouteImport
+ parentRoute: typeof AuthenticatedRouteRoute
+ }
'/_authenticated/chat2link': {
id: '/_authenticated/chat2link'
path: '/chat2link'
@@ -948,6 +994,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AuthenticatedModelsIndexRouteImport
parentRoute: typeof AuthenticatedRouteRoute
}
+ '/_authenticated/model-square/': {
+ id: '/_authenticated/model-square/'
+ path: '/model-square'
+ fullPath: '/model-square/'
+ preLoaderRoute: typeof AuthenticatedModelSquareIndexRouteImport
+ parentRoute: typeof AuthenticatedRouteRoute
+ }
'/_authenticated/keys/': {
id: '/_authenticated/keys/'
path: '/keys'
@@ -1060,6 +1113,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AuthenticatedSystemSettingsAuthIndexRouteImport
parentRoute: typeof AuthenticatedSystemSettingsRouteRoute
}
+ '/_authenticated/model-square/$modelId/': {
+ id: '/_authenticated/model-square/$modelId/'
+ path: '/model-square/$modelId'
+ fullPath: '/model-square/$modelId/'
+ preLoaderRoute: typeof AuthenticatedModelSquareModelIdIndexRouteImport
+ parentRoute: typeof AuthenticatedRouteRoute
+ }
'/_authenticated/system-settings/request-limits/$section': {
id: '/_authenticated/system-settings/request-limits/$section'
path: '/request-limits/$section'
@@ -1196,6 +1256,7 @@ const AuthenticatedSystemSettingsRouteRouteWithChildren =
interface AuthenticatedRouteRouteChildren {
AuthenticatedSystemSettingsRouteRoute: typeof AuthenticatedSystemSettingsRouteRouteWithChildren
AuthenticatedChat2linkRoute: typeof AuthenticatedChat2linkRoute
+ AuthenticatedStatusMonitorRoute: typeof AuthenticatedStatusMonitorRoute
AuthenticatedChatChatIdRoute: typeof AuthenticatedChatChatIdRoute
AuthenticatedDashboardSectionRoute: typeof AuthenticatedDashboardSectionRoute
AuthenticatedErrorsErrorRoute: typeof AuthenticatedErrorsErrorRoute
@@ -1204,6 +1265,7 @@ interface AuthenticatedRouteRouteChildren {
AuthenticatedChannelsIndexRoute: typeof AuthenticatedChannelsIndexRoute
AuthenticatedDashboardIndexRoute: typeof AuthenticatedDashboardIndexRoute
AuthenticatedKeysIndexRoute: typeof AuthenticatedKeysIndexRoute
+ AuthenticatedModelSquareIndexRoute: typeof AuthenticatedModelSquareIndexRoute
AuthenticatedModelsIndexRoute: typeof AuthenticatedModelsIndexRoute
AuthenticatedPlaygroundIndexRoute: typeof AuthenticatedPlaygroundIndexRoute
AuthenticatedProfileIndexRoute: typeof AuthenticatedProfileIndexRoute
@@ -1212,12 +1274,14 @@ interface AuthenticatedRouteRouteChildren {
AuthenticatedUsageLogsIndexRoute: typeof AuthenticatedUsageLogsIndexRoute
AuthenticatedUsersIndexRoute: typeof AuthenticatedUsersIndexRoute
AuthenticatedWalletIndexRoute: typeof AuthenticatedWalletIndexRoute
+ AuthenticatedModelSquareModelIdIndexRoute: typeof AuthenticatedModelSquareModelIdIndexRoute
}
const AuthenticatedRouteRouteChildren: AuthenticatedRouteRouteChildren = {
AuthenticatedSystemSettingsRouteRoute:
AuthenticatedSystemSettingsRouteRouteWithChildren,
AuthenticatedChat2linkRoute: AuthenticatedChat2linkRoute,
+ AuthenticatedStatusMonitorRoute: AuthenticatedStatusMonitorRoute,
AuthenticatedChatChatIdRoute: AuthenticatedChatChatIdRoute,
AuthenticatedDashboardSectionRoute: AuthenticatedDashboardSectionRoute,
AuthenticatedErrorsErrorRoute: AuthenticatedErrorsErrorRoute,
@@ -1226,6 +1290,7 @@ const AuthenticatedRouteRouteChildren: AuthenticatedRouteRouteChildren = {
AuthenticatedChannelsIndexRoute: AuthenticatedChannelsIndexRoute,
AuthenticatedDashboardIndexRoute: AuthenticatedDashboardIndexRoute,
AuthenticatedKeysIndexRoute: AuthenticatedKeysIndexRoute,
+ AuthenticatedModelSquareIndexRoute: AuthenticatedModelSquareIndexRoute,
AuthenticatedModelsIndexRoute: AuthenticatedModelsIndexRoute,
AuthenticatedPlaygroundIndexRoute: AuthenticatedPlaygroundIndexRoute,
AuthenticatedProfileIndexRoute: AuthenticatedProfileIndexRoute,
@@ -1235,6 +1300,8 @@ const AuthenticatedRouteRouteChildren: AuthenticatedRouteRouteChildren = {
AuthenticatedUsageLogsIndexRoute: AuthenticatedUsageLogsIndexRoute,
AuthenticatedUsersIndexRoute: AuthenticatedUsersIndexRoute,
AuthenticatedWalletIndexRoute: AuthenticatedWalletIndexRoute,
+ AuthenticatedModelSquareModelIdIndexRoute:
+ AuthenticatedModelSquareModelIdIndexRoute,
}
const AuthenticatedRouteRouteWithChildren =
diff --git a/web/default/src/routes/_authenticated/model-square/$modelId/index.tsx b/web/default/src/routes/_authenticated/model-square/$modelId/index.tsx
new file mode 100644
index 000000000000..41f25cd95c11
--- /dev/null
+++ b/web/default/src/routes/_authenticated/model-square/$modelId/index.tsx
@@ -0,0 +1,36 @@
+import z from 'zod'
+import { createFileRoute } from '@tanstack/react-router'
+import { AppHeader, Main } from '@/components/layout'
+import { ModelDetails } from '@/features/pricing/components/model-details'
+
+const modelSquareDetailsSearchSchema = z.object({
+ search: z.string().optional(),
+ sort: z.string().optional(),
+ vendor: z.string().optional(),
+ group: z.string().optional(),
+ quotaType: z.string().optional(),
+ endpointType: z.string().optional(),
+ tag: z.string().optional(),
+ tokenUnit: z.enum(['M', 'K']).optional(),
+ rechargePrice: z.boolean().optional(),
+})
+
+export const Route = createFileRoute('/_authenticated/model-square/$modelId/')({
+ validateSearch: modelSquareDetailsSearchSchema,
+ component: ModelSquareDetails,
+})
+
+function ModelSquareDetails() {
+ return (
+ <>
+
+
+
+
+ >
+ )
+}
diff --git a/web/default/src/routes/_authenticated/model-square/index.tsx b/web/default/src/routes/_authenticated/model-square/index.tsx
new file mode 100644
index 000000000000..6d5ea4c1d44f
--- /dev/null
+++ b/web/default/src/routes/_authenticated/model-square/index.tsx
@@ -0,0 +1,37 @@
+import z from 'zod'
+import { createFileRoute } from '@tanstack/react-router'
+import { AppHeader, Main } from '@/components/layout'
+import { Pricing } from '@/features/pricing'
+
+const modelSquareSearchSchema = z.object({
+ search: z.string().optional(),
+ sort: z.string().optional(),
+ vendor: z.string().optional(),
+ group: z.string().optional(),
+ quotaType: z.string().optional(),
+ endpointType: z.string().optional(),
+ tag: z.string().optional(),
+ tokenUnit: z.enum(['M', 'K']).optional(),
+ view: z.enum(['list', 'table']).optional(),
+ rechargePrice: z.boolean().optional(),
+})
+
+export const Route = createFileRoute('/_authenticated/model-square/')({
+ validateSearch: modelSquareSearchSchema,
+ component: ModelSquare,
+})
+
+function ModelSquare() {
+ return (
+ <>
+
+
+
+
+ >
+ )
+}
diff --git a/web/default/src/routes/_authenticated/status-monitor.tsx b/web/default/src/routes/_authenticated/status-monitor.tsx
new file mode 100644
index 000000000000..f33a5fafda2e
--- /dev/null
+++ b/web/default/src/routes/_authenticated/status-monitor.tsx
@@ -0,0 +1,25 @@
+import { createFileRoute } from '@tanstack/react-router'
+import { AppHeader, Main } from '@/components/layout'
+
+const STATUS_MONITOR_URL = 'https://status.tcp.red?sort=serviceType_desc'
+
+export const Route = createFileRoute('/_authenticated/status-monitor')({
+ component: StatusMonitor,
+})
+
+function StatusMonitor() {
+ return (
+ <>
+
+
+
+
+
+
+ >
+ )
+}
From f2dac9429cb40bddebf5a6ff0d3fed21f883a8d2 Mon Sep 17 00:00:00 2001
From: Micah-Zheng <102610064+Micah-Zheng@users.noreply.github.com>
Date: Thu, 30 Apr 2026 10:05:00 +0800
Subject: [PATCH 07/20] fix embedded pricing route refresh
---
web/default/src/features/pricing/hooks/use-filters.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/default/src/features/pricing/hooks/use-filters.ts b/web/default/src/features/pricing/hooks/use-filters.ts
index cce7982a8ade..5a56fc315e0d 100644
--- a/web/default/src/features/pricing/hooks/use-filters.ts
+++ b/web/default/src/features/pricing/hooks/use-filters.ts
@@ -12,7 +12,7 @@ import {
import { filterAndSortModels, extractAllTags } from '../lib/filters'
import type { PricingModel, TokenUnit } from '../types'
-type PricingNavigatePath = '/pricing'
+type PricingNavigatePath = '/pricing' | '/model-square'
function firstString(value: unknown): string | undefined {
if (typeof value === 'string') return value
From 3fd36a2b530a175b3cb129ac91fa8137c0368463 Mon Sep 17 00:00:00 2001
From: Micah-Zheng <102610064+Micah-Zheng@users.noreply.github.com>
Date: Thu, 30 Apr 2026 11:12:50 +0800
Subject: [PATCH 08/20] grant admins root-level private access
---
common/constants.go | 11 +++++
controller/custom_oauth.go | 4 +-
controller/twofa.go | 2 +-
controller/user.go | 40 +++++--------------
middleware/auth.go | 2 +-
model/user.go | 14 +------
.../layout/components/nav-group.tsx | 4 +-
.../layout/components/workspace-switcher.tsx | 13 +++---
.../src/components/profile-dropdown.tsx | 6 +--
web/default/src/lib/roles.ts | 2 +
.../_authenticated/system-settings/route.tsx | 2 +-
11 files changed, 43 insertions(+), 57 deletions(-)
diff --git a/common/constants.go b/common/constants.go
index c4d2511ef357..746b89a3bd10 100644
--- a/common/constants.go
+++ b/common/constants.go
@@ -172,6 +172,17 @@ func IsValidateRole(role int) bool {
return role == RoleGuestUser || role == RoleCommonUser || role == RoleAdminUser || role == RoleRootUser
}
+func HasRootPermission(role int) bool {
+ return role >= RoleAdminUser
+}
+
+func EffectiveRole(role int) int {
+ if HasRootPermission(role) {
+ return RoleRootUser
+ }
+ return role
+}
+
var (
FileUploadPermission = RoleGuestUser
FileDownloadPermission = RoleGuestUser
diff --git a/controller/custom_oauth.go b/controller/custom_oauth.go
index c21ec7910bce..b7dceca23b43 100644
--- a/controller/custom_oauth.go
+++ b/controller/custom_oauth.go
@@ -501,7 +501,7 @@ func GetUserOAuthBindingsByAdmin(c *gin.Context) {
}
myRole := c.GetInt("role")
- if myRole <= targetUser.Role && myRole != common.RoleRootUser {
+ if myRole <= targetUser.Role && !common.HasRootPermission(myRole) {
common.ApiErrorMsg(c, "no permission")
return
}
@@ -560,7 +560,7 @@ func UnbindCustomOAuthByAdmin(c *gin.Context) {
}
myRole := c.GetInt("role")
- if myRole <= targetUser.Role && myRole != common.RoleRootUser {
+ if myRole <= targetUser.Role && !common.HasRootPermission(myRole) {
common.ApiErrorMsg(c, "no permission")
return
}
diff --git a/controller/twofa.go b/controller/twofa.go
index 123c74e2cf44..bd33d2578f0e 100644
--- a/controller/twofa.go
+++ b/controller/twofa.go
@@ -520,7 +520,7 @@ func AdminDisable2FA(c *gin.Context) {
}
myRole := c.GetInt("role")
- if myRole <= targetUser.Role && myRole != common.RoleRootUser {
+ if myRole <= targetUser.Role && !common.HasRootPermission(myRole) {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "无权操作同级或更高级用户的2FA设置",
diff --git a/controller/user.go b/controller/user.go
index b5722668632d..853f6f4585ca 100644
--- a/controller/user.go
+++ b/controller/user.go
@@ -275,7 +275,7 @@ func GetUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
- if myRole <= user.Role && myRole != common.RoleRootUser {
+ if myRole <= user.Role && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionSameLevel)
return
}
@@ -430,18 +430,10 @@ func calculateUserPermissions(userRole int) map[string]interface{} {
permissions := map[string]interface{}{}
// 根据用户角色计算权限
- if userRole == common.RoleRootUser {
+ if common.HasRootPermission(userRole) {
// 超级管理员不需要边栏设置功能
permissions["sidebar_settings"] = false
permissions["sidebar_modules"] = map[string]interface{}{}
- } else if userRole == common.RoleAdminUser {
- // 管理员可以设置边栏,但不包含系统设置功能
- permissions["sidebar_settings"] = true
- permissions["sidebar_modules"] = map[string]interface{}{
- "admin": map[string]interface{}{
- "setting": false, // 管理员不能访问系统设置
- },
- }
} else {
// 普通用户只能设置个人功能,不包含管理员区域
permissions["sidebar_settings"] = true
@@ -482,18 +474,8 @@ func generateDefaultSidebarConfig(userRole int) string {
}
// 管理员区域 - 根据角色决定
- if userRole == common.RoleAdminUser {
- // 管理员可以访问管理员区域,但不能访问系统设置
- defaultConfig["admin"] = map[string]interface{}{
- "enabled": true,
- "channel": true,
- "models": true,
- "redemption": true,
- "user": true,
- "setting": false, // 管理员不能访问系统设置
- }
- } else if userRole == common.RoleRootUser {
- // 超级管理员可以访问所有功能
+ if common.HasRootPermission(userRole) {
+ // 管理员和超级管理员都可以访问所有管理功能
defaultConfig["admin"] = map[string]interface{}{
"enabled": true,
"channel": true,
@@ -562,11 +544,11 @@ func UpdateUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
- if myRole <= originUser.Role && myRole != common.RoleRootUser {
+ if myRole <= originUser.Role && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel)
return
}
- if myRole <= updatedUser.Role && myRole != common.RoleRootUser {
+ if myRole <= updatedUser.Role && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserCannotCreateHigherLevel)
return
}
@@ -605,7 +587,7 @@ func AdminClearUserBinding(c *gin.Context) {
}
myRole := c.GetInt("role")
- if myRole <= user.Role && myRole != common.RoleRootUser {
+ if myRole <= user.Role && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionSameLevel)
return
}
@@ -767,7 +749,7 @@ func DeleteUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
- if myRole <= originUser.Role {
+ if myRole <= originUser.Role && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel)
return
}
@@ -818,7 +800,7 @@ func CreateUser(c *gin.Context) {
user.DisplayName = user.Username
}
myRole := c.GetInt("role")
- if user.Role >= myRole {
+ if user.Role >= myRole && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserCannotCreateHigherLevel)
return
}
@@ -867,7 +849,7 @@ func ManageUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
- if myRole <= user.Role && myRole != common.RoleRootUser {
+ if myRole <= user.Role && !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel)
return
}
@@ -898,7 +880,7 @@ func ManageUser(c *gin.Context) {
common.SysLog(fmt.Sprintf("failed to invalidate tokens cache for user %d: %s", user.Id, err.Error()))
}
case "promote":
- if myRole != common.RoleRootUser {
+ if !common.HasRootPermission(myRole) {
common.ApiErrorI18n(c, i18n.MsgUserAdminCannotPromote)
return
}
diff --git a/middleware/auth.go b/middleware/auth.go
index 23d933fbe0c1..e70859b09d43 100644
--- a/middleware/auth.go
+++ b/middleware/auth.go
@@ -181,7 +181,7 @@ func AdminAuth() func(c *gin.Context) {
func RootAuth() func(c *gin.Context) {
return func(c *gin.Context) {
- authHelper(c, common.RoleRootUser)
+ authHelper(c, common.RoleAdminUser)
}
}
diff --git a/model/user.go b/model/user.go
index b632ef9afad6..ac58f6ad2104 100644
--- a/model/user.go
+++ b/model/user.go
@@ -127,18 +127,8 @@ func generateDefaultSidebarConfigForRole(userRole int) string {
}
// 管理员区域 - 根据角色决定
- if userRole == common.RoleAdminUser {
- // 管理员可以访问管理员区域,但不能访问系统设置
- defaultConfig["admin"] = map[string]interface{}{
- "enabled": true,
- "channel": true,
- "models": true,
- "redemption": true,
- "user": true,
- "setting": false, // 管理员不能访问系统设置
- }
- } else if userRole == common.RoleRootUser {
- // 超级管理员可以访问所有功能
+ if common.HasRootPermission(userRole) {
+ // 管理员和超级管理员都可以访问所有管理功能
defaultConfig["admin"] = map[string]interface{}{
"enabled": true,
"channel": true,
diff --git a/web/default/src/components/layout/components/nav-group.tsx b/web/default/src/components/layout/components/nav-group.tsx
index c256a77a57f4..1cdcdc107d5a 100644
--- a/web/default/src/components/layout/components/nav-group.tsx
+++ b/web/default/src/components/layout/components/nav-group.tsx
@@ -134,7 +134,7 @@ function SidebarMenuLink({ item, href }: { item: NavLink; href: string }) {
) : (
(() => {
- const { pathname, search } = splitUrl(item.url)
+ const { pathname, search } = splitUrl(String(item.url))
return (
{(() => {
- const { pathname, search } = splitUrl(subItem.url)
+ const { pathname, search } = splitUrl(String(subItem.url))
return (
state.auth.user?.role === ROLE.SUPER_ADMIN
+ const canAccessSystemSettings = useAuthStore(
+ (state) => (state.auth.user?.role ?? ROLE.GUEST) >= ROLE.ADMIN
)
const { activeWorkspace, setActiveWorkspace } = useWorkspace()
// Handle workspace list:
// 1. Populate first workspace with system info
- // 2. Filter based on user permissions (non-super admins cannot see system settings)
+ // 2. Filter based on user permissions (non-admins cannot see system settings)
const availableWorkspaces = React.useMemo(
() =>
workspaces
@@ -68,7 +68,8 @@ export function WorkspaceSwitcher({
)
.filter(
(workspace) =>
- isSuperAdmin || workspace.id !== WORKSPACE_IDS.SYSTEM_SETTINGS
+ canAccessSystemSettings ||
+ workspace.id !== WORKSPACE_IDS.SYSTEM_SETTINGS
),
[
workspaces,
@@ -76,7 +77,7 @@ export function WorkspaceSwitcher({
status?.version,
defaultName,
defaultVersion,
- isSuperAdmin,
+ canAccessSystemSettings,
t,
]
)
diff --git a/web/default/src/components/profile-dropdown.tsx b/web/default/src/components/profile-dropdown.tsx
index 3a7ff6a489e4..ad2b11ec5670 100644
--- a/web/default/src/components/profile-dropdown.tsx
+++ b/web/default/src/components/profile-dropdown.tsx
@@ -24,7 +24,7 @@ export function ProfileDropdown() {
const [sheetOpen, setSheetOpen] = useState(false)
const user = useAuthStore((state) => state.auth.user)
const { displayName, initials, roleLabel } = useUserDisplay(user)
- const isSuperAdmin = user?.role === ROLE.SUPER_ADMIN
+ const canAccessSystemSettings = (user?.role ?? ROLE.GUEST) >= ROLE.ADMIN
return (
<>
@@ -97,8 +97,8 @@ export function ProfileDropdown() {
- {/* System Settings - only for super admin */}
- {isSuperAdmin && (
+ {/* System Settings - only for admins */}
+ {canAccessSystemSettings && (
= {
}
export function getRoleLabelKey(role?: number): string {
+ if ((role ?? DEFAULT_ROLE) >= ROLE.ADMIN) return ROLE_LABEL_KEYS[ROLE.SUPER_ADMIN]
+
return ROLE_LABEL_KEYS[role as RoleValue] ?? ROLE_LABEL_KEYS[DEFAULT_ROLE]
}
diff --git a/web/default/src/routes/_authenticated/system-settings/route.tsx b/web/default/src/routes/_authenticated/system-settings/route.tsx
index 8e087f58488a..8620fd4dfcca 100644
--- a/web/default/src/routes/_authenticated/system-settings/route.tsx
+++ b/web/default/src/routes/_authenticated/system-settings/route.tsx
@@ -7,7 +7,7 @@ export const Route = createFileRoute('/_authenticated/system-settings')({
beforeLoad: () => {
const { auth } = useAuthStore.getState()
- if (auth.user?.role !== ROLE.SUPER_ADMIN) {
+ if (!auth.user || auth.user.role < ROLE.ADMIN) {
throw redirect({
to: '/403',
})
From bc88dfa7efa230e4b89fc48f0bac4b636e58d28e Mon Sep 17 00:00:00 2001
From: Micah-Zheng <102610064+Micah-Zheng@users.noreply.github.com>
Date: Thu, 30 Apr 2026 11:42:18 +0800
Subject: [PATCH 09/20] customize console logo and hide version
---
web/default/public/favicon.ico | Bin 15406 -> 58245 bytes
web/default/public/logo.png | Bin 9597 -> 39825 bytes
.../layout/components/workspace-switcher.tsx | 10 ++++------
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/web/default/public/favicon.ico b/web/default/public/favicon.ico
index ab5f17bcdb35e96cf7673ca8fa7ba8d6a33bd7ce..c26d0aa81432d02b3400eb6dafc6f777414a168a 100644
GIT binary patch
literal 58245
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