chore: run bun format to automatically format the frontend code

This commit is contained in:
t0ng7u
2026-07-01 06:38:41 +08:00
parent e514db20f7
commit 5bf3468362
679 changed files with 2719 additions and 1717 deletions
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { api } from '@/lib/api'
import type { AboutResponse } from './types'
export async function getAboutContent() {
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { api } from '@/lib/api'
import type {
LoginPayload,
LoginResponse,
+2 -1
View File
@@ -18,8 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { useSystemConfig } from '@/hooks/use-system-config'
import { Skeleton } from '@/components/ui/skeleton'
import { useSystemConfig } from '@/hooks/use-system-config'
type AuthLayoutProps = {
children: React.ReactNode
+3 -1
View File
@@ -17,9 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Checkbox } from '@/components/ui/checkbox'
import { Label } from '@/components/ui/label'
import { cn } from '@/lib/utils'
import type { SystemStatus } from '../types'
interface LegalConsentProps {
@@ -16,10 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { Loader2, Send, Shield, UserRound, type LucideIcon } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { SiGithub, SiLinux, SiWechat } from 'react-icons/si'
import { AuthLayout } from '../auth-layout'
type OAuthCallbackScreenProps = {
@@ -18,14 +18,16 @@ For commercial licensing, please contact support@quantumnous.com
*/
import type { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import {
IconDiscord,
IconGithub,
IconLinuxDo,
IconWeChat,
} from '@/assets/brand-icons'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import { useOAuthLogin } from '../hooks/use-oauth-login'
import type { SystemStatus } from '../types'
@@ -17,7 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import type { SystemStatus } from '../types'
interface TermsFooterProps {
@@ -16,15 +16,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import type { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { ArrowRight, Loader2 } from 'lucide-react'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { cn } from '@/lib/utils'
import { useCountdown } from '@/hooks/use-countdown'
import type { z } from 'zod'
import { Turnstile } from '@/components/turnstile'
import { Button } from '@/components/ui/button'
import {
Form,
@@ -35,13 +35,14 @@ import {
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Turnstile } from '@/components/turnstile'
import { sendPasswordResetEmail } from '@/features/auth/api'
import {
forgotPasswordFormSchema,
PASSWORD_RESET_COUNTDOWN,
} from '@/features/auth/constants'
import { useTurnstile } from '@/features/auth/hooks/use-turnstile'
import { useCountdown } from '@/hooks/use-countdown'
import { cn } from '@/lib/utils'
export function ForgotPasswordForm({
className,
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { AuthLayout } from '../auth-layout'
import { ForgotPasswordForm } from './components/forgot-password-form'
+4 -2
View File
@@ -18,9 +18,11 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useNavigate } from '@tanstack/react-router'
import i18n from 'i18next'
import { useAuthStore } from '@/stores/auth-store'
import { getSelf } from '@/lib/api'
import type { User } from '@/features/users/types'
import { getSelf } from '@/lib/api'
import { useAuthStore } from '@/stores/auth-store'
import { saveUserId } from '../lib/storage'
function getSavedLanguage(user: User): string | undefined {
@@ -16,10 +16,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import i18next from 'i18next'
import { useState } from 'react'
import { toast } from 'sonner'
import { useCountdown } from '@/hooks/use-countdown'
import { sendEmailVerification } from '../api'
import { EMAIL_VERIFICATION_COUNTDOWN } from '../constants'
+4 -2
View File
@@ -16,12 +16,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useRef, useEffect } from 'react'
import type { AxiosRequestConfig } from 'axios'
import { useState, useRef, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth-store'
import { api } from '@/lib/api'
import { useAuthStore } from '@/stores/auth-store'
import { getOAuthState } from '../api'
import {
buildGitHubOAuthUrl,
+2 -1
View File
@@ -16,9 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import i18next from 'i18next'
import { useState } from 'react'
import { toast } from 'sonner'
import { useStatus } from '@/hooks/use-status'
/**
+6 -5
View File
@@ -16,15 +16,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import type { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { Loader2 } from 'lucide-react'
import { useState } from 'react'
import { useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth-store'
import { cn } from '@/lib/utils'
import type { z } from 'zod'
import { Button } from '@/components/ui/button'
import {
Form,
@@ -57,6 +56,8 @@ import {
cleanBackupCode,
} from '@/features/auth/lib/validation'
import type { User } from '@/features/users/types'
import { cn } from '@/lib/utils'
import { useAuthStore } from '@/stores/auth-store'
type OtpFormProps = React.HTMLAttributes<HTMLFormElement>
+1
View File
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { AuthLayout } from '../auth-layout'
import { OtpForm } from './components/otp-form'
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { api } from '@/lib/api'
import type { ApiResponse, PasskeyOptionsPayload, PasskeyStatus } from './types'
export async function getPasskeyStatus(): Promise<ApiResponse<PasskeyStatus>> {
@@ -16,15 +16,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useCallback, useEffect, useMemo, useState } from 'react'
import i18next from 'i18next'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'
import {
buildRegistrationResult,
createCredential,
isPasskeySupported as detectPasskeySupport,
prepareCredentialCreationOptions,
} from '@/lib/passkey'
import {
beginPasskeyRegistration,
deletePasskey,
@@ -16,18 +16,20 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import { useNavigate } from '@tanstack/react-router'
import { CheckIcon, CopyIcon } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { api } from '@/lib/api'
import { copyToClipboard } from '@/lib/copy-to-clipboard'
import { useCountdown } from '@/hooks/use-countdown'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { useCountdown } from '@/hooks/use-countdown'
import { api } from '@/lib/api'
import { copyToClipboard } from '@/lib/copy-to-clipboard'
import { AuthLayout } from '../auth-layout'
export type ResetPasswordSearchParams = {
@@ -22,6 +22,7 @@ import {
prepareCredentialRequestOptions,
isPasskeySupported as detectPasskeySupport,
} from '@/lib/passkey'
import {
beginPasskeyVerification,
finishPasskeyVerification,
@@ -16,13 +16,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { ShieldCheck, KeyRound, Loader2 } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Dialog } from '@/components/dialog'
import type {
SecureVerificationState,
VerificationMethod,
@@ -16,13 +16,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useCallback, useEffect, useMemo, useState } from 'react'
import i18next from 'i18next'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { toast } from 'sonner'
import {
extractVerificationInfo,
isVerificationRequiredError,
} from '@/lib/secure-verification'
import { checkVerificationMethods, verify } from '../api'
import type {
SecureVerificationState,
@@ -16,21 +16,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useMemo, useState } from 'react'
import type { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { Link } from '@tanstack/react-router'
import { Loader2, LogIn, KeyRound } from 'lucide-react'
import { useEffect, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import {
buildAssertionResult,
prepareCredentialRequestOptions,
isPasskeySupported as detectPasskeySupport,
} from '@/lib/passkey'
import { cn } from '@/lib/utils'
import { useStatus } from '@/hooks/use-status'
import type { z } from 'zod'
import { Dialog } from '@/components/dialog'
import { PasswordInput } from '@/components/password-input'
import { Turnstile } from '@/components/turnstile'
import { Button } from '@/components/ui/button'
import {
Form,
@@ -42,9 +39,6 @@ import {
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Dialog } from '@/components/dialog'
import { PasswordInput } from '@/components/password-input'
import { Turnstile } from '@/components/turnstile'
import { login, wechatLoginByCode } from '@/features/auth/api'
import { LegalConsent } from '@/features/auth/components/legal-consent'
import { OAuthProviders } from '@/features/auth/components/oauth-providers'
@@ -53,6 +47,13 @@ import { useAuthRedirect } from '@/features/auth/hooks/use-auth-redirect'
import { useTurnstile } from '@/features/auth/hooks/use-turnstile'
import { beginPasskeyLogin, finishPasskeyLogin } from '@/features/auth/passkey'
import type { AuthFormProps } from '@/features/auth/types'
import { useStatus } from '@/hooks/use-status'
import {
buildAssertionResult,
prepareCredentialRequestOptions,
isPasskeySupported as detectPasskeySupport,
} from '@/lib/passkey'
import { cn } from '@/lib/utils'
export function UserAuthForm({
className,
+2
View File
@@ -18,7 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Link, useSearch } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { useStatus } from '@/hooks/use-status'
import { AuthLayout } from '../auth-layout'
import { TermsFooter } from '../components/terms-footer'
import { UserAuthForm } from './components/user-auth-form'
@@ -16,15 +16,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useMemo, useState } from 'react'
import type { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { Loader2 } from 'lucide-react'
import { useEffect, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { cn } from '@/lib/utils'
import { useStatus } from '@/hooks/use-status'
import type { z } from 'zod'
import { Dialog } from '@/components/dialog'
import { PasswordInput } from '@/components/password-input'
import { Turnstile } from '@/components/turnstile'
import { Button } from '@/components/ui/button'
import {
Form,
@@ -36,9 +38,6 @@ import {
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Dialog } from '@/components/dialog'
import { PasswordInput } from '@/components/password-input'
import { Turnstile } from '@/components/turnstile'
import { register, wechatLoginByCode } from '@/features/auth/api'
import { LegalConsent } from '@/features/auth/components/legal-consent'
import { OAuthProviders } from '@/features/auth/components/oauth-providers'
@@ -50,6 +49,8 @@ import {
getAffiliateCode,
saveAffiliateCode,
} from '@/features/auth/lib/storage'
import { useStatus } from '@/hooks/use-status'
import { cn } from '@/lib/utils'
export function SignUpForm({
className,
+2
View File
@@ -18,7 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { useStatus } from '@/hooks/use-status'
import { AuthLayout } from '../auth-layout'
import { TermsFooter } from '../components/terms-footer'
import { SignUpForm } from './components/sign-up-form'
+2 -1
View File
@@ -16,8 +16,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { api, type ApiRequestConfig } from '@/lib/api'
import { getGroups as getUserGroups } from '@/features/users/api'
import { api, type ApiRequestConfig } from '@/lib/api'
import type {
AddChannelRequest,
BatchDeleteParams,
@@ -16,28 +16,30 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { type Table } from '@tanstack/react-table'
import { Power, PowerOff, Tag, Trash2 } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { DataTableBulkActions as BulkActionsToolbar } from '@/components/data-table'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { useAuthStore } from '@/stores/auth-store'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import {
ADMIN_PERMISSION_ACTIONS,
ADMIN_PERMISSION_RESOURCES,
hasPermission,
} from '@/lib/admin-permissions'
import { cn } from '@/lib/utils'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { DataTableBulkActions as BulkActionsToolbar } from '@/components/data-table'
import { Dialog } from '@/components/dialog'
import { useAuthStore } from '@/stores/auth-store'
import {
handleBatchDelete,
handleBatchDisable,
@@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useContext, useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import type { Row } from '@tanstack/react-table'
import {
@@ -35,16 +34,11 @@ import {
RefreshCw,
Loader2,
} from 'lucide-react'
import { useContext, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { Button } from '@/components/ui/button'
import {
ADMIN_PERMISSION_ACTIONS,
ADMIN_PERMISSION_RESOURCES,
hasPermission,
} from '@/lib/admin-permissions'
import { useAuthStore } from '@/stores/auth-store'
import {
DropdownMenu,
DropdownMenuContent,
@@ -58,6 +52,12 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import {
ADMIN_PERMISSION_ACTIONS,
ADMIN_PERMISSION_RESOURCES,
hasPermission,
} from '@/lib/admin-permissions'
import { useAuthStore } from '@/stores/auth-store'
import { MODEL_FETCHABLE_TYPES } from '../constants'
import {
@@ -20,18 +20,20 @@ import { useQueryClient } from '@tanstack/react-query'
import type { Row } from '@tanstack/react-table'
import { Power, PowerOff, Pencil, Edit } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { DataTableRowActionMenu } from '@/components/data-table/core/row-action-menu'
import { Button } from '@/components/ui/button'
import {
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
} from '@/components/ui/dropdown-menu'
import { DataTableRowActionMenu } from '@/components/data-table/core/row-action-menu'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { handleEnableTagChannels, handleDisableTagChannels } from '../lib'
import type { Channel } from '../types'
import { useChannels } from './channels-provider'
@@ -16,10 +16,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { type ReactNode, useMemo, useRef, useState } from 'react'
import { ArrowRight, Check, Plus, Shuffle, Trash2 } from 'lucide-react'
import { type ReactNode, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { Dialog } from '@/components/dialog'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
@@ -39,8 +41,8 @@ import {
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { Dialog } from '@/components/dialog'
import { cn } from '@/lib/utils'
import {
ADVANCED_CUSTOM_AUTH_MODE_OPTIONS,
ADVANCED_CUSTOM_CONVERTER_OPTIONS,
@@ -341,7 +343,7 @@ export function AdvancedCustomEditorDialog({
)
}
>
<SelectTrigger className='h-8 min-w-[260px] max-w-full flex-1 sm:w-[320px]'>
<SelectTrigger className='h-8 max-w-full min-w-[260px] flex-1 sm:w-[320px]'>
<SelectValue className='min-w-0 truncate'>
{t(templateLabel)}
</SelectValue>
@@ -357,7 +359,7 @@ export function AdvancedCustomEditorDialog({
value={option.value}
className={longSelectItemClass}
>
<span className='min-w-0 whitespace-normal break-words leading-snug'>
<span className='min-w-0 leading-snug break-words whitespace-normal'>
{t(option.label)}
</span>
</SelectItem>
@@ -495,8 +497,10 @@ function RouteEditor({
[incomingPath]
)
const incomingPathLabel = getAdvancedCustomIncomingPathLabel(incomingPath)
const converterLabel =
getOptionLabel(ADVANCED_CUSTOM_CONVERTER_OPTIONS, converter)
const converterLabel = getOptionLabel(
ADVANCED_CUSTOM_CONVERTER_OPTIONS,
converter
)
const authLabel = getOptionLabel(ADVANCED_CUSTOM_AUTH_MODE_OPTIONS, authMode)
const isNativeConverter = converter === 'none'
const ConverterVisualIcon = isNativeConverter ? ArrowRight : Shuffle
@@ -575,7 +579,9 @@ function RouteEditor({
/>
<span className='sr-only'>{t(converterLabel)}</span>
</TooltipTrigger>
<TooltipContent side='top'>{t(converterLabel)}</TooltipContent>
<TooltipContent side='top'>
{t(converterLabel)}
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
@@ -597,10 +603,7 @@ function RouteEditor({
className='lg:gap-1'
labelClassName='lg:sr-only'
>
<Select
value={incomingPath}
onValueChange={setIncomingPath}
>
<Select value={incomingPath} onValueChange={setIncomingPath}>
<SelectTrigger className='w-full max-w-full lg:h-8'>
<SelectValue className='min-w-0 truncate'>
{`${incomingPathLabel}`}
@@ -617,9 +620,9 @@ function RouteEditor({
value={option.value}
className={longSelectItemClass}
>
<div className='flex min-w-0 flex-col gap-1 whitespace-normal leading-snug'>
<div className='flex min-w-0 flex-col gap-1 leading-snug whitespace-normal'>
<span>{option.label}</span>
<span className='text-muted-foreground break-all font-mono text-xs'>
<span className='text-muted-foreground font-mono text-xs break-all'>
{option.value}
</span>
</div>
@@ -676,7 +679,7 @@ function RouteEditor({
value={option.value}
className={longSelectItemClass}
>
<span className='min-w-0 whitespace-normal break-words leading-snug'>
<span className='min-w-0 leading-snug break-words whitespace-normal'>
{t(option.label)}
</span>
</SelectItem>
@@ -785,9 +788,7 @@ function FieldBlock({
}) {
return (
<div className={cn('flex min-w-0 flex-col gap-2', className)}>
<span className={cn('text-sm font-medium', labelClassName)}>
{label}
</span>
<span className={cn('text-sm font-medium', labelClassName)}>{label}</span>
{children}
</div>
)
@@ -16,15 +16,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { Loader2, RefreshCw, DollarSign } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { formatCurrencyFromUSD } from '@/lib/currency'
import { formatTimestampToDate } from '@/lib/format'
import { Button } from '@/components/ui/button'
import { Dialog } from '@/components/dialog'
import { getCodexUsage, updateChannelBalance } from '../../api'
import { channelsQueryKeys } from '../../lib'
import { useChannels } from '../channels-provider'
@@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { type ChangeEvent, useCallback, useMemo, useRef, useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import {
type ColumnDef,
@@ -32,10 +31,25 @@ import {
Settings,
Trash2,
} from 'lucide-react'
import { type ChangeEvent, useCallback, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { useCopyToClipboard } from '@/hooks/use-copy-to-clipboard'
import { useIsMobile } from '@/hooks/use-mobile'
import { ConfirmDialog } from '@/components/confirm-dialog'
import {
DataTableBulkActions as BulkActionsToolbar,
DataTablePagination,
DataTableView,
useDataTable,
} from '@/components/data-table'
import { Dialog } from '@/components/dialog'
import {
sideDrawerContentClassName,
sideDrawerFooterClassName,
sideDrawerFormClassName,
sideDrawerHeaderClassName,
} from '@/components/drawer-layout'
import { StatusBadge } from '@/components/status-badge'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
@@ -63,21 +77,9 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import {
DataTableBulkActions as BulkActionsToolbar,
DataTablePagination,
DataTableView,
useDataTable,
} from '@/components/data-table'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { Dialog } from '@/components/dialog'
import {
sideDrawerContentClassName,
sideDrawerFooterClassName,
sideDrawerFormClassName,
sideDrawerHeaderClassName,
} from '@/components/drawer-layout'
import { StatusBadge } from '@/components/status-badge'
import { useCopyToClipboard } from '@/hooks/use-copy-to-clipboard'
import { useIsMobile } from '@/hooks/use-mobile'
import { updateChannel } from '../../api'
import {
channelsQueryKeys,
@@ -947,7 +949,7 @@ function ChannelTestDialogContent({
value={option.value}
className={endpointSelectItemClass}
>
<span className='min-w-0 whitespace-normal break-words leading-snug'>
<span className='min-w-0 leading-snug break-words whitespace-normal'>
{option.label}
</span>
</SelectItem>
@@ -1341,11 +1343,7 @@ function FailureDetailsSheet({
)
}
function TestModelsBulkActions({
table,
}: {
table: TanStackTable<ModelRow>
}) {
function TestModelsBulkActions({ table }: { table: TanStackTable<ModelRow> }) {
const { t } = useTranslation()
const { copyToClipboard } = useCopyToClipboard()
const selectedRows = table.getFilteredSelectedRowModel().rows
@@ -16,15 +16,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { Loader2 } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Dialog } from '@/components/dialog'
import { handleCopyChannel } from '../../lib'
import { useChannels } from '../channels-provider'
@@ -16,11 +16,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useState } from 'react'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { Loader2 } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { Dialog } from '@/components/dialog'
import { GroupBadge } from '@/components/group-badge'
import { StatusBadge } from '@/components/status-badge'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
@@ -35,9 +39,7 @@ import {
} from '@/components/ui/select'
import { Separator } from '@/components/ui/separator'
import { Textarea } from '@/components/ui/textarea'
import { Dialog } from '@/components/dialog'
import { GroupBadge } from '@/components/group-badge'
import { StatusBadge } from '@/components/status-badge'
import {
editTagChannels,
getTagModels,
@@ -16,11 +16,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useEffect, useMemo } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { Loader2, Search, Info, ChevronDown } from 'lucide-react'
import { useState, useEffect, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import {
@@ -36,7 +38,7 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { Dialog } from '@/components/dialog'
import { fetchUpstreamModels, updateChannel } from '../../api'
import {
channelsQueryKeys,
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import {
AlertDialog,
AlertDialogAction,
@@ -16,17 +16,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useEffect } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { Loader2, RefreshCw, Trash2, Power, PowerOff } from 'lucide-react'
import { useState, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import {
ADMIN_PERMISSION_ACTIONS,
ADMIN_PERMISSION_RESOURCES,
hasPermission,
} from '@/lib/admin-permissions'
import { useAuthStore } from '@/stores/auth-store'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { StaticDataTable } from '@/components/data-table'
import { Dialog } from '@/components/dialog'
import { StatusBadge } from '@/components/status-badge'
import { Button } from '@/components/ui/button'
import {
Select,
@@ -37,10 +36,13 @@ import {
SelectValue,
} from '@/components/ui/select'
import { Separator } from '@/components/ui/separator'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { StaticDataTable } from '@/components/data-table'
import { Dialog } from '@/components/dialog'
import { StatusBadge } from '@/components/status-badge'
import {
ADMIN_PERMISSION_ACTIONS,
ADMIN_PERMISSION_RESOURCES,
hasPermission,
} from '@/lib/admin-permissions'
import { useAuthStore } from '@/stores/auth-store'
import {
getMultiKeyStatus,
enableMultiKey,
@@ -17,7 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
import type { MultiKeyConfirmAction } from '../../types'
type MultiKeyTableRowActionsProps = {
@@ -64,9 +66,7 @@ export function MultiKeyTableRowActions({
}}
disabled={!canDelete}
title={
canDelete
? undefined
: t('No permission to perform this action')
canDelete ? undefined : t('No permission to perform this action')
}
>
{t('Delete')}
@@ -16,12 +16,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { Loader2, RefreshCw, Trash2, Download, Search } from 'lucide-react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { getCommonHeaders } from '@/lib/api'
import { Dialog } from '@/components/dialog'
import {
AlertDialog,
AlertDialogAction,
@@ -38,7 +39,8 @@ import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Progress } from '@/components/ui/progress'
import { Separator } from '@/components/ui/separator'
import { Dialog } from '@/components/dialog'
import { getCommonHeaders } from '@/lib/api'
import {
deleteOllamaModel,
fetchModels as fetchModelsFromEndpoint,
@@ -16,14 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import {
type DragEvent,
type KeyboardEvent,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
import {
ChevronDown,
ChevronUp,
@@ -33,9 +25,18 @@ import {
Search,
Trash2,
} from 'lucide-react'
import {
type DragEvent,
type KeyboardEvent,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { cn } from '@/lib/utils'
import { Dialog } from '@/components/dialog'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import {
@@ -55,7 +56,7 @@ import {
} from '@/components/ui/select'
import { Switch } from '@/components/ui/switch'
import { Textarea } from '@/components/ui/textarea'
import { Dialog } from '@/components/dialog'
import { cn } from '@/lib/utils'
// ---------------------------------------------------------------------------
// Types
@@ -16,14 +16,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import { AlertTriangle } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Dialog } from '@/components/dialog'
interface StatusCodeRiskDialogProps {
open: boolean
@@ -16,19 +16,21 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useEffect, useMemo } from 'react'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { Loader2, AlertCircle } from 'lucide-react'
import { useState, useEffect, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { Dialog } from '@/components/dialog'
import { MultiSelect } from '@/components/multi-select'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Skeleton } from '@/components/ui/skeleton'
import { Textarea } from '@/components/ui/textarea'
import { Dialog } from '@/components/dialog'
import { MultiSelect } from '@/components/multi-select'
import {
getTagModels,
editTagChannels,
@@ -16,17 +16,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useMemo } from 'react'
import { Search } from 'lucide-react'
import { useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { Dialog } from '@/components/dialog'
import { StatusBadge } from '@/components/status-badge'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { Dialog } from '@/components/dialog'
import { StatusBadge } from '@/components/status-badge'
interface UpstreamUpdateDialogProps {
open: boolean
@@ -16,15 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import {
type ReactNode,
useEffect,
useState,
useMemo,
useCallback,
useRef,
} from 'react'
import { type SubmitErrorHandler, useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
@@ -51,6 +42,15 @@ import {
SlidersHorizontal,
Wand2,
} from 'lucide-react'
import {
type ReactNode,
useEffect,
useState,
useMemo,
useCallback,
useRef,
} from 'react'
import { type SubmitErrorHandler, useForm } from 'react-hook-form'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
@@ -729,9 +729,7 @@ export function ChannelMutateDrawer({
const currentAllowServiceTier = form.watch('allow_service_tier')
const currentDisableStore = form.watch('disable_store')
const currentAllowSafetyIdentifier = form.watch('allow_safety_identifier')
const currentAllowIncludeObfuscation = form.watch(
'allow_include_obfuscation'
)
const currentAllowIncludeObfuscation = form.watch('allow_include_obfuscation')
const currentAllowInferenceGeo = form.watch('allow_inference_geo')
const currentAllowSpeed = form.watch('allow_speed')
const currentClaudeBetaQuery = form.watch('claude_beta_query')
@@ -912,56 +910,56 @@ export function ChannelMutateDrawer({
const advancedSummary = advancedHaveErrors ? t('Error') : undefined
const routingStrategyConfigured = Boolean(
currentPriority ||
currentWeight ||
currentTestModel?.trim() ||
(currentAutoBan ?? 1) !== 1
currentWeight ||
currentTestModel?.trim() ||
(currentAutoBan ?? 1) !== 1
)
const internalNotesConfigured = Boolean(
currentTag?.trim() || currentRemark?.trim()
)
const overrideRulesConfigured = Boolean(
hasConfiguredOverrideValue(currentStatusCodeMapping) ||
hasConfiguredOverrideValue(currentParamOverride) ||
hasConfiguredOverrideValue(currentHeaderOverride)
hasConfiguredOverrideValue(currentParamOverride) ||
hasConfiguredOverrideValue(currentHeaderOverride)
)
const extraSettingsConfigured = Boolean(
currentForceFormat ||
currentThinkingToContent ||
currentPassThroughBodyEnabled ||
currentDisableTaskPollingSleep ||
currentProxy?.trim() ||
currentSystemPrompt?.trim() ||
currentSystemPromptOverride
currentThinkingToContent ||
currentPassThroughBodyEnabled ||
currentDisableTaskPollingSleep ||
currentProxy?.trim() ||
currentSystemPrompt?.trim() ||
currentSystemPromptOverride
)
let fieldPassthroughConfigured = false
if (currentType === 1) {
fieldPassthroughConfigured = Boolean(
currentAllowServiceTier ||
currentDisableStore ||
currentAllowSafetyIdentifier ||
currentAllowIncludeObfuscation ||
currentAllowInferenceGeo
currentDisableStore ||
currentAllowSafetyIdentifier ||
currentAllowIncludeObfuscation ||
currentAllowInferenceGeo
)
} else if (currentType === 14) {
fieldPassthroughConfigured = Boolean(
currentAllowServiceTier ||
currentAllowInferenceGeo ||
currentAllowSpeed ||
currentClaudeBetaQuery
currentAllowInferenceGeo ||
currentAllowSpeed ||
currentClaudeBetaQuery
)
}
const upstreamModelDetectionConfigured = Boolean(
upstreamModelUpdateCheckEnabled ||
currentUpstreamModelUpdateAutoSyncEnabled ||
currentUpstreamModelUpdateIgnoredModels?.trim()
currentUpstreamModelUpdateAutoSyncEnabled ||
currentUpstreamModelUpdateIgnoredModels?.trim()
)
const advancedConfigured = Boolean(
routingStrategyConfigured ||
internalNotesConfigured ||
overrideRulesConfigured ||
extraSettingsConfigured ||
fieldPassthroughConfigured ||
upstreamModelDetectionConfigured
internalNotesConfigured ||
overrideRulesConfigured ||
extraSettingsConfigured ||
fieldPassthroughConfigured ||
upstreamModelDetectionConfigured
)
const advancedNavChildren: ChannelEditorNavChildItem[] = [
{
@@ -2674,14 +2672,18 @@ export function ChannelMutateDrawer({
</Badge>
)
)}
{hiddenAdvancedCustomRouteTypeCount > 0 && (
{hiddenAdvancedCustomRouteTypeCount >
0 && (
<Badge
variant='outline'
title={
advancedCustomRouteTypeTitle
}
>
+{hiddenAdvancedCustomRouteTypeCount}
+
{
hiddenAdvancedCustomRouteTypeCount
}
</Badge>
)}
{!advancedCustomStats.valid && (
@@ -4116,9 +4118,7 @@ export function ChannelMutateDrawer({
>
<CardHeading
title={t('Field passthrough controls')}
icon={
<SlidersHorizontal className='h-4 w-4' />
}
icon={<SlidersHorizontal className='h-4 w-4' />}
/>
<fieldset
disabled={sensitiveLocked}
@@ -16,8 +16,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { ReactNode } from 'react'
import { KeyRound } from 'lucide-react'
import type { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import {
@@ -16,8 +16,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { ReactNode } from 'react'
import { KeyRound } from 'lucide-react'
import type { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
type ChannelAuthSectionProps = {
@@ -16,9 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { ReactNode } from 'react'
import { Server } from 'lucide-react'
import type { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import {
SideDrawerSection,
SideDrawerSectionHeader,
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { Skeleton } from '@/components/ui/skeleton'
export function ChannelEditorLoadingState() {
@@ -16,9 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { ReactNode } from 'react'
import { Boxes } from 'lucide-react'
import type { ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import {
SideDrawerSection,
SideDrawerSectionHeader,
@@ -16,15 +16,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useId, useMemo, useRef, useState } from 'react'
import { Code, Plus, Table, Trash2 } from 'lucide-react'
import { useEffect, useId, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Alert, AlertDescription } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Textarea } from '@/components/ui/textarea'
import { cn } from '@/lib/utils'
type ModelMappingEditorProps = {
value: string
@@ -16,10 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useEffect, useRef } from 'react'
import { Minus, Plus } from 'lucide-react'
import { cn } from '@/lib/utils'
import { useState, useEffect, useRef } from 'react'
import { Label } from '@/components/ui/label'
import { cn } from '@/lib/utils'
interface NumericSpinnerInputProps {
value: number | null | undefined
@@ -19,12 +19,14 @@ For commercial licensing, please contact support@quantumnous.com
import { useMutation } from '@tanstack/react-query'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import {
ADMIN_PERMISSION_ACTIONS,
ADMIN_PERMISSION_RESOURCES,
hasPermission,
} from '@/lib/admin-permissions'
import { useAuthStore } from '@/stores/auth-store'
import { createChannel, updateChannel } from '../api'
import { ERROR_MESSAGES, SUCCESS_MESSAGES } from '../constants'
import {
@@ -19,7 +19,9 @@ For commercial licensing, please contact support@quantumnous.com
import { useRef, useState, useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { api, type ApiRequestConfig } from '@/lib/api'
import { normalizeModelList } from '../lib/upstream-update-utils'
const upstreamUpdateRequestConfig = {
+5 -5
View File
@@ -16,10 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { Link } from '@tanstack/react-router'
import { useQuery } from '@tanstack/react-query'
import { Link } from '@tanstack/react-router'
import { Settings2 } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { SectionPageLayout } from '@/components/layout'
import { Badge } from '@/components/ui/badge'
import {
@@ -29,6 +30,7 @@ import {
} from '@/components/ui/tooltip'
import { ROLE } from '@/lib/roles'
import { useAuthStore } from '@/stores/auth-store'
import { getChannelOps } from './api'
import { ChannelsDialogs } from './components/channels-dialogs'
import { ChannelsPrimaryButtons } from './components/channels-primary-buttons'
@@ -48,9 +50,7 @@ export function Channels() {
})
const retryTimes = channelOpsQuery.data?.data?.retry_times
const retryLabel =
typeof retryTimes === 'number'
? `${t('Max Retries')}: ${retryTimes}`
: null
typeof retryTimes === 'number' ? `${t('Max Retries')}: ${retryTimes}` : null
let retryBadge = null
if (retryLabel) {
retryBadge = isRoot ? (
+3 -1
View File
@@ -565,7 +565,9 @@ function normalizeAdvancedCustomRoute(
return nextRoute
}
function getAdvancedCustomRouteUpstreamPath(route: AdvancedCustomRoute): string {
function getAdvancedCustomRouteUpstreamPath(
route: AdvancedCustomRoute
): string {
return (route.upstream_path || '').trim()
}
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { FieldPath } from 'react-hook-form'
import type { ChannelFormValues } from './channel-form'
type ChannelFormErrorMap = Partial<
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { z } from 'zod'
import {
CHANNEL_STATUS,
ERROR_MESSAGES,
+2 -1
View File
@@ -17,9 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useQuery } from '@tanstack/react-query'
import { useAuthStore } from '@/stores/auth-store'
import { fetchTokenKey, getApiKeys } from '@/features/keys/api'
import { API_KEY_STATUS } from '@/features/keys/constants'
import { useAuthStore } from '@/stores/auth-store'
export async function fetchActiveChatKey() {
const result = await getApiKeys({ p: 1, size: 50 })
+3 -1
View File
@@ -17,8 +17,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { useStatus } from '@/hooks/use-status'
import type { SystemStatus } from '@/features/auth/types'
import { useStatus } from '@/hooks/use-status'
import {
type ChatPreset,
parseChatConfig,
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { api } from '@/lib/api'
import type {
FlowQuotaDataItem,
QuotaDataItem,
@@ -16,14 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import {
Fragment,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import { useQuery } from '@tanstack/react-query'
import { VChart } from '@visactor/react-vchart'
import type { EventParamsDefinition, IVChart } from '@visactor/vchart'
@@ -39,6 +31,14 @@ import {
Route,
WalletCards,
} from 'lucide-react'
import {
Fragment,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { MultiSelect } from '@/components/multi-select'
@@ -90,6 +90,7 @@ import { useChartTheme } from '@/lib/use-chart-theme'
import { cn } from '@/lib/utils'
import { VCHART_OPTION } from '@/lib/vchart'
import { useAuthStore } from '@/stores/auth-store'
import { FlowNodeFilterControl } from './flow-node-filter'
interface FlowChartsProps {
@@ -172,9 +173,7 @@ const FLOW_OTHER_NODE_LABEL_KEYS: Record<FlowNodeKind, string> = {
type FlowChartPointerEvent = EventParamsDefinition['pointerdown']
function chartRecordValue(
value: unknown
): Record<string, unknown> | undefined {
function chartRecordValue(value: unknown): Record<string, unknown> | undefined {
return value && typeof value === 'object'
? (value as Record<string, unknown>)
: undefined
@@ -469,7 +468,9 @@ export function FlowCharts(props: FlowChartsProps) {
overflowMode,
flowRole,
activeFlowNode ? flowNodeFilterKey(activeFlowNode) : '',
activeFlowLink ? `${activeFlowLink.source}\u0000${activeFlowLink.target}` : '',
activeFlowLink
? `${activeFlowLink.source}\u0000${activeFlowLink.target}`
: '',
selectedNodes.map(flowNodeFilterKey).join(','),
selectedUsers.join(','),
visibleStages.join(','),
@@ -16,8 +16,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { Filter, X } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { Badge } from '@/components/ui/badge'
@@ -16,13 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useMemo, useRef, useState } from 'react'
import { VChart } from '@visactor/react-vchart'
import { AreaChart, BarChart3, WalletCards } from 'lucide-react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useThemeRadiusPx } from '@/lib/theme-radius'
import type { TimeGranularity } from '@/lib/time'
import { VCHART_OPTION } from '@/lib/vchart'
import { useThemeCustomization } from '@/context/theme-customization-provider'
import { useTheme } from '@/context/theme-provider'
import {
@@ -34,6 +32,9 @@ import type {
ConsumptionDistributionChartType,
QuotaDataItem,
} from '@/features/dashboard/types'
import { useThemeRadiusPx } from '@/lib/theme-radius'
import type { TimeGranularity } from '@/lib/time'
import { VCHART_OPTION } from '@/lib/vchart'
let themeManagerPromise: Promise<
(typeof import('@visactor/vchart'))['ThemeManager']
@@ -18,10 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/stores/auth-store'
import { formatCompactNumber, formatNumber, formatQuota } from '@/lib/format'
import { computeTimeRange } from '@/lib/time'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton'
import { getUserQuotaDates } from '@/features/dashboard/api'
import { useModelStatCardsConfig } from '@/features/dashboard/hooks/use-dashboard-config'
@@ -34,6 +31,10 @@ import type {
QuotaDataItem,
DashboardFilters,
} from '@/features/dashboard/types'
import { formatCompactNumber, formatNumber, formatQuota } from '@/lib/format'
import { computeTimeRange } from '@/lib/time'
import { cn } from '@/lib/utils'
import { useAuthStore } from '@/stores/auth-store'
interface LogStatCardsProps {
filters?: DashboardFilters
@@ -16,13 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useMemo, useState, useRef } from 'react'
import { VChart } from '@visactor/react-vchart'
import { PieChart as PieChartIcon } from 'lucide-react'
import { useEffect, useMemo, useState, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useThemeRadiusPx } from '@/lib/theme-radius'
import type { TimeGranularity } from '@/lib/time'
import { VCHART_OPTION } from '@/lib/vchart'
import { useThemeCustomization } from '@/context/theme-customization-provider'
import { useTheme } from '@/context/theme-provider'
import {
@@ -34,6 +32,9 @@ import type {
ModelAnalyticsChartTab,
QuotaDataItem,
} from '@/features/dashboard/types'
import { useThemeRadiusPx } from '@/lib/theme-radius'
import type { TimeGranularity } from '@/lib/time'
import { VCHART_OPTION } from '@/lib/vchart'
let themeManagerPromise: Promise<
(typeof import('@visactor/vchart'))['ThemeManager']
@@ -16,10 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import { Save, Settings2 } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { TimeGranularity } from '@/lib/time'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import {
@@ -30,7 +31,6 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { Dialog } from '@/components/dialog'
import {
CONSUMPTION_DISTRIBUTION_CHART_OPTIONS,
MODEL_ANALYTICS_CHART_OPTIONS,
@@ -42,6 +42,7 @@ import type {
DashboardChartPreferences,
ModelAnalyticsChartTab,
} from '@/features/dashboard/types'
import type { TimeGranularity } from '@/lib/time'
interface ModelsChartPreferencesProps {
preferences: DashboardChartPreferences
@@ -16,12 +16,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState } from 'react'
import { Filter, RotateCcw, Calendar, Search } from 'lucide-react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/stores/auth-store'
import { getRollingDateRange, type TimeGranularity } from '@/lib/time'
import { cn } from '@/lib/utils'
import { DateTimePicker } from '@/components/datetime-picker'
import { Dialog } from '@/components/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
@@ -34,8 +34,6 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import { DateTimePicker } from '@/components/datetime-picker'
import { Dialog } from '@/components/dialog'
import {
TIME_GRANULARITY_OPTIONS,
TIME_RANGE_PRESETS,
@@ -48,6 +46,9 @@ import type {
DashboardChartPreferences,
DashboardFilters,
} from '@/features/dashboard/types'
import { getRollingDateRange, type TimeGranularity } from '@/lib/time'
import { cn } from '@/lib/utils'
import { useAuthStore } from '@/stores/auth-store'
interface ModelsFilterProps {
preferences: DashboardChartPreferences
@@ -103,7 +104,8 @@ export function ModelsFilter(props: ModelsFilterProps) {
const [open, setOpen] = useState(false)
const [filters, setFilters] = useState<DashboardFilters>(
() => props.currentFilters ?? buildDefaultDashboardFilters(props.preferences)
() =>
props.currentFilters ?? buildDefaultDashboardFilters(props.preferences)
)
const [selectedRange, setSelectedRange] = useState<number | null>(() =>
detectQuickRangeDays(props.currentFilters)
@@ -16,11 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Gauge, HeartPulse, Timer } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton'
import { getPerfMetricsSummary } from '@/features/performance-metrics/api'
import {
@@ -31,6 +31,7 @@ import {
getSuccessRateTextClass,
} from '@/features/performance-metrics/lib/format'
import type { PerfModelSummary } from '@/features/performance-metrics/types'
import { cn } from '@/lib/utils'
const PERFORMANCE_WINDOW_HOURS = 24
const TOP_MODEL_LIMIT = 6
@@ -17,10 +17,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { RichContent } from '@/components/rich-content'
import { formatDateTimeObject } from '@/lib/time'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Dialog } from '@/components/dialog'
import { RichContent } from '@/components/rich-content'
import { ScrollArea } from '@/components/ui/scroll-area'
import { formatDateTimeObject } from '@/lib/time'
interface AnnouncementDetailModalProps {
open: boolean
@@ -16,16 +16,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { memo, useState } from 'react'
import { Megaphone } from 'lucide-react'
import { memo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { getAnnouncementColorClass } from '@/lib/colors'
import { formatDateTimeObject } from '@/lib/time'
import { cn } from '@/lib/utils'
import { ScrollArea } from '@/components/ui/scroll-area'
import { useAnnouncements } from '@/features/dashboard/hooks/use-status-data'
import { getPreviewText } from '@/features/dashboard/lib'
import type { AnnouncementItem } from '@/features/dashboard/types'
import { getAnnouncementColorClass } from '@/lib/colors'
import { formatDateTimeObject } from '@/lib/time'
import { cn } from '@/lib/utils'
import { PanelWrapper } from '../ui/panel-wrapper'
import { AnnouncementDetailModal } from './announcement-detail-dialog'
@@ -18,16 +18,17 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { Zap, ExternalLink, Gauge } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { getBgColorClass } from '@/lib/colors'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { CopyButton } from '@/components/copy-button'
import { StatusBadge } from '@/components/status-badge'
import { Button } from '@/components/ui/button'
import {
getLatencyColorClass,
openExternalSpeedTest,
} from '@/features/dashboard/lib/api-info'
import type { ApiInfoItem, PingStatus } from '@/features/dashboard/types'
import { getBgColorClass } from '@/lib/colors'
import { cn } from '@/lib/utils'
interface ApiInfoItemProps {
item: ApiInfoItem
@@ -16,9 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useCallback } from 'react'
import { Route } from 'lucide-react'
import { useState, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { ScrollArea } from '@/components/ui/scroll-area'
import { useApiInfo } from '@/features/dashboard/hooks/use-status-data'
import {
@@ -26,6 +27,7 @@ import {
getDefaultPingStatus,
} from '@/features/dashboard/lib/api-info'
import type { PingStatusMap, ApiInfoItem } from '@/features/dashboard/types'
import { PanelWrapper } from '../ui/panel-wrapper'
import { ApiInfoItemComponent } from './api-info-item'
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { HelpCircle } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import {
Accordion,
AccordionContent,
@@ -28,6 +29,7 @@ import { Markdown } from '@/components/ui/markdown'
import { ScrollArea } from '@/components/ui/scroll-area'
import { useFAQ } from '@/features/dashboard/hooks/use-status-data'
import type { FAQItem } from '@/features/dashboard/types'
import { PanelWrapper } from '../ui/panel-wrapper'
export function FAQPanel() {
@@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Link } from '@tanstack/react-router'
import {
@@ -38,21 +37,24 @@ import {
type LucideIcon,
} from 'lucide-react'
import { motion, useReducedMotion } from 'motion/react'
import { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth-store'
import { getUserModels } from '@/lib/api'
import { MOTION_TRANSITION } from '@/lib/motion'
import { ROLE } from '@/lib/roles'
import { cn } from '@/lib/utils'
import { useCopyToClipboard } from '@/hooks/use-copy-to-clipboard'
import { Button } from '@/components/ui/button'
import {
CardStaggerContainer,
CardStaggerItem,
} from '@/components/page-transition'
import { Button } from '@/components/ui/button'
import { fetchTokenKey, getApiKeys } from '@/features/keys/api'
import type { ApiKey } from '@/features/keys/types'
import { useCopyToClipboard } from '@/hooks/use-copy-to-clipboard'
import { getUserModels } from '@/lib/api'
import { MOTION_TRANSITION } from '@/lib/motion'
import { ROLE } from '@/lib/roles'
import { cn } from '@/lib/utils'
import { useAuthStore } from '@/stores/auth-store'
import {
useApiInfo,
useDashboardContentVisibility,
@@ -16,11 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Gauge, HeartPulse, Timer } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton'
import { getPerfMetricsSummary } from '@/features/performance-metrics/api'
import {
@@ -31,6 +31,7 @@ import {
getSuccessRateTextClass,
} from '@/features/performance-metrics/lib/format'
import type { PerfModelSummary } from '@/features/performance-metrics/types'
import { cn } from '@/lib/utils'
const PERFORMANCE_WINDOW_HOURS = 24
const TOP_MODEL_LIMIT = 6
@@ -16,22 +16,24 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Link } from '@tanstack/react-router'
import { ArrowRight, Flame, ShieldCheck, TrendingDown } from 'lucide-react'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/stores/auth-store'
import { StaggerContainer, StaggerItem } from '@/components/page-transition'
import { Button } from '@/components/ui/button'
import { getUserQuotaDates } from '@/features/dashboard/api'
import { useSummaryCardsConfig } from '@/features/dashboard/hooks/use-dashboard-config'
import type { QuotaDataItem } from '@/features/dashboard/types'
import { useStatus } from '@/hooks/use-status'
import { getCurrencyLabel, isCurrencyDisplayEnabled } from '@/lib/currency'
import { formatNumber, formatQuota } from '@/lib/format'
import { computeTimeRange } from '@/lib/time'
import { cn } from '@/lib/utils'
import { useStatus } from '@/hooks/use-status'
import { Button } from '@/components/ui/button'
import { StaggerContainer, StaggerItem } from '@/components/page-transition'
import { getUserQuotaDates } from '@/features/dashboard/api'
import { useSummaryCardsConfig } from '@/features/dashboard/hooks/use-dashboard-config'
import type { QuotaDataItem } from '@/features/dashboard/types'
import { useAuthStore } from '@/stores/auth-store'
import { StatCard } from '../ui/stat-card'
const SUMMARY_SPARKLINE_BUCKETS = 12
@@ -16,10 +16,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { memo, useEffect, useState } from 'react'
import { Activity, RotateCw } from 'lucide-react'
import { memo, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { ScrollArea } from '@/components/ui/scroll-area'
import { getUptimeStatus } from '@/features/dashboard/api'
@@ -27,6 +27,8 @@ import type {
UptimeGroupResult,
UptimeMonitor,
} from '@/features/dashboard/types'
import { cn } from '@/lib/utils'
import { PanelWrapper } from '../ui/panel-wrapper'
const STATUS_COLOR_MAP: Record<number, string> = {
@@ -18,8 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { type ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Skeleton } from '@/components/ui/skeleton'
import { cn } from '@/lib/utils'
interface PanelWrapperProps {
title: ReactNode
@@ -16,10 +16,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useId, type ReactNode } from 'react'
import { type LucideIcon } from 'lucide-react'
import { cn } from '@/lib/utils'
import { useId, type ReactNode } from 'react'
import { Skeleton } from '@/components/ui/skeleton'
import { cn } from '@/lib/utils'
type StatCardTone = 'rose' | 'teal' | 'gray'
type StatCardSparklineVariant = 'bars' | 'line'
@@ -16,16 +16,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useEffect, useMemo, useState, useRef, useCallback } from 'react'
import { useQuery } from '@tanstack/react-query'
import { VChart } from '@visactor/react-vchart'
import { Users, Loader2 } from 'lucide-react'
import { useEffect, useMemo, useState, useRef, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { getRollingDateRange, type TimeGranularity } from '@/lib/time'
import { VCHART_OPTION } from '@/lib/vchart'
import { useTheme } from '@/context/theme-provider'
import { Skeleton } from '@/components/ui/skeleton'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { useTheme } from '@/context/theme-provider'
import { getUserQuotaDataByUsers } from '@/features/dashboard/api'
import {
TIME_GRANULARITY_OPTIONS,
@@ -40,6 +39,8 @@ import type {
ProcessedUserChartData,
UserChartsFilters,
} from '@/features/dashboard/types'
import { getRollingDateRange, type TimeGranularity } from '@/lib/time'
import { VCHART_OPTION } from '@/lib/vchart'
let themeManagerPromise: Promise<
(typeof import('@visactor/vchart'))['ThemeManager']
@@ -28,6 +28,7 @@ import {
type LucideIcon,
} from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { safeDivide } from '@/features/dashboard/lib'
interface StatCardConfig {
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useStatus } from '@/hooks/use-status'
import type { AnnouncementItem, ApiInfoItem, FAQItem } from '../types'
/**
+7 -5
View File
@@ -16,12 +16,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useCallback, useMemo, lazy, Suspense } from 'react'
import { getRouteApi, useNavigate } from '@tanstack/react-router'
import { Eye, EyeOff } from 'lucide-react'
import { useState, useCallback, useMemo, lazy, Suspense } from 'react'
import { useTranslation } from 'react-i18next'
import { useAuthStore } from '@/stores/auth-store'
import { ROLE } from '@/lib/roles'
import { SectionPageLayout } from '@/components/layout'
import { FadeIn } from '@/components/page-transition'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
@@ -30,8 +31,9 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { SectionPageLayout } from '@/components/layout'
import { FadeIn } from '@/components/page-transition'
import { ROLE } from '@/lib/roles'
import { useAuthStore } from '@/stores/auth-store'
import { ModelsChartPreferences } from './components/models/models-chart-preferences'
import { ModelsFilter } from './components/models/models-filter-dialog'
import { OverviewDashboard } from './components/overview/overview-dashboard'
+3 -2
View File
@@ -17,14 +17,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { dataScheme as vchartDefaultDataScheme } from '@visactor/vchart/esm/theme/color-scheme/builtin/default'
import { getCurrencyDisplay } from '@/lib/currency'
import { formatChartTime, type TimeGranularity } from '@/lib/time'
import { MAX_CHART_TREND_POINTS } from '@/features/dashboard/constants'
import type {
QuotaDataItem,
ProcessedChartData,
ProcessedUserChartData,
} from '@/features/dashboard/types'
import { getCurrencyDisplay } from '@/lib/currency'
import { formatChartTime, type TimeGranularity } from '@/lib/time'
type TFunction = (key: string) => string
type TooltipLineItem = {
+1 -1
View File
@@ -16,7 +16,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { getRollingDateRange, type TimeGranularity } from '@/lib/time'
import {
DASHBOARD_CHART_PREFERENCES_STORAGE_KEY,
DEFAULT_DASHBOARD_CHART_PREFERENCES,
@@ -32,6 +31,7 @@ import type {
DashboardFilters,
ModelAnalyticsChartTab,
} from '@/features/dashboard/types'
import { getRollingDateRange, type TimeGranularity } from '@/lib/time'
function isTimeGranularity(value: unknown): value is TimeGranularity {
return value === 'hour' || value === 'day' || value === 'week'
@@ -1,5 +1,6 @@
import assert from 'node:assert/strict'
import { describe, test } from 'node:test'
import type { FlowUserFilterOption } from '../types'
import {
compactFlowSelectionLabel,
+2 -4
View File
@@ -297,8 +297,7 @@ describe('dashboard flow data', () => {
assert.equal(
result.filterOptions.nodes.some(
(option) =>
option.kind === 'model' && option.value === 'model:model-c'
(option) => option.kind === 'model' && option.value === 'model:model-c'
),
true
)
@@ -779,8 +778,7 @@ describe('dashboard flow data', () => {
)
const dimmedLink = values.links.find(
(link: Record<string, unknown>) =>
link.source === 'model:claude-4-sonnet' &&
link.target === 'channel:101'
link.source === 'model:claude-4-sonnet' && link.target === 'channel:101'
)
const nodeOpacity = flowSpec.node.style.fillOpacity
const linkOpacity = flowSpec.link.style.fillOpacity
+18 -19
View File
@@ -138,7 +138,9 @@ const SENSITIVE_FLOW_KINDS = new Set<FlowNodeKind>([
'channel',
])
const OTHER_FLOW_NODE_ID_SET = new Set<string>(Object.values(OTHER_FLOW_NODE_IDS))
const OTHER_FLOW_NODE_ID_SET = new Set<string>(
Object.values(OTHER_FLOW_NODE_IDS)
)
function numberValue(value: unknown): number {
const n = Number(value)
@@ -146,7 +148,9 @@ function numberValue(value: unknown): number {
}
function isFlowNodeKind(value: unknown): value is FlowNodeKind {
return typeof value === 'string' && FLOW_NODE_KIND_SET.has(value as FlowNodeKind)
return (
typeof value === 'string' && FLOW_NODE_KIND_SET.has(value as FlowNodeKind)
)
}
function rowMetrics(row: FlowQuotaDataItem): FlowMetrics {
@@ -399,7 +403,9 @@ function selectedNodeFiltersExceptKind(
selectedNodes: readonly FlowNodeFilter[] | undefined,
kind: FlowNodeKind
): FlowNodeFilter[] | undefined {
const filtered = (selectedNodes ?? []).filter((filter) => filter.kind !== kind)
const filtered = (selectedNodes ?? []).filter(
(filter) => filter.kind !== kind
)
return filtered.length > 0 ? filtered : undefined
}
@@ -932,14 +938,13 @@ function buildNodeFilterOptions(
}
}
return options
.sort(
(a, b) =>
(stageOrder.get(a.kind) ?? 0) - (stageOrder.get(b.kind) ?? 0) ||
b.valueRaw - a.valueRaw ||
a.label.localeCompare(b.label) ||
a.value.localeCompare(b.value)
)
return options.sort(
(a, b) =>
(stageOrder.get(a.kind) ?? 0) - (stageOrder.get(b.kind) ?? 0) ||
b.valueRaw - a.valueRaw ||
a.label.localeCompare(b.label) ||
a.value.localeCompare(b.value)
)
}
export function buildFlowFilterOptions(
@@ -1041,17 +1046,11 @@ function sankeyDatumValue(
return sankeyDatumSource(datum)[key]
}
function sankeyDatumFlag(
datum: Record<string, unknown>,
key: string
): boolean {
function sankeyDatumFlag(datum: Record<string, unknown>, key: string): boolean {
return sankeyDatumValue(datum, key) === true
}
export function flowSankeyDatumValue(
datum: unknown,
key: string
): unknown {
export function flowSankeyDatumValue(datum: unknown, key: string): unknown {
const record = recordValue(datum)
return record ? sankeyDatumValue(record, key) : undefined
}
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import type { TFunction } from 'i18next'
import { createSectionRegistry } from '@/features/system-settings/utils/section-registry'
/**
+1
View File
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useNavigate, useRouter } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
export function ForbiddenError() {
+2 -1
View File
@@ -18,8 +18,9 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useNavigate, useRouter } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { cn } from '@/lib/utils'
const FEEDBACK_URL = 'https://github.com/QuantumNous/new-api/issues'
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
export function MaintenanceError() {
+1
View File
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useNavigate, useRouter } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
export function NotFoundError() {
@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/
import { useNavigate, useRouter } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
export function UnauthorisedError() {
+1
View File
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { api } from '@/lib/api'
import type { HomePageContentResponse } from './types'
// ============================================================================
@@ -17,7 +17,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useTranslation } from 'react-i18next'
import { Separator } from '@/components/ui/separator'
import { getGatewayFeatures } from '../constants'
interface GatewayCardProps {
@@ -19,6 +19,7 @@ For commercial licensing, please contact support@quantumnous.com
import { Link } from '@tanstack/react-router'
import { ArrowRight } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
interface HeroButtonsProps {
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { useState, useEffect, useRef, type ReactNode } from 'react'
import { cn } from '@/lib/utils'
type AccentTone = 'emerald' | 'amber' | 'blue' | 'violet'
@@ -17,6 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { cn } from '@/lib/utils'
import { IconCard } from './icon-card'
interface ScrollingIconsProps {
+2 -1
View File
@@ -19,8 +19,9 @@ For commercial licensing, please contact support@quantumnous.com
import { Link } from '@tanstack/react-router'
import { ArrowRight } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { Button } from '@/components/ui/button'
import { AnimateInView } from '@/components/animate-in-view'
import { Button } from '@/components/ui/button'
interface CTAProps {
className?: string

Some files were not shown because too many files have changed in this diff Show More