feat: add show/hide toggle for API keys in settings (#7883)

* feat: add show/hide toggle for API keys in settings

Introduces an eye icon button to toggle visibility of API keys and tokens in Joplin, Notion, Siyuan, and Yuque settings pages. Refactors input fields to allow users to view or hide sensitive credentials, improving usability and security. Also updates translation keys in AgentsSubscribeUrlSettings for consistency.

* refactor: settings pages to use Input.Password for tokens

Replaced custom password visibility toggles and related styled-components with Ant Design's Input.Password component in Joplin, Notion, Siyuan, and Yuque settings pages. This simplifies the codebase and improves consistency in handling sensitive input fields.

* fix: Improve layout of token input fields in settings

Wrapped token/password input and check button pairs in Joplin, Notion, and Siyuan settings with Ant Design's Space.Compact for better alignment and consistent UI.

* fix: trigger token change handler on blur in settings

Added onBlur event handlers to the Joplin and Siyuan token input fields to ensure token changes are handled when the input loses focus, improving reliability of token updates.
This commit is contained in:
自由的世界人 2025-07-06 21:37:17 +08:00 committed by GitHub
parent c5d1f2dd7a
commit 7f8ad88c06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 18 additions and 15 deletions

View File

@ -24,18 +24,18 @@ const AgentsSubscribeUrlSettings: FC = () => {
<SettingGroup theme={theme}>
<SettingTitle>
{t('agents.tag.agent')}
{t('settings.websearch.subscribe_add')}
{t('settings.tool.websearch.subscribe_add')}
</SettingTitle>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.websearch.subscribe_url')}</SettingRowTitle>
<SettingRowTitle>{t('settings.tool.websearch.subscribe_url')}</SettingRowTitle>
<HStack alignItems="center" gap="5px" style={{ width: 315 }}>
<Input
type="text"
value={agentssubscribeUrl || ''}
onChange={handleAgentChange}
style={{ width: 315 }}
placeholder={t('settings.websearch.subscribe_name.placeholder')}
placeholder={t('settings.tool.websearch.subscribe_name.placeholder')}
/>
</HStack>
</SettingRow>

View File

@ -5,7 +5,7 @@ import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
import { RootState, useAppDispatch } from '@renderer/store'
import { setJoplinExportReasoning, setJoplinToken, setJoplinUrl } from '@renderer/store/settings'
import { Button, Space, Switch, Tooltip } from 'antd'
import Input from 'antd/es/input/Input'
import { Input } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
@ -107,11 +107,12 @@ const JoplinSettings: FC = () => {
</SettingRowTitle>
<HStack alignItems="center" gap="5px" style={{ width: 315 }}>
<Space.Compact style={{ width: '100%' }}>
<Input
type="password"
<Input.Password
value={joplinToken || ''}
onChange={handleJoplinTokenChange}
onBlur={handleJoplinTokenChange}
placeholder={t('settings.data.joplin.token_placeholder')}
style={{ width: '100%' }}
/>
<Button onClick={handleJoplinConnectionCheck}>{t('settings.data.joplin.check.button')}</Button>
</Space.Compact>

View File

@ -11,7 +11,7 @@ import {
setNotionPageNameKey
} from '@renderer/store/settings'
import { Button, Space, Switch, Tooltip } from 'antd'
import Input from 'antd/es/input/Input'
import { Input } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
@ -122,12 +122,12 @@ const NotionSettings: FC = () => {
<SettingRowTitle>{t('settings.data.notion.api_key')}</SettingRowTitle>
<HStack alignItems="center" gap="5px" style={{ width: 315 }}>
<Space.Compact style={{ width: '100%' }}>
<Input
type="password"
<Input.Password
value={notionApiKey || ''}
onChange={handleNotionTokenChange}
onBlur={handleNotionTokenChange}
placeholder={t('settings.data.notion.api_key_placeholder')}
style={{ width: '100%' }}
/>
<Button onClick={handleNotionConnectionCheck}>{t('settings.data.notion.check.button')}</Button>
</Space.Compact>

View File

@ -5,7 +5,7 @@ import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
import { RootState, useAppDispatch } from '@renderer/store'
import { setSiyuanApiUrl, setSiyuanBoxId, setSiyuanRootPath, setSiyuanToken } from '@renderer/store/settings'
import { Button, Space, Tooltip } from 'antd'
import Input from 'antd/es/input/Input'
import { Input } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
@ -109,11 +109,12 @@ const SiyuanSettings: FC = () => {
</SettingRowTitle>
<HStack alignItems="center" gap="5px" style={{ width: 315 }}>
<Space.Compact style={{ width: '100%' }}>
<Input
type="password"
<Input.Password
value={siyuanToken || ''}
onChange={handleTokenChange}
onBlur={handleTokenChange}
placeholder={t('settings.data.siyuan.token_placeholder')}
style={{ width: '100%' }}
/>
<Button onClick={handleCheckConnection}>{t('settings.data.siyuan.check.button')}</Button>
</Space.Compact>

View File

@ -5,7 +5,7 @@ import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
import { RootState, useAppDispatch } from '@renderer/store'
import { setYuqueRepoId, setYuqueToken, setYuqueUrl } from '@renderer/store/settings'
import { Button, Space, Tooltip } from 'antd'
import Input from 'antd/es/input/Input'
import { Input } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
@ -101,11 +101,12 @@ const YuqueSettings: FC = () => {
</SettingRowTitle>
<HStack alignItems="center" gap="5px" style={{ width: 315 }}>
<Space.Compact style={{ width: '100%' }}>
<Input
type="password"
<Input.Password
value={yuqueToken || ''}
onChange={handleYuqueTokenChange}
onBlur={handleYuqueTokenChange}
placeholder={t('settings.data.yuque.token_placeholder')}
style={{ width: '100%' }}
/>
<Button onClick={handleYuqueConnectionCheck}>{t('settings.data.yuque.check.button')}</Button>
</Space.Compact>