Browse Source

Do not display API key when adding a new provider by default

alexchenzl 4 months ago
parent
commit
d7754d77dd
1 changed files with 61 additions and 13 deletions
  1. 61 13
      pages/options/src/components/ModelSettings.tsx

+ 61 - 13
pages/options/src/components/ModelSettings.tsx

@@ -46,6 +46,8 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
   const [isProviderSelectorOpen, setIsProviderSelectorOpen] = useState(false);
   const newlyAddedProviderRef = useRef<string | null>(null);
   const [nameErrors, setNameErrors] = useState<Record<string, string>>({});
+  // Add state for tracking API key visibility
+  const [visibleApiKeys, setVisibleApiKeys] = useState<Record<string, boolean>>({});
   // Create a non-async wrapper for use in render functions
   const [availableModels, setAvailableModels] = useState<
     Array<{ provider: string; providerName: string; model: string }>
@@ -199,6 +201,14 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
     }));
   };
 
+  // Add a toggle handler for API key visibility
+  const toggleApiKeyVisibility = (provider: string) => {
+    setVisibleApiKeys(prev => ({
+      ...prev,
+      [provider]: !prev[provider],
+    }));
+  };
+
   const handleNameChange = (provider: string, name: string) => {
     setModifiedProviders(prev => new Set(prev).add(provider));
     setProviders(prev => {
@@ -899,23 +909,61 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
                       className={`w-20 text-sm font-medium ${isDarkMode ? 'text-gray-300' : 'text-gray-700'}`}>
                       Key{providerConfig.type !== ProviderTypeEnum.CustomOpenAI ? '*' : ''}
                     </label>
-                    <input
-                      id={`${providerId}-api-key`}
-                      type="password"
-                      placeholder={
-                        providerConfig.type === ProviderTypeEnum.CustomOpenAI
-                          ? `${providerConfig.name || providerId} API key (optional)`
-                          : `${providerConfig.name || providerId} API key (required)`
-                      }
-                      value={providerConfig.apiKey || ''}
-                      onChange={e => handleApiKeyChange(providerId, e.target.value, providerConfig.baseUrl)}
-                      className={`flex-1 rounded-md border text-sm ${isDarkMode ? 'border-slate-600 bg-slate-700 text-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-800' : 'border-gray-300 bg-white text-gray-700 focus:border-blue-400 focus:ring-2 focus:ring-blue-200'} p-2 outline-none`}
-                    />
+                    <div className="relative flex-1">
+                      <input
+                        id={`${providerId}-api-key`}
+                        type="password"
+                        placeholder={
+                          providerConfig.type === ProviderTypeEnum.CustomOpenAI
+                            ? `${providerConfig.name || providerId} API key (optional)`
+                            : `${providerConfig.name || providerId} API key (required)`
+                        }
+                        value={providerConfig.apiKey || ''}
+                        onChange={e => handleApiKeyChange(providerId, e.target.value, providerConfig.baseUrl)}
+                        className={`w-full rounded-md border text-sm ${isDarkMode ? 'border-slate-600 bg-slate-700 text-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-800' : 'border-gray-300 bg-white text-gray-700 focus:border-blue-400 focus:ring-2 focus:ring-blue-200'} p-2 outline-none`}
+                      />
+                      {/* Show eye button only for newly added providers */}
+                      {modifiedProviders.has(providerId) && !providersFromStorage.has(providerId) && (
+                        <button
+                          type="button"
+                          className={`absolute right-2 top-1/2 -translate-y-1/2 ${
+                            isDarkMode ? 'text-gray-400 hover:text-gray-300' : 'text-gray-500 hover:text-gray-700'
+                          }`}
+                          onClick={() => toggleApiKeyVisibility(providerId)}
+                          aria-label={visibleApiKeys[providerId] ? 'Hide API key' : 'Show API key'}>
+                          <svg
+                            xmlns="http://www.w3.org/2000/svg"
+                            viewBox="0 0 24 24"
+                            fill="none"
+                            stroke="currentColor"
+                            strokeWidth="2"
+                            strokeLinecap="round"
+                            strokeLinejoin="round"
+                            className="h-5 w-5"
+                            aria-hidden="true">
+                            <title>{visibleApiKeys[providerId] ? 'Hide API key' : 'Show API key'}</title>
+                            {visibleApiKeys[providerId] ? (
+                              <>
+                                <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
+                                <circle cx="12" cy="12" r="3" />
+                                <line x1="2" y1="22" x2="22" y2="2" />
+                              </>
+                            ) : (
+                              <>
+                                <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
+                                <circle cx="12" cy="12" r="3" />
+                              </>
+                            )}
+                          </svg>
+                        </button>
+                      )}
+                    </div>
                   </div>
 
-                  {/* Display API key for newly added providers */}
+                  {/* Display API key for newly added providers only when visible */}
                   {modifiedProviders.has(providerId) &&
                     !providersFromStorage.has(providerId) &&
+                    visibleApiKeys[providerId] &&
                     providerConfig.apiKey && (
                       <div className="ml-20 mt-1">
                         <p