@samanhappy/mcphub 0.12.17 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.fr.md +7 -5
- package/README.md +24 -4
- package/README.zh.md +25 -4
- package/bin/cli.js +64 -50
- package/dist/cli/call-arguments.js +81 -0
- package/dist/cli/call-arguments.js.map +1 -0
- package/dist/cli/commands/call.js +75 -0
- package/dist/cli/commands/call.js.map +1 -0
- package/dist/cli/commands/config.js +132 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/discover.js +127 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/export.js +20 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/groups.js +107 -0
- package/dist/cli/commands/groups.js.map +1 -0
- package/dist/cli/commands/install.js +173 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/keys.js +91 -0
- package/dist/cli/commands/keys.js.map +1 -0
- package/dist/cli/commands/login.js +70 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/servers.js +142 -0
- package/dist/cli/commands/servers.js.map +1 -0
- package/dist/cli/commands/tools.js +162 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/context.js +44 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/errors.js +19 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/help.js +157 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/http.js +93 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/main.js +81 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.js +47 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parse-args.js +103 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/profile.js +109 -0
- package/dist/cli/profile.js.map +1 -0
- package/dist/cli/prompts.js +56 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/controllers/oauthServerController.js +37 -1
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/dao/ServerDaoDbImpl.js +3 -0
- package/dist/dao/ServerDaoDbImpl.js.map +1 -1
- package/dist/db/connection.js +48 -4
- package/dist/db/connection.js.map +1 -1
- package/dist/db/entities/Server.js +4 -0
- package/dist/db/entities/Server.js.map +1 -1
- package/dist/db/entities/VectorEmbedding.js +2 -5
- package/dist/db/entities/VectorEmbedding.js.map +1 -1
- package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
- package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
- package/dist/services/dataService.js +10 -1
- package/dist/services/dataService.js.map +1 -1
- package/dist/services/mcpService.js +47 -10
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/sseService.js +5 -3
- package/dist/services/sseService.js.map +1 -1
- package/dist/services/vectorSearchService.js +16 -3
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/migration.js +1 -0
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/serverConfigPersistence.js +5 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/frontend/dist/assets/ActivityPage-DwzGiMh_.js +2 -0
- package/frontend/dist/assets/ActivityPage-DwzGiMh_.js.map +1 -0
- package/frontend/dist/assets/ConfirmDialog-CxlizGia.js +2 -0
- package/frontend/dist/assets/ConfirmDialog-CxlizGia.js.map +1 -0
- package/frontend/dist/assets/Dashboard-BUCJcvk-.js +2 -0
- package/frontend/dist/assets/Dashboard-BUCJcvk-.js.map +1 -0
- package/frontend/dist/assets/DeleteDialog-DRbWonMu.js +2 -0
- package/frontend/dist/assets/DeleteDialog-DRbWonMu.js.map +1 -0
- package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js +2 -0
- package/frontend/dist/assets/EndpointCopy-D5NjDdYi.js.map +1 -0
- package/frontend/dist/assets/GroupsPage-DfLlww4U.js +33 -0
- package/frontend/dist/assets/GroupsPage-DfLlww4U.js.map +1 -0
- package/frontend/dist/assets/LoginPage-DCjqYw_8.js +2 -0
- package/frontend/dist/assets/LoginPage-DCjqYw_8.js.map +1 -0
- package/frontend/dist/assets/LogsPage-CTa8kuDf.js +2 -0
- package/frontend/dist/assets/LogsPage-CTa8kuDf.js.map +1 -0
- package/frontend/dist/assets/MarketPage-C2Rh4WJB.js +3 -0
- package/frontend/dist/assets/MarketPage-C2Rh4WJB.js.map +1 -0
- package/frontend/dist/assets/{Pagination-y-gVO8ms.js → Pagination-BFi-X7qY.js} +2 -2
- package/frontend/dist/assets/{Pagination-y-gVO8ms.js.map → Pagination-BFi-X7qY.js.map} +1 -1
- package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js +2 -0
- package/frontend/dist/assets/PromptsPage-Dh3qjX3x.js.map +1 -0
- package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js +2 -0
- package/frontend/dist/assets/ResourcesPage-Bc5ZpCIh.js.map +1 -0
- package/frontend/dist/assets/ServersPage-hgCbCglG.js +37 -0
- package/frontend/dist/assets/ServersPage-hgCbCglG.js.map +1 -0
- package/frontend/dist/assets/SettingsPage-BzNX8mXv.js +12 -0
- package/frontend/dist/assets/SettingsPage-BzNX8mXv.js.map +1 -0
- package/frontend/dist/assets/StatusDot-CQzailBQ.js +2 -0
- package/frontend/dist/assets/StatusDot-CQzailBQ.js.map +1 -0
- package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js → ToggleGroup-CNBBvo3C.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-HfxdlkGi.js.map → ToggleGroup-CNBBvo3C.js.map} +1 -1
- package/frontend/dist/assets/UsersPage-C33b7LCM.js +2 -0
- package/frontend/dist/assets/UsersPage-C33b7LCM.js.map +1 -0
- package/frontend/dist/assets/{framework-vendor-_OBebcuv.js → framework-vendor-BUhDPOUZ.js} +2 -2
- package/frontend/dist/assets/{framework-vendor-_OBebcuv.js.map → framework-vendor-BUhDPOUZ.js.map} +1 -1
- package/frontend/dist/assets/{i18n-vendor-MQ921plD.js → i18n-vendor-Kbr87Ofu.js} +2 -2
- package/frontend/dist/assets/{i18n-vendor-MQ921plD.js.map → i18n-vendor-Kbr87Ofu.js.map} +1 -1
- package/frontend/dist/assets/icons-vendor-CKgJB3SC.js +292 -0
- package/frontend/dist/assets/icons-vendor-CKgJB3SC.js.map +1 -0
- package/frontend/dist/assets/index-BGiKkKzj.js +3 -0
- package/frontend/dist/assets/index-BGiKkKzj.js.map +1 -0
- package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
- package/frontend/dist/assets/{resourceService-BfCTSBsr.js → resourceService-C6umWRgq.js} +2 -2
- package/frontend/dist/assets/{resourceService-BfCTSBsr.js.map → resourceService-C6umWRgq.js.map} +1 -1
- package/frontend/dist/assets/useServerData-P5In98R4.js +2 -0
- package/frontend/dist/assets/{useServerData-QZqQTYcv.js.map → useServerData-P5In98R4.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-Cz7vKGLE.js +2 -0
- package/frontend/dist/assets/{useSettingsData-D3VROqS7.js.map → useSettingsData-Cz7vKGLE.js.map} +1 -1
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js +16 -0
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
- package/frontend/dist/index.html +5 -5
- package/package.json +2 -1
- package/frontend/dist/assets/ActivityPage-ClgKeihP.js +0 -2
- package/frontend/dist/assets/ActivityPage-ClgKeihP.js.map +0 -1
- package/frontend/dist/assets/Badge-Ck2fhRdl.js +0 -2
- package/frontend/dist/assets/Badge-Ck2fhRdl.js.map +0 -1
- package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js +0 -2
- package/frontend/dist/assets/ConfirmDialog-uYjffH4V.js.map +0 -1
- package/frontend/dist/assets/Dashboard-BIXrLobn.js +0 -2
- package/frontend/dist/assets/Dashboard-BIXrLobn.js.map +0 -1
- package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js +0 -2
- package/frontend/dist/assets/DeleteDialog-BAfrV8EB.js.map +0 -1
- package/frontend/dist/assets/GroupsPage-BjrvyHwu.js +0 -33
- package/frontend/dist/assets/GroupsPage-BjrvyHwu.js.map +0 -1
- package/frontend/dist/assets/LoginPage-BBHt_TfF.js +0 -2
- package/frontend/dist/assets/LoginPage-BBHt_TfF.js.map +0 -1
- package/frontend/dist/assets/LogsPage-D8Znq5NB.js +0 -2
- package/frontend/dist/assets/LogsPage-D8Znq5NB.js.map +0 -1
- package/frontend/dist/assets/MarketPage-haRuzjCw.js +0 -3
- package/frontend/dist/assets/MarketPage-haRuzjCw.js.map +0 -1
- package/frontend/dist/assets/PromptsPage-ByHWPyGe.js +0 -2
- package/frontend/dist/assets/PromptsPage-ByHWPyGe.js.map +0 -1
- package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js +0 -2
- package/frontend/dist/assets/ResourcesPage-Bodw5OY9.js.map +0 -1
- package/frontend/dist/assets/ServersPage-CtS1I4yS.js +0 -37
- package/frontend/dist/assets/ServersPage-CtS1I4yS.js.map +0 -1
- package/frontend/dist/assets/SettingsPage-DxVigf7p.js +0 -12
- package/frontend/dist/assets/SettingsPage-DxVigf7p.js.map +0 -1
- package/frontend/dist/assets/UsersPage-Bipw33cS.js +0 -2
- package/frontend/dist/assets/UsersPage-Bipw33cS.js.map +0 -1
- package/frontend/dist/assets/icons-vendor-B67NtVuR.js +0 -172
- package/frontend/dist/assets/icons-vendor-B67NtVuR.js.map +0 -1
- package/frontend/dist/assets/index-CmnA4an8.js +0 -5
- package/frontend/dist/assets/index-CmnA4an8.js.map +0 -1
- package/frontend/dist/assets/index-DfFHVARX.css +0 -1
- package/frontend/dist/assets/useGroupData-DLhbP6zd.js +0 -2
- package/frontend/dist/assets/useGroupData-DLhbP6zd.js.map +0 -1
- package/frontend/dist/assets/useServerData-QZqQTYcv.js +0 -2
- package/frontend/dist/assets/useSettingsData-D3VROqS7.js +0 -2
- package/frontend/dist/assets/variableDetection-C3Xi21av.js +0 -16
- package/frontend/dist/assets/variableDetection-C3Xi21av.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingsPage-BzNX8mXv.js","sources":["../../src/utils/passwordValidation.ts","../../src/components/ChangePasswordForm.tsx","../../src/components/ui/MultiSelect.tsx","../../src/utils/key.ts","../../src/constants/permissions.ts","../../src/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * Frontend password strength validation utility\n * Should match backend validation rules\n */\n\nexport interface PasswordValidationResult {\n isValid: boolean;\n errors: string[];\n}\n\nexport const validatePasswordStrength = (password: string): PasswordValidationResult => {\n const errors: string[] = [];\n\n // Check minimum length\n if (password.length < 8) {\n errors.push('passwordMinLength');\n }\n\n // Check for at least one letter\n if (!/[a-zA-Z]/.test(password)) {\n errors.push('passwordRequireLetter');\n }\n\n // Check for at least one number\n if (!/\\d/.test(password)) {\n errors.push('passwordRequireNumber');\n }\n\n // Check for at least one special character\n if (!/[!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password)) {\n errors.push('passwordRequireSpecial');\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n};\n","import React, { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { ChangePasswordCredentials } from '../types';\nimport { changePassword } from '../services/authService';\nimport { validatePasswordStrength } from '../utils/passwordValidation';\n\ninterface ChangePasswordFormProps {\n onSuccess?: () => void;\n onCancel?: () => void;\n}\n\nconst ChangePasswordForm: React.FC<ChangePasswordFormProps> = ({ onSuccess, onCancel }) => {\n const { t } = useTranslation();\n const [formData, setFormData] = useState<ChangePasswordCredentials>({\n currentPassword: '',\n newPassword: '',\n });\n const [confirmPassword, setConfirmPassword] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [success, setSuccess] = useState(false);\n const [passwordErrors, setPasswordErrors] = useState<string[]>([]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const { name, value } = e.target;\n if (name === 'confirmPassword') {\n setConfirmPassword(value);\n } else {\n setFormData(prev => ({ ...prev, [name]: value }));\n \n // Validate password strength on change for new password\n if (name === 'newPassword') {\n const validation = validatePasswordStrength(value);\n setPasswordErrors(validation.errors);\n }\n }\n };\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n // Validate password strength\n const validation = validatePasswordStrength(formData.newPassword);\n if (!validation.isValid) {\n setError(t('auth.passwordStrengthError'));\n setPasswordErrors(validation.errors);\n return;\n }\n\n // Validate passwords match\n if (formData.newPassword !== confirmPassword) {\n setError(t('auth.passwordsNotMatch'));\n return;\n }\n\n setIsLoading(true);\n try {\n const response = await changePassword(formData);\n\n if (response.success) {\n setSuccess(true);\n if (onSuccess) {\n onSuccess();\n }\n } else {\n setError(response.message || t('auth.changePasswordError'));\n }\n } catch (err) {\n setError(t('auth.changePasswordError'));\n } finally {\n setIsLoading(false);\n }\n };\n\n return (\n <div className=\"p-6 bg-white dark:bg-gray-800 rounded-lg shadow-md\">\n <h2 className=\"text-xl font-bold mb-4\">{t('auth.changePassword')}</h2>\n\n {success ? (\n <div className=\"bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4\">\n {t('auth.changePasswordSuccess')}\n </div>\n ) : (\n <form onSubmit={handleSubmit}>\n {error && (\n <div className=\"bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4\">\n {error}\n </div>\n )}\n\n <div className=\"mb-4\">\n <label className=\"block text-gray-700 text-sm font-bold mb-2\" htmlFor=\"currentPassword\">\n {t('auth.currentPassword')}\n </label>\n <input\n type=\"password\"\n id=\"currentPassword\"\n name=\"currentPassword\"\n className=\"w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 form-input\"\n value={formData.currentPassword}\n onChange={handleChange}\n required\n />\n </div>\n\n <div className=\"mb-4\">\n <label className=\"block text-gray-700 text-sm font-bold mb-2\" htmlFor=\"newPassword\">\n {t('auth.newPassword')}\n </label>\n <input\n type=\"password\"\n id=\"newPassword\"\n name=\"newPassword\"\n className=\"w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 form-input\"\n value={formData.newPassword}\n onChange={handleChange}\n required\n minLength={8}\n />\n {/* Password strength hints */}\n {formData.newPassword && passwordErrors.length > 0 && (\n <div className=\"mt-2 text-sm text-gray-600\">\n <p className=\"font-semibold mb-1\">{t('auth.passwordStrengthHint')}</p>\n <ul className=\"list-disc list-inside space-y-1\">\n {passwordErrors.map((errorKey) => (\n <li key={errorKey} className=\"text-red-600\">\n {t(`auth.${errorKey}`)}\n </li>\n ))}\n </ul>\n </div>\n )}\n {formData.newPassword && passwordErrors.length === 0 && (\n <p className=\"mt-2 text-sm text-green-600\">✓ {t('auth.passwordStrengthHint')}</p>\n )}\n </div>\n\n <div className=\"mb-6\">\n <label className=\"block text-gray-700 text-sm font-bold mb-2\" htmlFor=\"confirmPassword\">\n {t('auth.confirmPassword')}\n </label>\n <input\n type=\"password\"\n id=\"confirmPassword\"\n name=\"confirmPassword\"\n className=\"w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 form-input\"\n value={confirmPassword}\n onChange={handleChange}\n required\n minLength={8}\n />\n </div>\n\n <div className=\"flex justify-end space-x-2\">\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={isLoading}\n className=\"hub-btn\"\n >\n {t('common.cancel')}\n </button>\n )}\n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"hub-btn primary\"\n >\n {isLoading ? (\n <span className=\"flex items-center\">\n <svg className=\"animate-spin -ml-1 mr-2 h-4 w-4 text-white\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\"></circle>\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n {t('common.save')}\n </span>\n ) : (\n t('common.save')\n )}\n </button>\n </div>\n </form>\n )}\n </div>\n );\n};\n\nexport default ChangePasswordForm;","import React, { useState, useRef, useEffect } from 'react';\nimport { Check, ChevronDown, X } from 'lucide-react';\n\ninterface MultiSelectProps {\n options: { value: string; label: string }[];\n selected: string[];\n onChange: (selected: string[]) => void;\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n}\n\nexport const MultiSelect: React.FC<MultiSelectProps> = ({\n options,\n selected,\n onChange,\n placeholder = 'Select items...',\n disabled = false,\n className = '',\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const dropdownRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setSearchTerm('');\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const filteredOptions = options.filter((option) =>\n option.label.toLowerCase().includes(searchTerm.toLowerCase()),\n );\n\n const handleToggleOption = (value: string) => {\n if (disabled) return;\n\n const newSelected = selected.includes(value)\n ? selected.filter((item) => item !== value)\n : [...selected, value];\n\n onChange(newSelected);\n };\n\n const handleRemoveItem = (value: string, e: React.MouseEvent) => {\n e.stopPropagation();\n if (disabled) return;\n onChange(selected.filter((item) => item !== value));\n };\n\n const handleToggleDropdown = () => {\n if (disabled) return;\n setIsOpen(!isOpen);\n if (!isOpen) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n };\n\n const getSelectedLabels = () => {\n return selected\n .map((value) => options.find((opt) => opt.value === value)?.label || value)\n .filter(Boolean);\n };\n\n return (\n <div ref={dropdownRef} className={`relative ${className}`}>\n {/* Selected items display */}\n <div\n onClick={handleToggleDropdown}\n className={`\n min-h-[38px] w-full px-3 py-1.5 border rounded-md shadow-sm\n flex flex-wrap items-center gap-1.5 cursor-pointer\n transition-all duration-200\n ${disabled ? 'bg-gray-100 cursor-not-allowed' : 'bg-white hover:border-blue-400'}\n ${isOpen ? 'border-blue-500 ring-1 ring-blue-500' : 'border-gray-300'}\n `}\n >\n {selected.length > 0 ? (\n <>\n {getSelectedLabels().map((label, index) => (\n <span\n key={selected[index]}\n className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300\"\n >\n {label}\n {!disabled && (\n <button\n type=\"button\"\n onClick={(e) => handleRemoveItem(selected[index], e)}\n className=\"ml-1 hover:bg-blue-200 rounded-full p-0.5 transition-colors\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n )}\n </span>\n ))}\n </>\n ) : (\n <span className=\"text-gray-400 text-sm\">{placeholder}</span>\n )}\n <div className=\"flex-1\"></div>\n <ChevronDown\n className={`h-4 w-4 text-gray-400 transition-transform duration-200 ${isOpen ? 'transform rotate-180' : ''}`}\n />\n </div>\n\n {/* Dropdown menu */}\n {isOpen && !disabled && (\n <div className=\"absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 rounded-md shadow-lg max-h-60 overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-gray-200 dark:border-gray-700\">\n <input\n ref={inputRef}\n type=\"text\"\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n placeholder=\"Search...\"\n className=\"w-full px-3 py-1.5 text-sm border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500\"\n onClick={(e) => e.stopPropagation()}\n />\n </div>\n\n {/* Options list */}\n <div className=\"max-h-48 overflow-y-auto\">\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option) => {\n const isSelected = selected.includes(option.value);\n return (\n <div\n key={option.value}\n onClick={() => handleToggleOption(option.value)}\n className={`\n px-3 py-2 cursor-pointer flex items-center justify-between\n transition-colors duration-150\n ${isSelected ? 'bg-blue-50 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300' : 'hover:bg-gray-100 dark:hover:bg-gray-700'}\n `}\n >\n <span className=\"text-sm\">{option.label}</span>\n {isSelected && <Check className=\"h-4 w-4 text-blue-600\" />}\n </div>\n );\n })\n ) : (\n <div className=\"px-3 py-2 text-sm text-gray-500 text-center\">\n {searchTerm ? 'No results found' : 'No options available'}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n};\n","export function generateRandomKey(length: number = 32): string {\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return Array.from(array)\n .map((x) => characters.charAt(x % characters.length))\n .join('');\n}\n","// Predefined permission constants\nexport const PERMISSIONS = {\n // Settings page permissions\n SETTINGS_SMART_ROUTING: 'settings:smart_routing',\n SETTINGS_ROUTE_CONFIG: 'settings:route_config',\n SETTINGS_INSTALL_CONFIG: 'settings:install_config',\n SETTINGS_SYSTEM_CONFIG: 'settings:system_config',\n SETTINGS_OAUTH_SERVER: 'settings:oauth_server',\n SETTINGS_EXPORT_CONFIG: 'settings:export_config',\n} as const;\n\nexport default PERMISSIONS;\n","import React, { useState, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router-dom';\nimport ChangePasswordForm from '@/components/ChangePasswordForm';\nimport { Switch } from '@/components/ui/ToggleGroup';\nimport { MultiSelect } from '@/components/ui/MultiSelect';\nimport { useSettingsData } from '@/hooks/useSettingsData';\nimport { useToast } from '@/contexts/ToastContext';\nimport { generateRandomKey } from '@/utils/key';\nimport { PermissionChecker } from '@/components/PermissionChecker';\nimport { PERMISSIONS } from '@/constants/permissions';\nimport { Copy, Check, Download, Edit, Trash2, Code as CodeIcon, Zap, Database, Wrench, Sparkles, RefreshCw, Route as RouteIcon, Key, Lock, Cloud, SlidersHorizontal, ShieldCheck, Package, KeyRound, FileDown, X } from 'lucide-react';\nimport { EndpointCopy } from '@/components/ui/EndpointCopy';\nimport type { BearerKey } from '@/types';\nimport { useServerContext } from '@/contexts/ServerContext';\nimport { useGroupData } from '@/hooks/useGroupData';\n\ninterface BearerKeyRowProps {\n keyData: BearerKey;\n loading: boolean;\n availableServers: { value: string; label: string }[];\n availableGroups: { value: string; label: string }[];\n onSave: (\n id: string,\n payload: {\n name: string;\n token: string;\n enabled: boolean;\n accessType: 'all' | 'groups' | 'servers' | 'custom';\n allowedGroups: string;\n allowedServers: string;\n },\n ) => Promise<void>;\n onDelete: (id: string) => Promise<void>;\n}\n\nconst BearerKeyRow: React.FC<BearerKeyRowProps> = ({\n keyData,\n loading,\n availableServers,\n availableGroups,\n onSave,\n onDelete,\n}) => {\n const { t } = useTranslation();\n const { showToast } = useToast();\n const [isEditing, setIsEditing] = useState(false);\n const [name, setName] = useState(keyData.name);\n const [token, setToken] = useState(keyData.token);\n const [enabled, setEnabled] = useState<boolean>(keyData.enabled);\n const [accessType, setAccessType] = useState<'all' | 'groups' | 'servers' | 'custom'>(\n keyData.accessType || 'all',\n );\n const [selectedGroups, setSelectedGroups] = useState<string[]>(keyData.allowedGroups || []);\n const [selectedServers, setSelectedServers] = useState<string[]>(keyData.allowedServers || []);\n const [saving, setSaving] = useState(false);\n const [deleting, setDeleting] = useState(false);\n\n useEffect(() => {\n if (!isEditing) {\n setName(keyData.name);\n setToken(keyData.token);\n setEnabled(keyData.enabled);\n setAccessType(keyData.accessType || 'all');\n setSelectedGroups(keyData.allowedGroups || []);\n setSelectedServers(keyData.allowedServers || []);\n }\n }, [keyData, isEditing]);\n\n const handleCopyToken = async () => {\n try {\n if (navigator.clipboard && window.isSecureContext) {\n await navigator.clipboard.writeText(keyData.token);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n } else {\n const textArea = document.createElement('textarea');\n textArea.value = keyData.token;\n textArea.style.position = 'fixed';\n textArea.style.left = '-9999px';\n document.body.appendChild(textArea);\n textArea.focus();\n textArea.select();\n try {\n document.execCommand('copy');\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n } catch (err) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n }\n document.body.removeChild(textArea);\n }\n } catch (error) {\n console.error('Failed to copy', error);\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n }\n };\n\n const handleSave = async () => {\n if (accessType === 'groups' && selectedGroups.length === 0) {\n showToast(t('settings.selectAtLeastOneGroup') || 'Please select at least one group', 'error');\n return;\n }\n if (accessType === 'servers' && selectedServers.length === 0) {\n showToast(\n t('settings.selectAtLeastOneServer') || 'Please select at least one server',\n 'error',\n );\n return;\n }\n if (accessType === 'custom' && selectedGroups.length === 0 && selectedServers.length === 0) {\n showToast(\n t('settings.selectAtLeastOneGroupOrServer') || 'Please select at least one group or server',\n 'error',\n );\n return;\n }\n\n setSaving(true);\n try {\n await onSave(keyData.id, {\n name,\n token,\n enabled,\n accessType,\n allowedGroups: selectedGroups.join(', '),\n allowedServers: selectedServers.join(', '),\n });\n setIsEditing(false);\n } finally {\n setSaving(false);\n }\n };\n\n const handleDelete = async () => {\n if (!window.confirm(t('settings.deleteBearerKeyConfirm') || 'Delete this key?')) {\n return;\n }\n setDeleting(true);\n try {\n await onDelete(keyData.id);\n } finally {\n setDeleting(false);\n }\n };\n\n const isGroupsMode = accessType === 'groups';\n const isCustomMode = accessType === 'custom';\n\n // Helper function to format access type display text\n const formatAccessTypeDisplay = (key: BearerKey): string => {\n if (key.accessType === 'all') {\n return t('settings.bearerKeyAccessAll') || 'All Resources';\n }\n if (key.accessType === 'groups') {\n return `${t('settings.bearerKeyAccessGroups') || 'Groups'}: ${key.allowedGroups}`;\n }\n if (key.accessType === 'servers') {\n return `${t('settings.bearerKeyAccessServers') || 'Servers'}: ${key.allowedServers}`;\n }\n if (key.accessType === 'custom') {\n const parts: string[] = [];\n if (key.allowedGroups && key.allowedGroups.length > 0) {\n parts.push(`${t('settings.bearerKeyAccessGroups') || 'Groups'}: ${key.allowedGroups}`);\n }\n if (key.allowedServers && key.allowedServers.length > 0) {\n parts.push(`${t('settings.bearerKeyAccessServers') || 'Servers'}: ${key.allowedServers}`);\n }\n return `${t('settings.bearerKeyAccessCustom') || 'Custom'}: ${parts.join('; ')}`;\n }\n return '';\n };\n\n if (isEditing) {\n return (\n <tr>\n <td colSpan={5} className=\"p-0 border-b border-gray-200 dark:border-gray-700\">\n <div className=\"bg-gray-50 dark:bg-gray-800 p-5\">\n <div className=\"grid grid-cols-1 md:grid-cols-12 gap-4 mb-4\">\n <div className=\"md:col-span-3\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyName') || 'Name'}\n </label>\n <input\n type=\"text\"\n className=\"block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input transition-shadow duration-200\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n disabled={loading}\n />\n </div>\n <div className=\"md:col-span-9\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyToken') || 'Token'}\n </label>\n <input\n type=\"text\"\n className=\"block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input transition-shadow duration-200\"\n value={token}\n onChange={(e) => setToken(e.target.value)}\n disabled={loading}\n />\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-end gap-4\">\n <div className=\"w-40\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyEnabled') || 'Status'}\n </label>\n <div className=\"flex items-center h-[38px] px-3 bg-white dark:bg-gray-800 border border-gray-300 rounded-md\">\n <span\n className={`text-sm mr-3 ${enabled ? 'text-green-600 font-medium' : 'text-gray-500'}`}\n >\n {enabled ? 'Active' : 'Inactive'}\n </span>\n <Switch\n disabled={loading}\n checked={enabled}\n onCheckedChange={(checked) => setEnabled(checked)}\n />\n </div>\n </div>\n\n <div className=\"w-48\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyAccessType') || 'Access scope'}\n </label>\n <select\n className=\"block w-full py-2 px-3 border border-gray-300 bg-white dark:bg-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-select transition-shadow duration-200\"\n value={accessType}\n onChange={(e) =>\n setAccessType(e.target.value as 'all' | 'groups' | 'servers' | 'custom')\n }\n disabled={loading}\n >\n <option value=\"all\">{t('settings.bearerKeyAccessAll') || 'All Resources'}</option>\n <option value=\"groups\">\n {t('settings.bearerKeyAccessGroups') || 'Specific Groups'}\n </option>\n <option value=\"servers\">\n {t('settings.bearerKeyAccessServers') || 'Specific Servers'}\n </option>\n <option value=\"custom\">\n {t('settings.bearerKeyAccessCustom') || 'Custom (Groups & Servers)'}\n </option>\n </select>\n </div>\n\n {/* Show single selector for groups or servers mode */}\n {!isCustomMode && (\n <div className=\"flex-1 min-w-[200px]\">\n <label\n className={`block text-sm font-medium mb-1 ${accessType === 'all' ? 'text-gray-400' : 'text-gray-700'}`}\n >\n {isGroupsMode\n ? t('settings.bearerKeyAllowedGroups') || 'Allowed groups'\n : t('settings.bearerKeyAllowedServers') || 'Allowed servers'}\n </label>\n <MultiSelect\n options={isGroupsMode ? availableGroups : availableServers}\n selected={isGroupsMode ? selectedGroups : selectedServers}\n onChange={isGroupsMode ? setSelectedGroups : setSelectedServers}\n placeholder={\n isGroupsMode\n ? t('settings.selectGroups') || 'Select groups...'\n : t('settings.selectServers') || 'Select servers...'\n }\n disabled={loading || accessType === 'all'}\n />\n </div>\n )}\n\n {/* Show both selectors for custom mode */}\n {isCustomMode && (\n <>\n <div className=\"flex-1 min-w-[200px]\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyAllowedGroups') || 'Allowed groups'}\n </label>\n <MultiSelect\n options={availableGroups}\n selected={selectedGroups}\n onChange={setSelectedGroups}\n placeholder={t('settings.selectGroups') || 'Select groups...'}\n disabled={loading}\n />\n </div>\n <div className=\"flex-1 min-w-[200px]\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyAllowedServers') || 'Allowed servers'}\n </label>\n <MultiSelect\n options={availableServers}\n selected={selectedServers}\n onChange={setSelectedServers}\n placeholder={t('settings.selectServers') || 'Select servers...'}\n disabled={loading}\n />\n </div>\n </>\n )}\n\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => setIsEditing(false)}\n className=\"px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 text-gray-700 rounded-md text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 h-[38px]\"\n >\n {t('common.cancel') || 'Cancel'}\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={loading || saving}\n className=\"hub-btn primary\"\n >\n {saving ? t('common.saving') || 'Saving...' : t('common.save') || 'Save'}\n </button>\n </div>\n </div>\n </div>\n </td>\n </tr>\n );\n }\n\n return (\n <tr className=\"hover:bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700\">\n <td className=\"px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900\">\n {keyData.name}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500 font-mono\">\n <div className=\"flex items-center gap-2\">\n <span>\n {keyData.token.length > 12\n ? `${keyData.token.substring(0, 8)}...${keyData.token.substring(keyData.token.length - 4)}`\n : keyData.token}\n </span>\n <button\n onClick={handleCopyToken}\n className=\"text-gray-400 hover:text-gray-600 transition-colors\"\n title={t('common.copy') || 'Copy'}\n >\n <Copy className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm\">\n <span className={`hub-status ${keyData.enabled ? 'ok' : 'muted'}`}>\n <span className=\"hub-dot\" />\n {keyData.enabled ? t('common.active') || 'Active' : t('common.inactive') || 'Inactive'}\n </span>\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-sm text-gray-500\">\n {formatAccessTypeDisplay(keyData)}\n </td>\n <td className=\"px-6 py-4 whitespace-nowrap text-right text-sm font-medium\">\n <button\n onClick={() => setIsEditing(true)}\n className=\"text-blue-600 hover:text-blue-900 mr-4 inline-flex items-center\"\n title={t('common.edit') || 'Edit'}\n >\n <Edit className=\"h-4 w-4\" />\n </button>\n <button\n onClick={handleDelete}\n disabled={deleting}\n className=\"text-red-600 hover:text-red-900 inline-flex items-center\"\n title={t('common.delete') || 'Delete'}\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </td>\n </tr>\n );\n};\n\n/**\n * Returns the default token limit for a given embedding model name.\n * Mirrors the backend getModelDefaultTokenLimit() function.\n * Used to display a contextual hint in the embeddingMaxTokens field.\n */\nfunction getDefaultTokenLimitForUI(model: string): number {\n const lower = model.toLowerCase();\n const MODEL_LIMITS: Array<[string, number]> = [\n ['text-embedding-3-small', 8191],\n ['text-embedding-3-large', 8191],\n ['text-embedding-ada-002', 8191],\n ['gemini-embedding-001', 2048],\n ['bge-m3', 8192],\n ];\n for (const [pattern, limit] of MODEL_LIMITS) {\n if (lower.includes(pattern)) return limit;\n }\n if (lower.includes('bge')) return 512;\n return 512;\n}\n\n/**\n * Parses embeddingMaxTokens from form input string.\n * Returns the parsed value if it differs from current value, otherwise undefined (no update needed).\n * - Empty string or whitespace → null (clear override)\n * - Valid number string → parsed number\n * - Invalid input or unchanged value → undefined\n */\nfunction parseEmbeddingMaxTokensForUpdate(\n rawValue: string,\n currentValue: number | null | undefined,\n): number | null | undefined {\n const trimmed = rawValue.trim();\n const parsed = trimmed ? parseInt(trimmed, 10) : NaN;\n const result = trimmed && !isNaN(parsed) ? parsed : null;\n const current = currentValue ?? null;\n return result !== current ? result : undefined;\n}\n\nfunction parseBasePacingDelayForUpdate(\n rawValue: string,\n currentValue: number | null | undefined,\n): number | null | undefined {\n const trimmed = rawValue.trim();\n const parsed = trimmed ? parseInt(trimmed, 10) : NaN;\n const result = trimmed && !isNaN(parsed) && parsed >= 0 ? parsed : null;\n const current = currentValue ?? null;\n return result !== current ? result : undefined;\n}\n\nconst SettingsPage: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { showToast } = useToast();\n const { allServers: servers } = useServerContext(); // Use allServers for settings (not paginated)\n const { groups } = useGroupData();\n\n const [installConfig, setInstallConfig] = useState<{\n pythonIndexUrl: string;\n npmRegistry: string;\n baseUrl: string;\n }>({\n pythonIndexUrl: '',\n npmRegistry: '',\n baseUrl: 'http://localhost:3000',\n });\n\n const [tempSmartRoutingConfig, setTempSmartRoutingConfig] = useState<{\n dbUrl: string;\n basePacingDelayMs: string;\n embeddingProvider: 'openai' | 'azure_openai';\n embeddingEncodingFormat: 'auto' | 'base64' | 'float';\n openaiApiBaseUrl: string;\n openaiApiKey: string;\n openaiApiEmbeddingModel: string;\n azureOpenaiEndpoint: string;\n azureOpenaiApiKey: string;\n azureOpenaiApiVersion: string;\n azureOpenaiEmbeddingDeployment: string;\n azureOpenaiEmbeddingModel: string;\n // Empty string = use model default; numeric string = explicit override\n embeddingMaxTokens: string;\n }>({\n dbUrl: '',\n basePacingDelayMs: '',\n embeddingProvider: 'openai',\n embeddingEncodingFormat: 'auto',\n openaiApiBaseUrl: '',\n openaiApiKey: '',\n openaiApiEmbeddingModel: '',\n azureOpenaiEndpoint: '',\n azureOpenaiApiKey: '',\n azureOpenaiApiVersion: '2024-02-15-preview',\n azureOpenaiEmbeddingDeployment: '',\n azureOpenaiEmbeddingModel: '',\n embeddingMaxTokens: '',\n });\n\n const [tempMCPRouterConfig, setTempMCPRouterConfig] = useState<{\n apiKey: string;\n referer: string;\n title: string;\n baseUrl: string;\n }>({\n apiKey: '',\n referer: 'https://www.mcphub.app',\n title: 'MCPHub',\n baseUrl: 'https://api.mcprouter.to/v1',\n });\n\n const [tempOAuthServerConfig, setTempOAuthServerConfig] = useState<{\n accessTokenLifetime: string;\n refreshTokenLifetime: string;\n authorizationCodeLifetime: string;\n allowedScopes: string;\n dynamicRegistrationAllowedGrantTypes: string;\n }>({\n accessTokenLifetime: '3600',\n refreshTokenLifetime: '1209600',\n authorizationCodeLifetime: '300',\n allowedScopes: 'read, write',\n dynamicRegistrationAllowedGrantTypes: 'authorization_code, refresh_token',\n });\n\n const [tempNameSeparator, setTempNameSeparator] = useState<string>('-');\n const [showAddBearerKeyForm, setShowAddBearerKeyForm] = useState(false);\n\n const {\n routingConfig,\n tempRoutingConfig,\n setTempRoutingConfig,\n installConfig: savedInstallConfig,\n smartRoutingConfig,\n mcpRouterConfig,\n oauthServerConfig,\n nameSeparator,\n enableSessionRebuild,\n loading,\n bearerKeys,\n updateRoutingConfig,\n updateInstallConfig,\n updateSmartRoutingConfig,\n updateSmartRoutingConfigBatch,\n updateMCPRouterConfig,\n updateOAuthServerConfig,\n updateNameSeparator,\n updateSessionRebuild,\n exportMCPSettings,\n createBearerKey,\n updateBearerKey,\n deleteBearerKey,\n refreshBearerKeys,\n } = useSettingsData();\n\n // Update local installConfig when savedInstallConfig changes\n useEffect(() => {\n if (savedInstallConfig) {\n setInstallConfig(savedInstallConfig);\n }\n }, [savedInstallConfig]);\n\n // Update local tempSmartRoutingConfig when smartRoutingConfig changes\n useEffect(() => {\n if (smartRoutingConfig) {\n setTempSmartRoutingConfig({\n dbUrl: smartRoutingConfig.dbUrl || '',\n basePacingDelayMs:\n smartRoutingConfig.basePacingDelayMs != null\n ? String(smartRoutingConfig.basePacingDelayMs)\n : '',\n embeddingProvider:\n smartRoutingConfig.embeddingProvider === 'azure_openai' ? 'azure_openai' : 'openai',\n embeddingEncodingFormat:\n smartRoutingConfig.embeddingEncodingFormat === 'base64'\n ? 'base64'\n : smartRoutingConfig.embeddingEncodingFormat === 'float'\n ? 'float'\n : 'auto',\n openaiApiBaseUrl: smartRoutingConfig.openaiApiBaseUrl || '',\n openaiApiKey: smartRoutingConfig.openaiApiKey || '',\n openaiApiEmbeddingModel: smartRoutingConfig.openaiApiEmbeddingModel || '',\n azureOpenaiEndpoint: smartRoutingConfig.azureOpenaiEndpoint || '',\n azureOpenaiApiKey: smartRoutingConfig.azureOpenaiApiKey || '',\n azureOpenaiApiVersion: smartRoutingConfig.azureOpenaiApiVersion || '2024-02-15-preview',\n azureOpenaiEmbeddingDeployment: smartRoutingConfig.azureOpenaiEmbeddingDeployment || '',\n azureOpenaiEmbeddingModel: smartRoutingConfig.azureOpenaiEmbeddingModel || '',\n embeddingMaxTokens:\n smartRoutingConfig.embeddingMaxTokens != null\n ? String(smartRoutingConfig.embeddingMaxTokens)\n : '',\n });\n }\n }, [smartRoutingConfig]);\n\n // Update local tempMCPRouterConfig when mcpRouterConfig changes\n useEffect(() => {\n if (mcpRouterConfig) {\n setTempMCPRouterConfig({\n apiKey: mcpRouterConfig.apiKey || '',\n referer: mcpRouterConfig.referer || 'https://www.mcphub.app',\n title: mcpRouterConfig.title || 'MCPHub',\n baseUrl: mcpRouterConfig.baseUrl || 'https://api.mcprouter.to/v1',\n });\n }\n }, [mcpRouterConfig]);\n\n useEffect(() => {\n if (oauthServerConfig) {\n setTempOAuthServerConfig({\n accessTokenLifetime:\n oauthServerConfig.accessTokenLifetime !== undefined\n ? String(oauthServerConfig.accessTokenLifetime)\n : '',\n refreshTokenLifetime:\n oauthServerConfig.refreshTokenLifetime !== undefined\n ? String(oauthServerConfig.refreshTokenLifetime)\n : '',\n authorizationCodeLifetime:\n oauthServerConfig.authorizationCodeLifetime !== undefined\n ? String(oauthServerConfig.authorizationCodeLifetime)\n : '',\n allowedScopes:\n oauthServerConfig.allowedScopes && oauthServerConfig.allowedScopes.length > 0\n ? oauthServerConfig.allowedScopes.join(', ')\n : '',\n dynamicRegistrationAllowedGrantTypes: oauthServerConfig.dynamicRegistration\n ?.allowedGrantTypes?.length\n ? oauthServerConfig.dynamicRegistration.allowedGrantTypes.join(', ')\n : '',\n });\n }\n }, [oauthServerConfig]);\n\n // Update local tempNameSeparator when nameSeparator changes\n useEffect(() => {\n setTempNameSeparator(nameSeparator);\n }, [nameSeparator]);\n\n // Refresh bearer keys when component mounts\n useEffect(() => {\n refreshBearerKeys();\n }, []);\n\n const [sectionsVisible, setSectionsVisible] = useState({\n routingConfig: false,\n installConfig: false,\n smartRoutingConfig: false,\n oauthServerConfig: false,\n mcpRouterConfig: false,\n nameSeparator: false,\n password: false,\n exportConfig: false,\n bearerKeys: false,\n });\n\n const toggleSection = (\n section:\n | 'routingConfig'\n | 'installConfig'\n | 'smartRoutingConfig'\n | 'oauthServerConfig'\n | 'mcpRouterConfig'\n | 'nameSeparator'\n | 'password'\n | 'exportConfig'\n | 'bearerKeys',\n ) => {\n setSectionsVisible((prev) => ({\n ...prev,\n [section]: !prev[section],\n }));\n };\n\n const handleRoutingConfigChange = async (\n key:\n | 'enableGlobalRoute'\n | 'enableGroupNameRoute'\n | 'enableBearerAuth'\n | 'bearerAuthKey'\n | 'bearerAuthHeaderName'\n | 'jsonBodyLimit'\n | 'skipAuth',\n value: boolean | string,\n ) => {\n await updateRoutingConfig(key, value);\n };\n\n const handleTempRoutingConfigChange = (\n key: 'bearerAuthHeaderName' | 'jsonBodyLimit',\n value: string,\n ) => {\n setTempRoutingConfig((prev) => ({\n ...prev,\n [key]: value,\n }));\n };\n\n const handleInstallConfigChange = (\n key: 'pythonIndexUrl' | 'npmRegistry' | 'baseUrl',\n value: string,\n ) => {\n setInstallConfig({\n ...installConfig,\n [key]: value,\n });\n };\n\n const saveInstallConfig = async (key: 'pythonIndexUrl' | 'npmRegistry' | 'baseUrl') => {\n await updateInstallConfig(key, installConfig[key]);\n };\n\n const handleSmartRoutingConfigChange = (\n key:\n | 'dbUrl'\n | 'basePacingDelayMs'\n | 'embeddingProvider'\n | 'embeddingEncodingFormat'\n | 'openaiApiBaseUrl'\n | 'openaiApiKey'\n | 'openaiApiEmbeddingModel'\n | 'azureOpenaiEndpoint'\n | 'azureOpenaiApiKey'\n | 'azureOpenaiApiVersion'\n | 'azureOpenaiEmbeddingDeployment'\n | 'azureOpenaiEmbeddingModel'\n | 'embeddingMaxTokens',\n value: string,\n ) => {\n setTempSmartRoutingConfig({\n ...tempSmartRoutingConfig,\n [key]: value,\n });\n };\n\n const handleMCPRouterConfigChange = (\n key: 'apiKey' | 'referer' | 'title' | 'baseUrl',\n value: string,\n ) => {\n setTempMCPRouterConfig({\n ...tempMCPRouterConfig,\n [key]: value,\n });\n };\n\n const saveMCPRouterConfig = async (key: 'apiKey' | 'referer' | 'title' | 'baseUrl') => {\n await updateMCPRouterConfig(key, tempMCPRouterConfig[key]);\n };\n\n type OAuthServerNumberField =\n | 'accessTokenLifetime'\n | 'refreshTokenLifetime'\n | 'authorizationCodeLifetime';\n\n const handleOAuthServerNumberChange = (key: OAuthServerNumberField, value: string) => {\n setTempOAuthServerConfig((prev) => ({\n ...prev,\n [key]: value,\n }));\n };\n\n const handleOAuthServerTextChange = (\n key: 'allowedScopes' | 'dynamicRegistrationAllowedGrantTypes',\n value: string,\n ) => {\n setTempOAuthServerConfig((prev) => ({\n ...prev,\n [key]: value,\n }));\n };\n\n const saveOAuthServerNumberConfig = async (key: OAuthServerNumberField) => {\n const rawValue = tempOAuthServerConfig[key];\n if (!rawValue || rawValue.trim() === '') {\n showToast(t('settings.invalidNumberInput') || 'Please enter a valid number', 'error');\n return;\n }\n\n const parsedValue = Number(rawValue);\n if (Number.isNaN(parsedValue) || parsedValue < 0) {\n showToast(t('settings.invalidNumberInput') || 'Please enter a valid number', 'error');\n return;\n }\n\n await updateOAuthServerConfig(key, parsedValue);\n };\n\n const saveOAuthServerAllowedScopes = async () => {\n const scopes = tempOAuthServerConfig.allowedScopes\n .split(',')\n .map((scope) => scope.trim())\n .filter((scope) => scope.length > 0);\n\n await updateOAuthServerConfig('allowedScopes', scopes);\n };\n\n const saveOAuthServerGrantTypes = async () => {\n const grantTypes = tempOAuthServerConfig.dynamicRegistrationAllowedGrantTypes\n .split(',')\n .map((grant) => grant.trim())\n .filter((grant) => grant.length > 0);\n\n await updateOAuthServerConfig('dynamicRegistration', {\n ...oauthServerConfig.dynamicRegistration,\n allowedGrantTypes: grantTypes,\n });\n };\n\n const handleOAuthServerToggle = async (\n key: 'enabled' | 'requireClientSecret' | 'requireState',\n value: boolean,\n ) => {\n await updateOAuthServerConfig(key, value);\n };\n\n const handleDynamicRegistrationToggle = async (\n updates: Partial<typeof oauthServerConfig.dynamicRegistration>,\n ) => {\n await updateOAuthServerConfig('dynamicRegistration', {\n ...oauthServerConfig.dynamicRegistration,\n ...updates,\n });\n };\n\n const saveNameSeparator = async () => {\n await updateNameSeparator(tempNameSeparator);\n };\n\n const handleSmartRoutingEnabledChange = async (value: boolean) => {\n // If enabling Smart Routing, validate required fields and save any unsaved changes\n if (value) {\n const currentDbUrl = tempSmartRoutingConfig.dbUrl || smartRoutingConfig.dbUrl;\n const missingFields: string[] = [];\n if (!currentDbUrl) missingFields.push(t('settings.dbUrl') || 'Database URL');\n\n if (tempSmartRoutingConfig.embeddingProvider === 'azure_openai') {\n const currentEndpoint =\n tempSmartRoutingConfig.azureOpenaiEndpoint || smartRoutingConfig.azureOpenaiEndpoint;\n const currentKey =\n tempSmartRoutingConfig.azureOpenaiApiKey || smartRoutingConfig.azureOpenaiApiKey;\n const currentApiVersion =\n tempSmartRoutingConfig.azureOpenaiApiVersion || smartRoutingConfig.azureOpenaiApiVersion;\n const currentDeployment =\n tempSmartRoutingConfig.azureOpenaiEmbeddingDeployment ||\n smartRoutingConfig.azureOpenaiEmbeddingDeployment;\n\n if (!currentEndpoint || !currentKey || !currentApiVersion || !currentDeployment) {\n missingFields.push(\n t('settings.azureOpenaiEndpoint') || 'Azure OpenAI Endpoint',\n t('settings.azureOpenaiApiKey') || 'Azure OpenAI API Key',\n t('settings.azureOpenaiApiVersion') || 'Azure OpenAI API Version',\n t('settings.azureOpenaiEmbeddingDeployment') || 'Azure Embedding Deployment',\n );\n }\n } else {\n // Get current OpenAI config values with explicit type checking and trim\n const currentOpenaiApiKey = (typeof tempSmartRoutingConfig.openaiApiKey === 'string'\n ? tempSmartRoutingConfig.openaiApiKey\n : smartRoutingConfig.openaiApiKey || ''\n ).trim();\n const currentOpenaiApiBaseUrl = (typeof tempSmartRoutingConfig.openaiApiBaseUrl === 'string'\n ? tempSmartRoutingConfig.openaiApiBaseUrl\n : smartRoutingConfig.openaiApiBaseUrl || ''\n ).trim();\n const currentOpenaiApiEmbeddingModel = (typeof tempSmartRoutingConfig.openaiApiEmbeddingModel === 'string'\n ? tempSmartRoutingConfig.openaiApiEmbeddingModel\n : smartRoutingConfig.openaiApiEmbeddingModel || ''\n ).trim();\n\n if (!currentOpenaiApiKey) {\n missingFields.push(t('settings.openaiApiKey') || 'OpenAI API Key');\n }\n if (!currentOpenaiApiBaseUrl) {\n missingFields.push(t('settings.openaiApiBaseUrl') || 'OpenAI API Base URL');\n }\n if (!currentOpenaiApiEmbeddingModel) {\n missingFields.push(t('settings.openaiApiEmbeddingModel') || 'OpenAI Embedding Model');\n }\n }\n\n if (missingFields.length > 0) {\n showToast(\n t('settings.smartRoutingValidationError', {\n fields: missingFields.join(', '),\n }),\n );\n return;\n }\n\n // Prepare updates object with unsaved changes and enabled status\n const updates: any = { enabled: value };\n\n // Check for unsaved changes and include them in the batch update\n if (tempSmartRoutingConfig.dbUrl !== smartRoutingConfig.dbUrl) {\n updates.dbUrl = tempSmartRoutingConfig.dbUrl;\n }\n const parsedBasePacingDelay = parseBasePacingDelayForUpdate(\n tempSmartRoutingConfig.basePacingDelayMs,\n smartRoutingConfig.basePacingDelayMs,\n );\n if (parsedBasePacingDelay !== undefined) {\n updates.basePacingDelayMs = parsedBasePacingDelay;\n }\n if (tempSmartRoutingConfig.embeddingProvider !== smartRoutingConfig.embeddingProvider) {\n updates.embeddingProvider = tempSmartRoutingConfig.embeddingProvider;\n }\n if (\n tempSmartRoutingConfig.embeddingEncodingFormat !==\n smartRoutingConfig.embeddingEncodingFormat\n ) {\n updates.embeddingEncodingFormat = tempSmartRoutingConfig.embeddingEncodingFormat;\n }\n if (tempSmartRoutingConfig.openaiApiBaseUrl !== smartRoutingConfig.openaiApiBaseUrl) {\n updates.openaiApiBaseUrl = tempSmartRoutingConfig.openaiApiBaseUrl;\n }\n if (tempSmartRoutingConfig.openaiApiKey !== smartRoutingConfig.openaiApiKey) {\n updates.openaiApiKey = tempSmartRoutingConfig.openaiApiKey;\n }\n if (\n tempSmartRoutingConfig.openaiApiEmbeddingModel !==\n smartRoutingConfig.openaiApiEmbeddingModel\n ) {\n updates.openaiApiEmbeddingModel = tempSmartRoutingConfig.openaiApiEmbeddingModel;\n }\n\n if (tempSmartRoutingConfig.azureOpenaiEndpoint !== smartRoutingConfig.azureOpenaiEndpoint) {\n updates.azureOpenaiEndpoint = tempSmartRoutingConfig.azureOpenaiEndpoint;\n }\n if (tempSmartRoutingConfig.azureOpenaiApiKey !== smartRoutingConfig.azureOpenaiApiKey) {\n updates.azureOpenaiApiKey = tempSmartRoutingConfig.azureOpenaiApiKey;\n }\n if (\n tempSmartRoutingConfig.azureOpenaiApiVersion !== smartRoutingConfig.azureOpenaiApiVersion\n ) {\n updates.azureOpenaiApiVersion = tempSmartRoutingConfig.azureOpenaiApiVersion;\n }\n if (\n tempSmartRoutingConfig.azureOpenaiEmbeddingDeployment !==\n smartRoutingConfig.azureOpenaiEmbeddingDeployment\n ) {\n updates.azureOpenaiEmbeddingDeployment =\n tempSmartRoutingConfig.azureOpenaiEmbeddingDeployment;\n }\n if (\n tempSmartRoutingConfig.azureOpenaiEmbeddingModel !==\n smartRoutingConfig.azureOpenaiEmbeddingModel\n ) {\n updates.azureOpenaiEmbeddingModel = tempSmartRoutingConfig.azureOpenaiEmbeddingModel;\n }\n\n // embeddingMaxTokens: empty string → null (clear override), numeric string → number\n const parsedTokens = parseEmbeddingMaxTokensForUpdate(\n tempSmartRoutingConfig.embeddingMaxTokens,\n smartRoutingConfig.embeddingMaxTokens,\n );\n if (parsedTokens !== undefined) {\n updates.embeddingMaxTokens = parsedTokens;\n }\n\n // Save all changes in a single batch update\n await updateSmartRoutingConfigBatch(updates);\n } else {\n // If disabling, just update the enabled status\n await updateSmartRoutingConfig('enabled', value);\n }\n };\n\n const handleSaveSmartRoutingConfig = async () => {\n const updates: any = {};\n\n if (tempSmartRoutingConfig.dbUrl !== smartRoutingConfig.dbUrl) {\n updates.dbUrl = tempSmartRoutingConfig.dbUrl;\n }\n const parsedBasePacingDelay = parseBasePacingDelayForUpdate(\n tempSmartRoutingConfig.basePacingDelayMs,\n smartRoutingConfig.basePacingDelayMs,\n );\n if (parsedBasePacingDelay !== undefined) {\n updates.basePacingDelayMs = parsedBasePacingDelay;\n }\n if (tempSmartRoutingConfig.embeddingProvider !== smartRoutingConfig.embeddingProvider) {\n updates.embeddingProvider = tempSmartRoutingConfig.embeddingProvider;\n }\n if (\n tempSmartRoutingConfig.embeddingEncodingFormat !== smartRoutingConfig.embeddingEncodingFormat\n ) {\n updates.embeddingEncodingFormat = tempSmartRoutingConfig.embeddingEncodingFormat;\n }\n if (tempSmartRoutingConfig.openaiApiBaseUrl !== smartRoutingConfig.openaiApiBaseUrl) {\n updates.openaiApiBaseUrl = tempSmartRoutingConfig.openaiApiBaseUrl;\n }\n if (tempSmartRoutingConfig.openaiApiKey !== smartRoutingConfig.openaiApiKey) {\n updates.openaiApiKey = tempSmartRoutingConfig.openaiApiKey;\n }\n if (\n tempSmartRoutingConfig.openaiApiEmbeddingModel !== smartRoutingConfig.openaiApiEmbeddingModel\n ) {\n updates.openaiApiEmbeddingModel = tempSmartRoutingConfig.openaiApiEmbeddingModel;\n }\n\n if (tempSmartRoutingConfig.azureOpenaiEndpoint !== smartRoutingConfig.azureOpenaiEndpoint) {\n updates.azureOpenaiEndpoint = tempSmartRoutingConfig.azureOpenaiEndpoint;\n }\n if (tempSmartRoutingConfig.azureOpenaiApiKey !== smartRoutingConfig.azureOpenaiApiKey) {\n updates.azureOpenaiApiKey = tempSmartRoutingConfig.azureOpenaiApiKey;\n }\n if (tempSmartRoutingConfig.azureOpenaiApiVersion !== smartRoutingConfig.azureOpenaiApiVersion) {\n updates.azureOpenaiApiVersion = tempSmartRoutingConfig.azureOpenaiApiVersion;\n }\n if (\n tempSmartRoutingConfig.azureOpenaiEmbeddingDeployment !==\n smartRoutingConfig.azureOpenaiEmbeddingDeployment\n ) {\n updates.azureOpenaiEmbeddingDeployment =\n tempSmartRoutingConfig.azureOpenaiEmbeddingDeployment;\n }\n if (\n tempSmartRoutingConfig.azureOpenaiEmbeddingModel !==\n smartRoutingConfig.azureOpenaiEmbeddingModel\n ) {\n updates.azureOpenaiEmbeddingModel = tempSmartRoutingConfig.azureOpenaiEmbeddingModel;\n }\n\n // embeddingMaxTokens: empty string → null (clear override), numeric string → number\n const parsedEmbeddingMaxTokens = parseEmbeddingMaxTokensForUpdate(\n tempSmartRoutingConfig.embeddingMaxTokens,\n smartRoutingConfig.embeddingMaxTokens,\n );\n if (parsedEmbeddingMaxTokens !== undefined) {\n updates.embeddingMaxTokens = parsedEmbeddingMaxTokens;\n }\n\n if (Object.keys(updates).length > 0) {\n await updateSmartRoutingConfigBatch(updates);\n } else {\n showToast(t('settings.noChanges') || 'No changes to save', 'info');\n }\n };\n\n const handlePasswordChangeSuccess = () => {\n setTimeout(() => {\n navigate('/');\n }, 2000);\n };\n\n const [copiedConfig, setCopiedConfig] = useState(false);\n const [mcpSettingsJson, setMcpSettingsJson] = useState<string>('');\n\n const [newBearerKey, setNewBearerKey] = useState<{\n name: string;\n token: string;\n enabled: boolean;\n accessType: 'all' | 'groups' | 'servers' | 'custom';\n allowedGroups: string;\n allowedServers: string;\n }>({\n name: '',\n token: '',\n enabled: true,\n accessType: 'all',\n allowedGroups: '',\n allowedServers: '',\n });\n\n const [newSelectedGroups, setNewSelectedGroups] = useState<string[]>([]);\n const [newSelectedServers, setNewSelectedServers] = useState<string[]>([]);\n\n // Prepare options for MultiSelect\n const availableServers = servers.map((server) => ({\n value: server.name,\n label: server.name,\n }));\n\n const availableGroups = groups.map((group) => ({\n value: group.name,\n label: group.name,\n }));\n\n // Reset selected arrays when accessType changes\n useEffect(() => {\n if (newBearerKey.accessType !== 'groups' && newBearerKey.accessType !== 'custom') {\n setNewSelectedGroups([]);\n }\n if (newBearerKey.accessType !== 'servers' && newBearerKey.accessType !== 'custom') {\n setNewSelectedServers([]);\n }\n }, [newBearerKey.accessType]);\n\n const fetchMcpSettings = async () => {\n try {\n const result = await exportMCPSettings();\n console.log('Fetched MCP settings:', result);\n const configJson = JSON.stringify(result.data, null, 2);\n setMcpSettingsJson(configJson);\n } catch (error) {\n console.error('Error fetching MCP settings:', error);\n showToast(t('settings.exportError') || 'Failed to fetch settings', 'error');\n }\n };\n\n useEffect(() => {\n if (sectionsVisible.exportConfig && !mcpSettingsJson) {\n fetchMcpSettings();\n }\n }, [sectionsVisible.exportConfig]);\n\n const handleCopyConfig = async () => {\n if (!mcpSettingsJson) return;\n\n try {\n if (navigator.clipboard && window.isSecureContext) {\n await navigator.clipboard.writeText(mcpSettingsJson);\n setCopiedConfig(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopiedConfig(false), 2000);\n } else {\n // Fallback for HTTP or unsupported clipboard API\n const textArea = document.createElement('textarea');\n textArea.value = mcpSettingsJson;\n textArea.style.position = 'fixed';\n textArea.style.left = '-9999px';\n document.body.appendChild(textArea);\n textArea.focus();\n textArea.select();\n try {\n document.execCommand('copy');\n setCopiedConfig(true);\n showToast(t('common.copySuccess') || 'Copied to clipboard', 'success');\n setTimeout(() => setCopiedConfig(false), 2000);\n } catch (err) {\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n console.error('Copy to clipboard failed:', err);\n }\n document.body.removeChild(textArea);\n }\n } catch (error) {\n console.error('Error copying configuration:', error);\n showToast(t('common.copyFailed') || 'Copy failed', 'error');\n }\n };\n\n const handleDownloadConfig = () => {\n if (!mcpSettingsJson) return;\n\n const blob = new Blob([mcpSettingsJson], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = 'mcp_settings.json';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n showToast(t('settings.exportSuccess') || 'Settings exported successfully', 'success');\n };\n\n const parseCommaSeparated = (value: string): string[] | undefined => {\n const parts = value\n .split(',')\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n return parts.length > 0 ? parts : undefined;\n };\n\n const handleCreateBearerKey = async () => {\n if (!newBearerKey.name || !newBearerKey.token) {\n showToast(t('settings.bearerKeyRequired') || 'Name and token are required', 'error');\n return;\n }\n\n if (newBearerKey.accessType === 'groups' && newSelectedGroups.length === 0) {\n showToast(t('settings.selectAtLeastOneGroup') || 'Please select at least one group', 'error');\n return;\n }\n if (newBearerKey.accessType === 'servers' && newSelectedServers.length === 0) {\n showToast(\n t('settings.selectAtLeastOneServer') || 'Please select at least one server',\n 'error',\n );\n return;\n }\n if (\n newBearerKey.accessType === 'custom' &&\n newSelectedGroups.length === 0 &&\n newSelectedServers.length === 0\n ) {\n showToast(\n t('settings.selectAtLeastOneGroupOrServer') || 'Please select at least one group or server',\n 'error',\n );\n return;\n }\n\n await createBearerKey({\n name: newBearerKey.name,\n token: newBearerKey.token,\n enabled: newBearerKey.enabled,\n accessType: newBearerKey.accessType,\n allowedGroups:\n (newBearerKey.accessType === 'groups' || newBearerKey.accessType === 'custom') &&\n newSelectedGroups.length > 0\n ? newSelectedGroups\n : undefined,\n allowedServers:\n (newBearerKey.accessType === 'servers' || newBearerKey.accessType === 'custom') &&\n newSelectedServers.length > 0\n ? newSelectedServers\n : undefined,\n } as any);\n\n setNewBearerKey({\n name: '',\n token: '',\n enabled: true,\n accessType: 'all',\n allowedGroups: '',\n allowedServers: '',\n });\n setNewSelectedGroups([]);\n setNewSelectedServers([]);\n await refreshBearerKeys();\n };\n\n const handleSaveExistingBearerKey = async (\n id: string,\n payload: {\n name: string;\n token: string;\n enabled: boolean;\n accessType: 'all' | 'groups' | 'servers' | 'custom';\n allowedGroups: string;\n allowedServers: string;\n },\n ) => {\n await updateBearerKey(id, {\n name: payload.name,\n token: payload.token,\n enabled: payload.enabled,\n accessType: payload.accessType,\n allowedGroups: parseCommaSeparated(payload.allowedGroups),\n allowedServers: parseCommaSeparated(payload.allowedServers),\n } as any);\n await refreshBearerKeys();\n };\n\n const handleDeleteExistingBearerKey = async (id: string) => {\n await deleteBearerKey(id);\n await refreshBearerKeys();\n };\n\n return (\n <div>\n <div className=\"mb-6\">\n <h1 className=\"hub-h1\">{t('pages.settings.title')}</h1>\n <p className=\"hub-sub\">{t('settings.subtitle') || ''}</p>\n </div>\n\n {/* Bearer Keys Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_ROUTE_CONFIG}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('bearerKeys')}\n >\n <div className=\"flex items-center gap-2.5\">\n <Key size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">\n {t('settings.bearerKeysSectionTitle') || 'Bearer authentication keys'}\n </h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">\n {sectionsVisible.bearerKeys ? '−' : '+'}\n </span>\n </div>\n\n {sectionsVisible.bearerKeys && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.enableBearerAuth') || 'Enable Bearer Authentication'}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.enableBearerAuthDescription') ||\n 'Require bearer token authentication for MCP requests'}\n </p>\n </div>\n <Switch\n disabled={loading}\n checked={routingConfig.enableBearerAuth}\n onCheckedChange={(checked) =>\n handleRoutingConfigChange('enableBearerAuth', checked)\n }\n />\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.bearerAuthHeaderName')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.bearerAuthHeaderNameDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempRoutingConfig.bearerAuthHeaderName}\n onChange={(e) =>\n handleTempRoutingConfigChange('bearerAuthHeaderName', e.target.value)\n }\n placeholder={t('settings.bearerAuthHeaderNamePlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() =>\n handleRoutingConfigChange(\n 'bearerAuthHeaderName',\n tempRoutingConfig.bearerAuthHeaderName,\n )\n }\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"flex justify-between items-center\">\n <p className=\"text-sm text-gray-600\">\n {t('settings.bearerKeysSectionDescription') ||\n 'Manage multiple bearer authentication keys with different access scopes.'}\n </p>\n {!showAddBearerKeyForm && (\n <button\n type=\"button\"\n onClick={() => setShowAddBearerKeyForm(true)}\n className=\"flex items-center text-blue-600 hover:text-blue-800 font-medium transition-colors duration-200\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5 mr-1\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {t('settings.addBearerKey') || 'Add bearer key'}\n </button>\n )}\n </div>\n\n {/* Existing keys */}\n {bearerKeys.length === 0 ? (\n <p className=\"text-sm text-gray-500\">\n {t('settings.noBearerKeys') || 'No bearer keys configured yet.'}\n </p>\n ) : (\n <div className=\"mt-2 overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 dark:divide-gray-700 border border-gray-200 dark:border-gray-700 rounded-lg\">\n <thead className=\"bg-gray-50 dark:bg-gray-800\">\n <tr>\n <th\n scope=\"col\"\n className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"\n >\n {t('settings.bearerKeyName') || 'Name'}\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"\n >\n {t('settings.bearerKeyToken') || 'Token'}\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"\n >\n {t('settings.bearerKeyEnabled') || 'Status'}\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\"\n >\n {t('settings.bearerKeyAccessType') || 'Access Scope'}\n </th>\n <th\n scope=\"col\"\n className=\"px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider\"\n >\n {t('common.actions') || 'Actions'}\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700\">\n {bearerKeys.map((key) => (\n <BearerKeyRow\n key={key.id}\n keyData={key}\n loading={loading}\n availableServers={availableServers}\n availableGroups={availableGroups}\n onSave={handleSaveExistingBearerKey}\n onDelete={handleDeleteExistingBearerKey}\n />\n ))}\n </tbody>\n </table>\n </div>\n )}\n\n {/* New key form */}\n {showAddBearerKeyForm && (\n <div className=\"mt-6 border-t border-gray-200 dark:border-gray-700 pt-6\">\n <div className=\"bg-gray-50 dark:bg-gray-800 rounded-lg p-5 border border-gray-200 dark:border-gray-700\">\n <h3 className=\"font-medium text-gray-900 mb-4 flex items-center gap-2\">\n <span className=\"bg-blue-100 text-blue-600 p-1 rounded\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </span>\n {t('settings.addBearerKey') || 'Add bearer key'}\n </h3>\n\n <div className=\"grid grid-cols-1 md:grid-cols-12 gap-4 mb-4\">\n <div className=\"md:col-span-3\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyName') || 'Name'}\n </label>\n <input\n type=\"text\"\n className=\"block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input transition-shadow duration-200\"\n placeholder=\"e.g. My API Key\"\n value={newBearerKey.name}\n onChange={(e) =>\n setNewBearerKey((prev) => ({ ...prev, name: e.target.value }))\n }\n disabled={loading}\n />\n </div>\n <div className=\"md:col-span-9\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyToken') || 'Token'}\n </label>\n <div className=\"flex rounded-md shadow-sm\">\n <input\n type=\"text\"\n className=\"flex-1 block w-full py-2 px-3 border border-gray-300 rounded-l-md rounded-r-none border-r-0 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input transition-shadow duration-200\"\n placeholder=\"sk-...\"\n value={newBearerKey.token}\n onChange={(e) =>\n setNewBearerKey((prev) => ({ ...prev, token: e.target.value }))\n }\n disabled={loading}\n />\n <button\n type=\"button\"\n onClick={() =>\n setNewBearerKey((prev) => ({ ...prev, token: generateRandomKey() }))\n }\n disabled={loading}\n className=\"relative -ml-[5px] inline-flex items-center px-4 py-2 border border-gray-300 bg-gray-100 dark:bg-gray-800 text-gray-700 text-sm font-medium rounded-r-md rounded-l-none hover:bg-gray-200 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 transition-colors duration-200 z-10\"\n >\n {t('settings.generate') || 'Generate'}\n </button>\n </div>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-end gap-4 mb-2\">\n <div className=\"w-40\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyEnabled') || 'Status'}\n </label>\n <div className=\"flex items-center h-[38px] px-3 bg-white dark:bg-gray-800 border border-gray-300 rounded-md\">\n <span\n className={`text-sm mr-3 ${newBearerKey.enabled ? 'text-green-600 font-medium' : 'text-gray-500'}`}\n >\n {newBearerKey.enabled ? 'Active' : 'Inactive'}\n </span>\n <Switch\n disabled={loading}\n checked={newBearerKey.enabled}\n onCheckedChange={(checked) =>\n setNewBearerKey((prev) => ({ ...prev, enabled: checked }))\n }\n />\n </div>\n </div>\n\n <div className=\"w-48\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyAccessType') || 'Access scope'}\n </label>\n <select\n className=\"block w-full py-2 px-3 border border-gray-300 bg-white dark:bg-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-select transition-shadow duration-200\"\n value={newBearerKey.accessType}\n onChange={(e) =>\n setNewBearerKey((prev) => ({\n ...prev,\n accessType: e.target.value as 'all' | 'groups' | 'servers' | 'custom',\n }))\n }\n disabled={loading}\n >\n <option value=\"all\">\n {t('settings.bearerKeyAccessAll') || 'All Resources'}\n </option>\n <option value=\"groups\">\n {t('settings.bearerKeyAccessGroups') || 'Specific Groups'}\n </option>\n <option value=\"servers\">\n {t('settings.bearerKeyAccessServers') || 'Specific Servers'}\n </option>\n <option value=\"custom\">\n {t('settings.bearerKeyAccessCustom') || 'Custom (Groups & Servers)'}\n </option>\n </select>\n </div>\n\n {newBearerKey.accessType !== 'custom' && (\n <div className=\"flex-1 min-w-[200px]\">\n <label\n className={`block text-sm font-medium mb-1 ${newBearerKey.accessType === 'all' ? 'text-gray-400' : 'text-gray-700'}`}\n >\n {newBearerKey.accessType === 'groups'\n ? t('settings.bearerKeyAllowedGroups') || 'Allowed groups'\n : t('settings.bearerKeyAllowedServers') || 'Allowed servers'}\n </label>\n <MultiSelect\n options={\n newBearerKey.accessType === 'groups'\n ? availableGroups\n : availableServers\n }\n selected={\n newBearerKey.accessType === 'groups'\n ? newSelectedGroups\n : newSelectedServers\n }\n onChange={\n newBearerKey.accessType === 'groups'\n ? setNewSelectedGroups\n : setNewSelectedServers\n }\n placeholder={\n newBearerKey.accessType === 'groups'\n ? t('settings.selectGroups') || 'Select groups...'\n : t('settings.selectServers') || 'Select servers...'\n }\n disabled={loading || newBearerKey.accessType === 'all'}\n />\n </div>\n )}\n\n {newBearerKey.accessType === 'custom' && (\n <>\n <div className=\"flex-1 min-w-[200px]\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyAllowedGroups') || 'Allowed groups'}\n </label>\n <MultiSelect\n options={availableGroups}\n selected={newSelectedGroups}\n onChange={setNewSelectedGroups}\n placeholder={t('settings.selectGroups') || 'Select groups...'}\n disabled={loading}\n />\n </div>\n <div className=\"flex-1 min-w-[200px]\">\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">\n {t('settings.bearerKeyAllowedServers') || 'Allowed servers'}\n </label>\n <MultiSelect\n options={availableServers}\n selected={newSelectedServers}\n onChange={setNewSelectedServers}\n placeholder={t('settings.selectServers') || 'Select servers...'}\n disabled={loading}\n />\n </div>\n </>\n )}\n\n <div className=\"flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => setShowAddBearerKeyForm(false)}\n className=\"px-4 py-2 bg-white dark:bg-gray-800 border border-gray-300 text-gray-700 rounded-md text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 h-[38px]\"\n >\n {t('common.cancel') || 'Cancel'}\n </button>\n <button\n type=\"button\"\n onClick={handleCreateBearerKey}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('settings.addBearerKeyButton') || 'Create Key'}\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* Smart Routing Configuration Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_SMART_ROUTING}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] px-6 py-3\"\n onClick={() => toggleSection('smartRoutingConfig')}\n >\n <div className=\"flex items-center gap-2.5\">\n <RouteIcon size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('pages.settings.smartRouting')}</h2>\n <span className=\"hub-status ml-2\" data-state={smartRoutingConfig.enabled ? 'on' : 'off'}>\n <span\n className=\"hub-dot\"\n style={{\n background: smartRoutingConfig.enabled ? 'var(--hub-ok)' : 'var(--hub-ink-3)',\n boxShadow: smartRoutingConfig.enabled\n ? '0 0 0 3px oklch(0.66 0.15 145 / 0.15)'\n : 'none',\n }}\n />\n <span\n style={{\n color: smartRoutingConfig.enabled ? 'oklch(0.4 0.13 145)' : 'var(--hub-ink-3)',\n fontSize: 12,\n }}\n >\n {smartRoutingConfig.enabled ? t('common.active') : t('common.inactive')}\n </span>\n </span>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">\n {sectionsVisible.smartRoutingConfig ? '−' : '+'}\n </span>\n </div>\n\n {sectionsVisible.smartRoutingConfig && (\n <div className=\"px-6 py-5 border-t border-[var(--hub-line-2)]\">\n {/* Status banner */}\n <div\n className=\"hub-card mb-4\"\n style={{ padding: 16, background: 'var(--hub-bg-2)' }}\n >\n <div\n className=\"grid items-center gap-4\"\n style={{ gridTemplateColumns: '1.1fr 1px 1.4fr 1px auto' }}\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"relative\" style={{ width: 40, height: 40 }}>\n <div\n className=\"absolute inset-0 rounded-md grid place-items-center\"\n style={{\n background: smartRoutingConfig.enabled\n ? 'oklch(0.95 0.05 145)'\n : 'var(--hub-bg-2)',\n border: '1px solid var(--hub-line)',\n }}\n >\n <RouteIcon\n size={18}\n style={{\n color: smartRoutingConfig.enabled\n ? 'oklch(0.4 0.13 145)'\n : 'var(--hub-ink-3)',\n }}\n />\n </div>\n {smartRoutingConfig.enabled && (\n <span\n className=\"absolute\"\n style={{\n top: -2,\n right: -2,\n width: 10,\n height: 10,\n borderRadius: 50,\n background: 'var(--hub-ok)',\n boxShadow: '0 0 0 2px var(--hub-surface)',\n }}\n />\n )}\n </div>\n <div>\n <div style={{ fontSize: 13.5, fontWeight: 500 }}>\n {smartRoutingConfig.enabled\n ? t('common.active')\n : t('common.inactive')}\n </div>\n <div style={{ fontSize: 11.5, color: 'var(--hub-ink-3)' }}>\n {t('settings.enableSmartRoutingDescription')}\n </div>\n </div>\n </div>\n <div style={{ background: 'var(--hub-line)', height: 36 }} />\n <div>\n <div className=\"hub-sect\" style={{ marginBottom: 5 }}>\n smart endpoint\n </div>\n <EndpointCopy\n label=\"SMART\"\n url={`${(installConfig.baseUrl || '').replace(/\\/+$/, '')}/mcp/$smart`}\n />\n </div>\n <div style={{ background: 'var(--hub-line)', height: 36 }} />\n <div className=\"flex items-center gap-2\">\n <span style={{ fontSize: 12.5, color: 'var(--hub-ink-2)' }}>\n {t('settings.enableSmartRouting')}\n </span>\n <Switch\n disabled={loading}\n checked={smartRoutingConfig.enabled}\n onCheckedChange={(checked) => handleSmartRoutingEnabledChange(checked)}\n />\n </div>\n </div>\n </div>\n\n {/* Flow diagram */}\n <div className=\"hub-card mb-4\" style={{ padding: 18 }}>\n <h3 className=\"hub-card-title\" style={{ marginBottom: 4 }}>\n {t('settings.smartRoutingWorkflow') || 'Workflow'}\n </h3>\n <p className=\"hub-sub\" style={{ marginTop: 0, marginBottom: 16 }}>\n {t('settings.smartRoutingWorkflowDescription') ||\n 'Prompt is embedded, top-k similar tools are retrieved from pgvector, only relevant tools are exposed.'}\n </p>\n <div\n className=\"grid items-center\"\n style={{ gridTemplateColumns: 'repeat(9, 1fr)' }}\n >\n {[\n { icon: <CodeIcon size={16} />, title: 'Prompt', sub: 'client' },\n null,\n { icon: <Zap size={16} />, title: 'Embedding', sub: 'openai · 1536d' },\n null,\n { icon: <Database size={16} />, title: 'pgvector', sub: 'ann · cosine' },\n null,\n { icon: <Wrench size={16} />, title: 'Top-K', sub: 'score > 0.7' },\n null,\n { icon: <Sparkles size={16} />, title: 'LLM', sub: 'relevant subset' },\n ].map((step, i) =>\n step === null ? (\n <div key={`sep-${i}`} className=\"flex justify-center\">\n <svg width=\"100%\" height=\"20\" preserveAspectRatio=\"none\" viewBox=\"0 0 100 20\">\n <line\n x1=\"4\"\n y1=\"10\"\n x2=\"96\"\n y2=\"10\"\n stroke=\"var(--hub-line)\"\n strokeWidth=\"1\"\n strokeDasharray=\"3 3\"\n />\n <polygon points=\"96,10 88,6 88,14\" fill=\"var(--hub-ink-3)\" />\n </svg>\n </div>\n ) : (\n <div key={i} className=\"flex flex-col items-center gap-2\">\n <div\n className=\"grid place-items-center\"\n style={{\n width: 42,\n height: 42,\n borderRadius: 10,\n border: '1px solid var(--hub-line)',\n background: 'var(--hub-surface)',\n color: 'var(--hub-ink)',\n }}\n >\n {step.icon}\n </div>\n <div className=\"text-center\">\n <div style={{ fontSize: 12, fontWeight: 500 }}>{step.title}</div>\n <div\n className=\"hub-mono\"\n style={{ fontSize: 10.5, color: 'var(--hub-ink-3)' }}\n >\n {step.sub}\n </div>\n </div>\n </div>\n ),\n )}\n </div>\n </div>\n\n {/* Required Fields Information */}\n <div\n className=\"mb-4 flex items-start gap-2\"\n style={{\n padding: '8px 12px',\n borderRadius: 7,\n background: 'var(--hub-accent-soft)',\n color: 'var(--hub-accent)',\n fontSize: 12.5,\n }}\n >\n <span>{t('settings.smartRoutingRequiredFields')}</span>\n </div>\n\n <div className=\"space-y-3 hub-sr-fields\">\n\n {/* hide when DB_URL env is set */}\n {smartRoutingConfig.dbUrl !== '${DB_URL}' && (\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.dbUrl')}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.dbUrl}\n onChange={(e) => handleSmartRoutingConfigChange('dbUrl', e.target.value)}\n placeholder={t('settings.dbUrlPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm border-gray-300 form-input\"\n disabled={loading}\n />\n </div>\n </div>\n )}\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.embeddingProvider') || 'Embedding Provider'}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <select\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 bg-white dark:bg-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-select\"\n value={tempSmartRoutingConfig.embeddingProvider}\n onChange={(e) =>\n handleSmartRoutingConfigChange(\n 'embeddingProvider',\n e.target.value as 'openai' | 'azure_openai',\n )\n }\n disabled={loading}\n >\n <option value=\"openai\">OpenAI (or compatible)</option>\n <option value=\"azure_openai\">Azure OpenAI</option>\n </select>\n </div>\n </div>\n\n {tempSmartRoutingConfig.embeddingProvider === 'openai' ? (\n <>\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.openaiApiKey')}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"password\"\n value={tempSmartRoutingConfig.openaiApiKey}\n onChange={(e) =>\n handleSmartRoutingConfigChange('openaiApiKey', e.target.value)\n }\n placeholder={t('settings.openaiApiKeyPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm border-gray-300\"\n disabled={loading}\n />\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.openaiApiBaseUrl')}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.openaiApiBaseUrl}\n onChange={(e) =>\n handleSmartRoutingConfigChange('openaiApiBaseUrl', e.target.value)\n }\n placeholder={t('settings.openaiApiBaseUrlPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n required\n />\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.openaiApiEmbeddingModel')}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.openaiApiEmbeddingModel}\n onChange={(e) =>\n handleSmartRoutingConfigChange('openaiApiEmbeddingModel', e.target.value)\n }\n placeholder={t('settings.openaiApiEmbeddingModelPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n required\n />\n </div>\n </div>\n </>\n ) : (\n <>\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.azureOpenaiEndpoint') || 'Azure OpenAI Endpoint'}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.azureOpenaiEndpoint}\n onChange={(e) =>\n handleSmartRoutingConfigChange('azureOpenaiEndpoint', e.target.value)\n }\n placeholder={\n t('settings.azureOpenaiEndpointPlaceholder') ||\n 'https://YOUR_RESOURCE_NAME.openai.azure.com'\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.azureOpenaiApiKey') || 'Azure OpenAI API Key'}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"password\"\n value={tempSmartRoutingConfig.azureOpenaiApiKey}\n onChange={(e) =>\n handleSmartRoutingConfigChange('azureOpenaiApiKey', e.target.value)\n }\n placeholder={t('settings.azureOpenaiApiKeyPlaceholder') || '***'}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm border-gray-300\"\n disabled={loading}\n />\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.azureOpenaiApiVersion') || 'Azure OpenAI API Version'}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.azureOpenaiApiVersion}\n onChange={(e) =>\n handleSmartRoutingConfigChange('azureOpenaiApiVersion', e.target.value)\n }\n placeholder={\n t('settings.azureOpenaiApiVersionPlaceholder') || '2024-02-15-preview'\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.azureOpenaiEmbeddingDeployment') ||\n 'Azure Embedding Deployment'}\n </h3>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.azureOpenaiEmbeddingDeployment}\n onChange={(e) =>\n handleSmartRoutingConfigChange(\n 'azureOpenaiEmbeddingDeployment',\n e.target.value,\n )\n }\n placeholder={\n t('settings.azureOpenaiEmbeddingDeploymentPlaceholder') ||\n 'your-embedding-deployment-name'\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n <span className=\"text-red-500 px-1\">*</span>\n {t('settings.azureOpenaiEmbeddingModel') || 'Azure Embedding Model Name'}\n </h3>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t('settings.azureOpenaiEmbeddingModelDescription') ||\n 'The actual OpenAI model name deployed in Azure (e.g. text-embedding-3-small). Used for accurate token counting.'}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempSmartRoutingConfig.azureOpenaiEmbeddingModel}\n onChange={(e) =>\n handleSmartRoutingConfigChange(\n 'azureOpenaiEmbeddingModel',\n e.target.value,\n )\n }\n placeholder={\n t('settings.azureOpenaiEmbeddingModelPlaceholder') ||\n 'text-embedding-3-small'\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n required\n />\n </div>\n </div>\n </>\n )}\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.basePacingDelayMs')}\n </h3>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t('settings.basePacingDelayMsDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"number\"\n min=\"0\"\n step=\"1000\"\n value={tempSmartRoutingConfig.basePacingDelayMs}\n onChange={(e) =>\n handleSmartRoutingConfigChange('basePacingDelayMs', e.target.value)\n }\n placeholder={\n t('settings.basePacingDelayMsPlaceholder') || 'Empty = default 0 ms'\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n </div>\n <p className=\"text-xs text-gray-500 mt-2\">\n {(() => {\n const trimmedValue = tempSmartRoutingConfig.basePacingDelayMs.trim();\n if (!trimmedValue) {\n return t('settings.basePacingDelayMsAuto', { value: 0 });\n }\n if (trimmedValue === '0') {\n return t('settings.basePacingDelayMsZero');\n }\n return t('settings.basePacingDelayMsOverride');\n })()}\n </p>\n\n\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.embeddingEncodingFormat')}\n </h3>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t('settings.embeddingEncodingFormatDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <select\n value={tempSmartRoutingConfig.embeddingEncodingFormat}\n onChange={(e) =>\n handleSmartRoutingConfigChange(\n 'embeddingEncodingFormat',\n e.target.value as 'auto' | 'base64' | 'float',\n )\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-select\"\n disabled={loading}\n >\n <option value=\"auto\">\n {t('settings.embeddingEncodingFormatAuto') || 'Auto'}\n </option>\n <option value=\"base64\">Base64</option>\n <option value=\"float\">Float</option>\n </select>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.embeddingMaxTokens')}\n </h3>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t('settings.embeddingMaxTokensDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"number\"\n min=\"1\"\n value={tempSmartRoutingConfig.embeddingMaxTokens}\n onChange={(e) =>\n handleSmartRoutingConfigChange('embeddingMaxTokens', e.target.value)\n }\n placeholder={\n t('settings.embeddingMaxTokensPlaceholder') || 'Empty = auto by model'\n }\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n </div>\n <p className=\"text-xs text-gray-500 mt-2\">\n {(() => {\n const embeddingModelName =\n (tempSmartRoutingConfig.embeddingProvider === 'azure_openai'\n ? tempSmartRoutingConfig.azureOpenaiEmbeddingModel ||\n smartRoutingConfig.azureOpenaiEmbeddingModel\n : tempSmartRoutingConfig.openaiApiEmbeddingModel ||\n smartRoutingConfig.openaiApiEmbeddingModel) ||\n 'text-embedding-3-small';\n\n return tempSmartRoutingConfig.embeddingMaxTokens.trim()\n ? t('settings.embeddingMaxTokensOverride')\n : t('settings.embeddingMaxTokensAuto', {\n limit: getDefaultTokenLimitForUI(embeddingModelName),\n model: embeddingModelName,\n });\n })()}\n </p>\n </div>\n \n <div\n className=\"flex items-center justify-between\"\n style={{\n padding: '12px 14px',\n border: '1px solid var(--hub-line)',\n borderRadius: 8,\n background: 'var(--hub-bg-2)',\n }}\n >\n <div>\n <h3 className=\"font-medium\" style={{ color: 'var(--hub-ink)', fontSize: 13 }}>\n {t('settings.progressiveDisclosure')}\n </h3>\n <p style={{ fontSize: 12, color: 'var(--hub-ink-3)' }}>\n {t('settings.progressiveDisclosureDescription')}\n </p>\n </div>\n <Switch\n disabled={loading || !smartRoutingConfig.enabled}\n checked={smartRoutingConfig.progressiveDisclosure}\n onCheckedChange={(checked) =>\n updateSmartRoutingConfig('progressiveDisclosure', checked)\n }\n />\n </div>\n </div> {/* end space-y-3 fields wrapper */}\n\n <div className=\"flex justify-end pt-3\">\n <button\n onClick={handleSaveSmartRoutingConfig}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* OAuth Server Configuration Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_OAUTH_SERVER}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('oauthServerConfig')}\n >\n <div className=\"flex items-center gap-2.5\">\n <Lock size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('pages.settings.oauthServer')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">{sectionsVisible.oauthServerConfig ? '−' : '+'}</span>\n </div>\n\n {sectionsVisible.oauthServerConfig && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">{t('settings.enableOauthServer')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.enableOauthServerDescription')}\n </p>\n </div>\n <Switch\n disabled={loading}\n checked={oauthServerConfig.enabled}\n onCheckedChange={(checked) => handleOAuthServerToggle('enabled', checked)}\n />\n </div>\n\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">{t('settings.requireClientSecret')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.requireClientSecretDescription')}\n </p>\n </div>\n <Switch\n disabled={loading || !oauthServerConfig.enabled}\n checked={oauthServerConfig.requireClientSecret}\n onCheckedChange={(checked) =>\n handleOAuthServerToggle('requireClientSecret', checked)\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">{t('settings.requireState')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.requireStateDescription')}</p>\n </div>\n <Switch\n disabled={loading || !oauthServerConfig.enabled}\n checked={oauthServerConfig.requireState}\n onCheckedChange={(checked) => handleOAuthServerToggle('requireState', checked)}\n />\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.accessTokenLifetime')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.accessTokenLifetimeDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"number\"\n value={tempOAuthServerConfig.accessTokenLifetime}\n onChange={(e) =>\n handleOAuthServerNumberChange('accessTokenLifetime', e.target.value)\n }\n placeholder={t('settings.accessTokenLifetimePlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveOAuthServerNumberConfig('accessTokenLifetime')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.refreshTokenLifetime')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.refreshTokenLifetimeDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"number\"\n value={tempOAuthServerConfig.refreshTokenLifetime}\n onChange={(e) =>\n handleOAuthServerNumberChange('refreshTokenLifetime', e.target.value)\n }\n placeholder={t('settings.refreshTokenLifetimePlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveOAuthServerNumberConfig('refreshTokenLifetime')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.authorizationCodeLifetime')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.authorizationCodeLifetimeDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"number\"\n value={tempOAuthServerConfig.authorizationCodeLifetime}\n onChange={(e) =>\n handleOAuthServerNumberChange('authorizationCodeLifetime', e.target.value)\n }\n placeholder={t('settings.authorizationCodeLifetimePlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveOAuthServerNumberConfig('authorizationCodeLifetime')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.allowedScopes')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.allowedScopesDescription')}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempOAuthServerConfig.allowedScopes}\n onChange={(e) => handleOAuthServerTextChange('allowedScopes', e.target.value)}\n placeholder={t('settings.allowedScopesPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={saveOAuthServerAllowedScopes}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md space-y-4\">\n <div className=\"flex justify-between items-center\">\n <div>\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.enableDynamicRegistration')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.dynamicRegistrationDescription')}\n </p>\n </div>\n <Switch\n disabled={loading || !oauthServerConfig.enabled}\n checked={oauthServerConfig.dynamicRegistration.enabled}\n onCheckedChange={(checked) =>\n handleDynamicRegistrationToggle({ enabled: checked })\n }\n />\n </div>\n\n <div>\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.dynamicRegistrationAllowedGrantTypes')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.dynamicRegistrationAllowedGrantTypesDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempOAuthServerConfig.dynamicRegistrationAllowedGrantTypes}\n onChange={(e) =>\n handleOAuthServerTextChange(\n 'dynamicRegistrationAllowedGrantTypes',\n e.target.value,\n )\n }\n placeholder={t('settings.dynamicRegistrationAllowedGrantTypesPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={\n loading ||\n !oauthServerConfig.enabled ||\n !oauthServerConfig.dynamicRegistration.enabled\n }\n />\n <button\n onClick={saveOAuthServerGrantTypes}\n disabled={\n loading ||\n !oauthServerConfig.enabled ||\n !oauthServerConfig.dynamicRegistration.enabled\n }\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.dynamicRegistrationAuth')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.dynamicRegistrationAuthDescription')}\n </p>\n </div>\n <Switch\n disabled={\n loading ||\n !oauthServerConfig.enabled ||\n !oauthServerConfig.dynamicRegistration.enabled\n }\n checked={oauthServerConfig.dynamicRegistration.requiresAuthentication}\n onCheckedChange={(checked) =>\n handleDynamicRegistrationToggle({ requiresAuthentication: checked })\n }\n />\n </div>\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* MCPRouter Configuration Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_INSTALL_CONFIG}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('mcpRouterConfig')}\n >\n <div className=\"flex items-center gap-2.5\">\n <Cloud size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('settings.mcpRouterConfig')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">\n {sectionsVisible.mcpRouterConfig ? '−' : '+'}\n </span>\n </div>\n\n {sectionsVisible.mcpRouterConfig && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.mcpRouterApiKey')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.mcpRouterApiKeyDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"password\"\n value={tempMCPRouterConfig.apiKey}\n onChange={(e) => handleMCPRouterConfigChange('apiKey', e.target.value)}\n placeholder={t('settings.mcpRouterApiKeyPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm border-gray-300 form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveMCPRouterConfig('apiKey')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.mcpRouterBaseUrl')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.mcpRouterBaseUrlDescription')}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempMCPRouterConfig.baseUrl}\n onChange={(e) => handleMCPRouterConfigChange('baseUrl', e.target.value)}\n placeholder={t('settings.mcpRouterBaseUrlPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveMCPRouterConfig('baseUrl')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* System Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_SYSTEM_CONFIG}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('nameSeparator')}\n >\n <div className=\"flex items-center gap-2.5\">\n <SlidersHorizontal size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('settings.systemSettings')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">{sectionsVisible.nameSeparator ? '−' : '+'}</span>\n </div>\n\n {sectionsVisible.nameSeparator && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.nameSeparatorLabel')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.nameSeparatorDescription')}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempNameSeparator}\n onChange={(e) => setTempNameSeparator(e.target.value)}\n placeholder=\"-\"\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n maxLength={5}\n />\n <button\n onClick={saveNameSeparator}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.enableSessionRebuild')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.enableSessionRebuildDescription')}\n </p>\n </div>\n <Switch\n disabled={loading}\n checked={enableSessionRebuild}\n onCheckedChange={(checked) => updateSessionRebuild(checked)}\n />\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* Route Configuration Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_ROUTE_CONFIG}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('routingConfig')}\n >\n <div className=\"flex items-center gap-2.5\">\n <ShieldCheck size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('pages.settings.routeConfig')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">{sectionsVisible.routingConfig ? '−' : '+'}</span>\n </div>\n\n {sectionsVisible.routingConfig && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">{t('settings.enableGlobalRoute')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.enableGlobalRouteDescription')}\n </p>\n </div>\n <Switch\n disabled={loading}\n checked={routingConfig.enableGlobalRoute}\n onCheckedChange={(checked) =>\n handleRoutingConfigChange('enableGlobalRoute', checked)\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">\n {t('settings.enableGroupNameRoute')}\n </h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.enableGroupNameRouteDescription')}\n </p>\n </div>\n <Switch\n disabled={loading}\n checked={routingConfig.enableGroupNameRoute}\n onCheckedChange={(checked) =>\n handleRoutingConfigChange('enableGroupNameRoute', checked)\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div>\n <h3 className=\"font-medium text-gray-700\">{t('settings.skipAuth')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.skipAuthDescription')}</p>\n </div>\n <Switch\n disabled={loading}\n checked={routingConfig.skipAuth}\n onCheckedChange={(checked) => handleRoutingConfigChange('skipAuth', checked)}\n />\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.jsonBodyLimit')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.jsonBodyLimitDescription')}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={tempRoutingConfig.jsonBodyLimit}\n onChange={(e) => handleTempRoutingConfigChange('jsonBodyLimit', e.target.value)}\n placeholder={t('settings.jsonBodyLimitPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => handleRoutingConfigChange('jsonBodyLimit', tempRoutingConfig.jsonBodyLimit)}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* Installation Configuration Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_INSTALL_CONFIG}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('installConfig')}\n >\n <div className=\"flex items-center gap-2.5\">\n <Package size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('settings.installConfig')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">{sectionsVisible.installConfig ? '−' : '+'}</span>\n </div>\n\n {sectionsVisible.installConfig && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.baseUrl')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.baseUrlDescription')}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={installConfig.baseUrl}\n onChange={(e) => handleInstallConfigChange('baseUrl', e.target.value)}\n placeholder={t('settings.baseUrlPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveInstallConfig('baseUrl')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.pythonIndexUrl')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.pythonIndexUrlDescription')}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={installConfig.pythonIndexUrl}\n onChange={(e) => handleInstallConfigChange('pythonIndexUrl', e.target.value)}\n placeholder={t('settings.pythonIndexUrlPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveInstallConfig('pythonIndexUrl')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-2\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.npmRegistry')}</h3>\n <p className=\"text-sm text-gray-500\">{t('settings.npmRegistryDescription')}</p>\n </div>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"text\"\n value={installConfig.npmRegistry}\n onChange={(e) => handleInstallConfigChange('npmRegistry', e.target.value)}\n placeholder={t('settings.npmRegistryPlaceholder')}\n className=\"flex-1 mt-1 block w-full py-2 px-3 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm form-input\"\n disabled={loading}\n />\n <button\n onClick={() => saveInstallConfig('npmRegistry')}\n disabled={loading}\n className=\"hub-btn primary\"\n >\n {t('common.save')}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n\n {/* Change Password */}\n <div className=\"hub-card mb-6 overflow-hidden\" data-section=\"password\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('password')}\n role=\"button\"\n >\n <div className=\"flex items-center gap-2.5\">\n <KeyRound size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('auth.changePassword')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">{sectionsVisible.password ? '−' : '+'}</span>\n </div>\n\n {sectionsVisible.password && (\n <div className=\"max-w-lg pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <ChangePasswordForm onSuccess={handlePasswordChangeSuccess} />\n </div>\n )}\n </div>\n\n {/* Export MCP Settings */}\n <PermissionChecker permissions={PERMISSIONS.SETTINGS_EXPORT_CONFIG}>\n <div className=\"hub-card mb-6 overflow-hidden\">\n <div\n className=\"flex justify-between items-center cursor-pointer transition-colors hover:bg-[var(--hub-surface-hover)] py-3 px-5\"\n onClick={() => toggleSection('exportConfig')}\n >\n <div className=\"flex items-center gap-2.5\">\n <FileDown size={15} className=\"text-[var(--hub-ink-2)]\" />\n <h2 className=\"font-medium text-[var(--hub-ink)]\">{t('settings.exportMcpSettings')}</h2>\n </div>\n <span className=\"text-[var(--hub-ink-3)]\">{sectionsVisible.exportConfig ? '−' : '+'}</span>\n </div>\n\n {sectionsVisible.exportConfig && (\n <div className=\"space-y-4 pb-4 px-6 pt-4 border-t border-[var(--hub-line-2)]\">\n <div className=\"p-3 bg-gray-50 dark:bg-gray-800 rounded-md\">\n <div className=\"mb-4\">\n <h3 className=\"font-medium text-gray-700\">{t('settings.mcpSettingsJson')}</h3>\n <p className=\"text-sm text-gray-500\">\n {t('settings.mcpSettingsJsonDescription')}\n </p>\n </div>\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={handleCopyConfig}\n disabled={!mcpSettingsJson}\n className=\"hub-btn primary\"\n >\n {copiedConfig ? <Check size={16} /> : <Copy size={16} />}\n {copiedConfig ? t('common.copied') : t('settings.copyToClipboard')}\n </button>\n <button\n onClick={handleDownloadConfig}\n disabled={!mcpSettingsJson}\n className=\"hub-btn\"\n >\n <Download size={16} />\n {t('settings.downloadJson')}\n </button>\n </div>\n {mcpSettingsJson && (\n <div className=\"mt-3\">\n <pre className=\"bg-gray-900 text-gray-100 p-4 rounded-md overflow-x-auto text-xs max-h-96\">\n {mcpSettingsJson}\n </pre>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n </PermissionChecker>\n </div>\n );\n};\n\nexport default SettingsPage;\n"],"names":["validatePasswordStrength","password","errors","ChangePasswordForm","onSuccess","onCancel","t","useTranslation","formData","setFormData","useState","confirmPassword","setConfirmPassword","isLoading","setIsLoading","error","setError","success","setSuccess","passwordErrors","setPasswordErrors","handleChange","e","name","value","prev","validation","handleSubmit","response","changePassword","jsxs","jsx","errorKey","MultiSelect","options","selected","onChange","placeholder","disabled","className","isOpen","setIsOpen","searchTerm","setSearchTerm","dropdownRef","useRef","inputRef","useEffect","handleClickOutside","event","filteredOptions","option","handleToggleOption","newSelected","item","handleRemoveItem","handleToggleDropdown","_a","getSelectedLabels","opt","Fragment","label","index","X","ChevronDown","isSelected","Check","generateRandomKey","length","characters","array","x","PERMISSIONS","BearerKeyRow","keyData","loading","availableServers","availableGroups","onSave","onDelete","showToast","useToast","isEditing","setIsEditing","setName","token","setToken","enabled","setEnabled","accessType","setAccessType","selectedGroups","setSelectedGroups","selectedServers","setSelectedServers","saving","setSaving","deleting","setDeleting","handleCopyToken","textArea","handleSave","handleDelete","isGroupsMode","isCustomMode","formatAccessTypeDisplay","key","parts","Switch","checked","Copy","Edit","Trash2","getDefaultTokenLimitForUI","model","lower","MODEL_LIMITS","pattern","limit","parseEmbeddingMaxTokensForUpdate","rawValue","currentValue","trimmed","parsed","result","parseBasePacingDelayForUpdate","SettingsPage","navigate","useNavigate","servers","useServerContext","groups","useGroupData","installConfig","setInstallConfig","tempSmartRoutingConfig","setTempSmartRoutingConfig","tempMCPRouterConfig","setTempMCPRouterConfig","tempOAuthServerConfig","setTempOAuthServerConfig","tempNameSeparator","setTempNameSeparator","showAddBearerKeyForm","setShowAddBearerKeyForm","routingConfig","tempRoutingConfig","setTempRoutingConfig","savedInstallConfig","smartRoutingConfig","mcpRouterConfig","oauthServerConfig","nameSeparator","enableSessionRebuild","bearerKeys","updateRoutingConfig","updateInstallConfig","updateSmartRoutingConfig","updateSmartRoutingConfigBatch","updateMCPRouterConfig","updateOAuthServerConfig","updateNameSeparator","updateSessionRebuild","exportMCPSettings","createBearerKey","updateBearerKey","deleteBearerKey","refreshBearerKeys","useSettingsData","_b","sectionsVisible","setSectionsVisible","toggleSection","section","handleRoutingConfigChange","handleTempRoutingConfigChange","handleInstallConfigChange","saveInstallConfig","handleSmartRoutingConfigChange","handleMCPRouterConfigChange","saveMCPRouterConfig","handleOAuthServerNumberChange","handleOAuthServerTextChange","saveOAuthServerNumberConfig","parsedValue","saveOAuthServerAllowedScopes","scopes","scope","saveOAuthServerGrantTypes","grantTypes","grant","handleOAuthServerToggle","handleDynamicRegistrationToggle","updates","saveNameSeparator","handleSmartRoutingEnabledChange","currentDbUrl","missingFields","currentEndpoint","currentKey","currentApiVersion","currentDeployment","currentOpenaiApiKey","currentOpenaiApiBaseUrl","currentOpenaiApiEmbeddingModel","parsedBasePacingDelay","parsedTokens","handleSaveSmartRoutingConfig","parsedEmbeddingMaxTokens","handlePasswordChangeSuccess","copiedConfig","setCopiedConfig","mcpSettingsJson","setMcpSettingsJson","newBearerKey","setNewBearerKey","newSelectedGroups","setNewSelectedGroups","newSelectedServers","setNewSelectedServers","server","group","fetchMcpSettings","configJson","handleCopyConfig","err","handleDownloadConfig","blob","url","link","parseCommaSeparated","handleCreateBearerKey","handleSaveExistingBearerKey","id","payload","handleDeleteExistingBearerKey","PermissionChecker","Key","RouteIcon","EndpointCopy","CodeIcon","Zap","Database","Wrench","Sparkles","step","i","trimmedValue","embeddingModelName","Lock","Cloud","SlidersHorizontal","ShieldCheck","Package","KeyRound","FileDown","Download"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as e}from"./framework-vendor-BUhDPOUZ.js";import{m as d}from"./index-BGiKkKzj.js";import{u}from"./i18n-vendor-Kbr87Ofu.js";const l={connected:"ok",connecting:"warn",oauth_required:"warn",disconnected:"err"},h={connected:"status.online",connecting:"status.connecting",oauth_required:"status.oauthRequired",disconnected:"status.offline"},a=({kind:n,label:r,className:o,onClick:t,title:s})=>e.jsxs("span",{className:d("hub-status",n,t?"cursor-pointer hover:opacity-80":"",o),onClick:t,title:s,children:[e.jsx("span",{className:"hub-dot"}),r!=null&&e.jsx("span",{children:r})]}),j=({status:n,enabled:r,onAuthClick:o,className:t})=>{const{t:s}=u();if(r===!1)return e.jsx(a,{kind:"muted",label:s("server.disable")||"Disabled",className:t});const c=l[n]??"muted",i=n==="oauth_required";return e.jsx(a,{kind:c,label:e.jsxs(e.Fragment,{children:[i&&e.jsx("span",{"aria-hidden":!0,children:"🔐"}),e.jsx("span",{children:s(h[n]||n)})]}),onClick:i&&o?o:void 0,title:i?s("status.clickToAuthorize"):void 0,className:t})};export{j as S,a};
|
|
2
|
+
//# sourceMappingURL=StatusDot-CQzailBQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusDot-CQzailBQ.js","sources":["../../src/components/ui/StatusDot.tsx"],"sourcesContent":["import React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport type { ServerStatus } from '@/types';\nimport { cn } from '@/utils/cn';\n\nexport type DotKind = 'ok' | 'warn' | 'err' | 'muted';\n\nconst STATUS_TO_KIND: Record<ServerStatus, DotKind> = {\n connected: 'ok',\n connecting: 'warn',\n oauth_required: 'warn',\n disconnected: 'err',\n};\n\nconst STATUS_TO_KEY: Record<ServerStatus, string> = {\n connected: 'status.online',\n connecting: 'status.connecting',\n oauth_required: 'status.oauthRequired',\n disconnected: 'status.offline',\n};\n\ninterface StatusDotProps {\n kind: DotKind;\n label?: React.ReactNode;\n className?: string;\n onClick?: (e: React.MouseEvent) => void;\n title?: string;\n}\n\nexport const StatusDot: React.FC<StatusDotProps> = ({ kind, label, className, onClick, title }) => (\n <span\n className={cn('hub-status', kind, onClick ? 'cursor-pointer hover:opacity-80' : '', className)}\n onClick={onClick}\n title={title}\n >\n <span className=\"hub-dot\" />\n {label != null && <span>{label}</span>}\n </span>\n);\n\ninterface ServerStatusDotProps {\n status: ServerStatus;\n enabled?: boolean;\n onAuthClick?: (e: React.MouseEvent) => void;\n className?: string;\n}\n\nexport const ServerStatusDot: React.FC<ServerStatusDotProps> = ({\n status,\n enabled,\n onAuthClick,\n className,\n}) => {\n const { t } = useTranslation();\n if (enabled === false) {\n return <StatusDot kind=\"muted\" label={t('server.disable') || 'Disabled'} className={className} />;\n }\n const kind = STATUS_TO_KIND[status] ?? 'muted';\n const isOAuth = status === 'oauth_required';\n return (\n <StatusDot\n kind={kind}\n label={\n <>\n {isOAuth && <span aria-hidden>🔐</span>}\n <span>{t(STATUS_TO_KEY[status] || status)}</span>\n </>\n }\n onClick={isOAuth && onAuthClick ? onAuthClick : undefined}\n title={isOAuth ? t('status.clickToAuthorize') : undefined}\n className={className}\n />\n );\n};\n"],"names":["STATUS_TO_KIND","STATUS_TO_KEY","StatusDot","kind","label","className","onClick","title","jsxs","cn","jsx","ServerStatusDot","status","enabled","onAuthClick","t","useTranslation","isOAuth","Fragment"],"mappings":"oIAOA,MAAMA,EAAgD,CACpD,UAAW,KACX,WAAY,OACZ,eAAgB,OAChB,aAAc,KAChB,EAEMC,EAA8C,CAClD,UAAW,gBACX,WAAY,oBACZ,eAAgB,uBAChB,aAAc,gBAChB,EAUaC,EAAsC,CAAC,CAAE,KAAAC,EAAM,MAAAC,EAAO,UAAAC,EAAW,QAAAC,EAAS,MAAAC,KACrFC,EAAAA,KAAC,OAAA,CACC,UAAWC,EAAG,aAAcN,EAAMG,EAAU,kCAAoC,GAAID,CAAS,EAC7F,QAAAC,EACA,MAAAC,EAEA,SAAA,CAAAG,EAAAA,IAAC,OAAA,CAAK,UAAU,SAAA,CAAU,EACzBN,GAAS,MAAQM,EAAAA,IAAC,OAAA,CAAM,SAAAN,CAAA,CAAM,CAAA,CAAA,CACjC,EAUWO,EAAkD,CAAC,CAC9D,OAAAC,EACA,QAAAC,EACA,YAAAC,EACA,UAAAT,CACF,IAAM,CACJ,KAAM,CAAE,EAAAU,CAAA,EAAMC,EAAA,EACd,GAAIH,IAAY,GACd,OAAOH,MAACR,GAAU,KAAK,QAAQ,MAAOa,EAAE,gBAAgB,GAAK,WAAY,UAAAV,CAAA,CAAsB,EAEjG,MAAMF,EAAOH,EAAeY,CAAM,GAAK,QACjCK,EAAUL,IAAW,iBAC3B,OACEF,EAAAA,IAACR,EAAA,CACC,KAAAC,EACA,MACEK,EAAAA,KAAAU,WAAA,CACG,SAAA,CAAAD,GAAWP,EAAAA,IAAC,OAAA,CAAK,cAAW,GAAC,SAAA,KAAE,QAC/B,OAAA,CAAM,SAAAK,EAAEd,EAAcW,CAAM,GAAKA,CAAM,CAAA,CAAE,CAAA,EAC5C,EAEF,QAASK,GAAWH,EAAcA,EAAc,OAChD,MAAOG,EAAUF,EAAE,yBAAyB,EAAI,OAChD,UAAAV,CAAA,CAAA,CAGN"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as s}from"./framework-vendor-
|
|
2
|
-
//# sourceMappingURL=ToggleGroup-
|
|
1
|
+
import{j as s}from"./framework-vendor-BUhDPOUZ.js";import{m as i}from"./index-BGiKkKzj.js";const l=({checked:t,onCheckedChange:n,disabled:o=!1})=>s.jsx("button",{type:"button",role:"switch","aria-checked":t,disabled:o,className:i("relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500",t?"bg-blue-200":"bg-gray-100",o?"opacity-50 cursor-not-allowed":"cursor-pointer"),onClick:()=>!o&&n(!t),children:s.jsx("span",{className:i("inline-block h-4 w-4 transform rounded-full bg-white transition-transform",t?"translate-x-6":"translate-x-1")})});export{l as S};
|
|
2
|
+
//# sourceMappingURL=ToggleGroup-CNBBvo3C.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroup-
|
|
1
|
+
{"version":3,"file":"ToggleGroup-CNBBvo3C.js","sources":["../../src/components/ui/ToggleGroup.tsx"],"sourcesContent":["import React, { ReactNode } from 'react';\nimport { cn } from '@/utils/cn';\n\ninterface ToggleGroupItemProps {\n value: string;\n isSelected: boolean;\n onClick: () => void;\n children: ReactNode;\n}\n\nexport const ToggleGroupItem: React.FC<ToggleGroupItemProps> = ({\n isSelected,\n onClick,\n children\n}) => {\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={isSelected}\n className={cn(\n \"flex w-full items-center justify-between p-2 rounded transition-colors cursor-pointer\",\n isSelected\n ? \"bg-blue-50 text-blue-700 hover:bg-blue-100 border-l-4 border-blue-500\"\n : \"hover:bg-gray-50 text-gray-700\"\n )}\n onClick={onClick}\n >\n <span className=\"flex items-center\">\n {children}\n </span>\n {isSelected && (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" className=\"w-5 h-5 text-blue-500\">\n <path fillRule=\"evenodd\" d=\"M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z\" clipRule=\"evenodd\" />\n </svg>\n )}\n </button>\n );\n};\n\ninterface ToggleGroupProps {\n label: string;\n helpText?: string;\n noOptionsText?: string;\n values: string[];\n options: { value: string; label: string }[];\n onChange: (values: string[]) => void;\n className?: string;\n}\n\nexport const ToggleGroup: React.FC<ToggleGroupProps> = ({\n label,\n helpText,\n noOptionsText = \"No options available\",\n values,\n options,\n onChange,\n className\n}) => {\n const handleToggle = (value: string) => {\n const isSelected = values.includes(value);\n if (isSelected) {\n onChange(values.filter(v => v !== value));\n } else {\n onChange([...values, value]);\n }\n };\n\n return (\n <div className={className}>\n <label className=\"block text-gray-700 text-sm font-bold mb-2\">\n {label}\n </label>\n <div className=\"border border-gray-200 dark:border-gray-700 rounded shadow max-h-60 overflow-y-auto\">\n {options.length === 0 ? (\n <p className=\"text-gray-500 text-sm p-3\">{noOptionsText}</p>\n ) : (\n <div className=\"space-y-1 p-1\">\n {options.map(option => (\n <ToggleGroupItem\n key={option.value}\n value={option.value}\n isSelected={values.includes(option.value)}\n onClick={() => handleToggle(option.value)}\n >\n {option.label}\n </ToggleGroupItem>\n ))}\n </div>\n )}\n </div>\n {helpText && (\n <p className=\"text-xs text-gray-500 mt-1\">\n {helpText}\n </p>\n )}\n </div>\n );\n};\n\ninterface SwitchProps {\n checked: boolean;\n onCheckedChange: (checked: boolean) => void;\n disabled?: boolean;\n}\n\nexport const Switch: React.FC<SwitchProps> = ({\n checked,\n onCheckedChange,\n disabled = false\n}) => {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n disabled={disabled}\n className={cn(\n \"relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500\",\n checked ? \"bg-blue-200\" : \"bg-gray-100\",\n disabled ? \"opacity-50 cursor-not-allowed\" : \"cursor-pointer\"\n )}\n onClick={() => !disabled && onCheckedChange(!checked)}\n >\n <span\n className={cn(\n \"inline-block h-4 w-4 transform rounded-full bg-white transition-transform\",\n checked ? \"translate-x-6\" : \"translate-x-1\"\n )}\n />\n </button>\n );\n};"],"names":["Switch","checked","onCheckedChange","disabled","jsx","cn"],"mappings":"2FA0GO,MAAMA,EAAgC,CAAC,CAC5C,QAAAC,EACA,gBAAAC,EACA,SAAAC,EAAW,EACb,IAEIC,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,KAAK,SACL,eAAcH,EACd,SAAAE,EACA,UAAWE,EACT,wLACAJ,EAAU,cAAgB,cAC1BE,EAAW,gCAAkC,gBAAA,EAE/C,QAAS,IAAM,CAACA,GAAYD,EAAgB,CAACD,CAAO,EAEpD,SAAAG,EAAAA,IAAC,OAAA,CACC,UAAWC,EACT,4EACAJ,EAAU,gBAAkB,eAAA,CAC9B,CAAA,CACF,CAAA"}
|