refactor(Selector, HomePage, MessageGroupSettings, NutstoreSettings, WebDavSettings): replace Select components with Selector for improved consistency

- Updated Selector component to handle value checks more robustly.
- Removed unused ContentContainer styles in HomePage for cleaner code.
- Replaced Select components with Selector in MessageGroupSettings, NutstoreSettings, and WebDavSettings for a unified UI experience.
- Enhanced option handling in Selector for better integration with existing settings.
This commit is contained in:
Teo 2025-06-13 14:03:30 +08:00
parent 5339f4a9a3
commit 2757fcf6b9
5 changed files with 66 additions and 48 deletions

View File

@ -35,7 +35,7 @@ const Selector = <V extends string | number>({
const [open, setOpen] = useState(false)
const label = useMemo(() => {
if (value) {
if (value !== undefined && value !== null) {
const findLabel = (opts: SelectorOption<V>[]): string | ReactNode | undefined => {
for (const opt of opts) {
if (opt.value === value) {

View File

@ -38,11 +38,6 @@ const Container = styled.div`
flex-direction: column;
`
const ContentContainer = styled.div`
overflow: hidden;
display: flex;
flex: 1;
flex-direction: row;
`
const ContentContainer = styled.div``
export default HomePage

View File

@ -1,10 +1,11 @@
import { SettingOutlined } from '@ant-design/icons'
import Selector from '@renderer/components/Selector'
import { useSettings } from '@renderer/hooks/useSettings'
import { SettingDivider } from '@renderer/pages/settings'
import { SettingRow } from '@renderer/pages/settings'
import { useAppDispatch } from '@renderer/store'
import { setGridColumns, setGridPopoverTrigger } from '@renderer/store/settings'
import { Col, Row, Select, Slider } from 'antd'
import { Col, Row, Slider } from 'antd'
import { Popover } from 'antd'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -18,19 +19,22 @@ const MessageGroupSettings: FC = () => {
return (
<Popover
arrow={false}
trigger={undefined}
showArrow
content={
<div style={{ padding: 10 }}>
<SettingRow>
<div style={{ marginRight: 10 }}>{t('settings.messages.grid_popover_trigger')}</div>
<Select
<Selector
size={14}
value={gridPopoverTrigger || 'hover'}
onChange={(value) => dispatch(setGridPopoverTrigger(value as 'hover' | 'click'))}
size="small">
<Select.Option value="hover">{t('settings.messages.grid_popover_trigger.hover')}</Select.Option>
<Select.Option value="click">{t('settings.messages.grid_popover_trigger.click')}</Select.Option>
</Select>
options={[
{ label: t('settings.messages.grid_popover_trigger.hover'), value: 'hover' },
{ label: t('settings.messages.grid_popover_trigger.click'), value: 'click' }
]}
/>
</SettingRow>
<SettingDivider />
<SettingRow>

View File

@ -1,6 +1,7 @@
import { CheckOutlined, FolderOutlined, LoadingOutlined, SyncOutlined, WarningOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import NutstorePathPopup from '@renderer/components/Popups/NutsorePathPopup'
import Selector from '@renderer/components/Selector'
import { WebdavBackupManager } from '@renderer/components/WebdavBackupManager'
import { useWebdavBackupModal, WebdavBackupModal } from '@renderer/components/WebdavModals'
import { useTheme } from '@renderer/context/ThemeProvider'
@ -23,7 +24,7 @@ import {
} from '@renderer/store/nutstore'
import { modalConfirm } from '@renderer/utils'
import { NUTSTORE_HOST } from '@shared/config/nutstore'
import { Button, Input, Select, Switch, Tooltip, Typography } from 'antd'
import { Button, Input, Switch, Tooltip, Typography } from 'antd'
import dayjs from 'dayjs'
import { FC, useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -279,18 +280,23 @@ const NutstoreSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.data.webdav.autoSync')}</SettingRowTitle>
<Select value={syncInterval} onChange={onSyncIntervalChange} style={{ width: 120 }}>
<Select.Option value={0}>{t('settings.data.webdav.autoSync.off')}</Select.Option>
<Select.Option value={1}>{t('settings.data.webdav.minute_interval', { count: 1 })}</Select.Option>
<Select.Option value={5}>{t('settings.data.webdav.minute_interval', { count: 5 })}</Select.Option>
<Select.Option value={15}>{t('settings.data.webdav.minute_interval', { count: 15 })}</Select.Option>
<Select.Option value={30}>{t('settings.data.webdav.minute_interval', { count: 30 })}</Select.Option>
<Select.Option value={60}>{t('settings.data.webdav.hour_interval', { count: 1 })}</Select.Option>
<Select.Option value={120}>{t('settings.data.webdav.hour_interval', { count: 2 })}</Select.Option>
<Select.Option value={360}>{t('settings.data.webdav.hour_interval', { count: 6 })}</Select.Option>
<Select.Option value={720}>{t('settings.data.webdav.hour_interval', { count: 12 })}</Select.Option>
<Select.Option value={1440}>{t('settings.data.webdav.hour_interval', { count: 24 })}</Select.Option>
</Select>
<Selector
size={14}
value={syncInterval}
onChange={onSyncIntervalChange}
options={[
{ label: t('settings.data.webdav.autoSync.off'), value: 0 },
{ label: t('settings.data.webdav.minute_interval', { count: 1 }), value: 1 },
{ label: t('settings.data.webdav.minute_interval', { count: 5 }), value: 5 },
{ label: t('settings.data.webdav.minute_interval', { count: 15 }), value: 15 },
{ label: t('settings.data.webdav.minute_interval', { count: 30 }), value: 30 },
{ label: t('settings.data.webdav.hour_interval', { count: 1 }), value: 60 },
{ label: t('settings.data.webdav.hour_interval', { count: 2 }), value: 120 },
{ label: t('settings.data.webdav.hour_interval', { count: 6 }), value: 360 },
{ label: t('settings.data.webdav.hour_interval', { count: 12 }), value: 720 },
{ label: t('settings.data.webdav.hour_interval', { count: 24 }), value: 1440 }
]}
/>
</SettingRow>
{nutstoreAutoSync && syncInterval > 0 && (
<>

View File

@ -1,5 +1,6 @@
import { FolderOpenOutlined, SaveOutlined, SyncOutlined, WarningOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import Selector from '@renderer/components/Selector'
import { WebdavBackupManager } from '@renderer/components/WebdavBackupManager'
import { useWebdavBackupModal, WebdavBackupModal } from '@renderer/components/WebdavModals'
import { useTheme } from '@renderer/context/ThemeProvider'
@ -16,7 +17,7 @@ import {
setWebdavSyncInterval as _setWebdavSyncInterval,
setWebdavUser as _setWebdavUser
} from '@renderer/store/settings'
import { Button, Input, Select, Switch, Tooltip } from 'antd'
import { Button, Input, Switch, Tooltip } from 'antd'
import dayjs from 'dayjs'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -173,31 +174,43 @@ const WebDavSettings: FC = () => {
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.data.webdav.autoSync')}</SettingRowTitle>
<Select value={syncInterval} onChange={onSyncIntervalChange} disabled={!webdavHost} style={{ width: 120 }}>
<Select.Option value={0}>{t('settings.data.webdav.autoSync.off')}</Select.Option>
<Select.Option value={1}>{t('settings.data.webdav.minute_interval', { count: 1 })}</Select.Option>
<Select.Option value={5}>{t('settings.data.webdav.minute_interval', { count: 5 })}</Select.Option>
<Select.Option value={15}>{t('settings.data.webdav.minute_interval', { count: 15 })}</Select.Option>
<Select.Option value={30}>{t('settings.data.webdav.minute_interval', { count: 30 })}</Select.Option>
<Select.Option value={60}>{t('settings.data.webdav.hour_interval', { count: 1 })}</Select.Option>
<Select.Option value={120}>{t('settings.data.webdav.hour_interval', { count: 2 })}</Select.Option>
<Select.Option value={360}>{t('settings.data.webdav.hour_interval', { count: 6 })}</Select.Option>
<Select.Option value={720}>{t('settings.data.webdav.hour_interval', { count: 12 })}</Select.Option>
<Select.Option value={1440}>{t('settings.data.webdav.hour_interval', { count: 24 })}</Select.Option>
</Select>
<Selector
size={14}
value={syncInterval}
onChange={onSyncIntervalChange}
disabled={!webdavHost}
options={[
{ label: t('settings.data.webdav.autoSync.off'), value: 0 },
{ label: t('settings.data.webdav.minute_interval', { count: 1 }), value: 1 },
{ label: t('settings.data.webdav.minute_interval', { count: 5 }), value: 5 },
{ label: t('settings.data.webdav.minute_interval', { count: 15 }), value: 15 },
{ label: t('settings.data.webdav.minute_interval', { count: 30 }), value: 30 },
{ label: t('settings.data.webdav.hour_interval', { count: 1 }), value: 60 },
{ label: t('settings.data.webdav.hour_interval', { count: 2 }), value: 120 },
{ label: t('settings.data.webdav.hour_interval', { count: 6 }), value: 360 },
{ label: t('settings.data.webdav.hour_interval', { count: 12 }), value: 720 },
{ label: t('settings.data.webdav.hour_interval', { count: 24 }), value: 1440 }
]}
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitle>{t('settings.data.webdav.maxBackups')}</SettingRowTitle>
<Select value={maxBackups} onChange={onMaxBackupsChange} disabled={!webdavHost} style={{ width: 120 }}>
<Select.Option value={0}>{t('settings.data.webdav.maxBackups.unlimited')}</Select.Option>
<Select.Option value={1}>1</Select.Option>
<Select.Option value={3}>3</Select.Option>
<Select.Option value={5}>5</Select.Option>
<Select.Option value={10}>10</Select.Option>
<Select.Option value={20}>20</Select.Option>
<Select.Option value={50}>50</Select.Option>
</Select>
<Selector
size={14}
value={maxBackups}
onChange={onMaxBackupsChange}
disabled={!webdavHost}
options={[
{ label: t('settings.data.webdav.maxBackups.unlimited'), value: 0 },
{ label: '1', value: 1 },
{ label: '3', value: 3 },
{ label: '5', value: 5 },
{ label: '10', value: 10 },
{ label: '20', value: 20 },
{ label: '50', value: 50 }
]}
/>
</SettingRow>
<SettingDivider />
<SettingRow>