mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
feat(web): base-ui slider (#34064)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@ -145,7 +145,7 @@ describe('AgentStrategy', () => {
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByRole('slider')).toBeInTheDocument()
|
||||
expect(screen.getByLabelText('Count')).toBeInTheDocument()
|
||||
expect(screen.getByRole('textbox')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@ import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Agent } from '@/app/components/base/icons/src/vender/workflow'
|
||||
import ListEmpty from '@/app/components/base/list-empty'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import {
|
||||
NumberField,
|
||||
NumberFieldControls,
|
||||
@ -18,6 +17,7 @@ import {
|
||||
NumberFieldIncrement,
|
||||
NumberFieldInput,
|
||||
} from '@/app/components/base/ui/number-field'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
import { FormTypeEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
|
||||
@ -147,10 +147,11 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
|
||||
<div className="flex w-[200px] items-center gap-3">
|
||||
<Slider
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onValueChange={onChange}
|
||||
className="w-full"
|
||||
min={def.min}
|
||||
max={def.max}
|
||||
aria-label={renderI18nObject(def.label)}
|
||||
/>
|
||||
<NumberField
|
||||
value={value}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import type { FC } from 'react'
|
||||
import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
|
||||
export type InputNumberWithSliderProps = {
|
||||
value: number
|
||||
@ -22,7 +22,7 @@ const InputNumberWithSlider: FC<InputNumberWithSliderProps> = ({
|
||||
onChange,
|
||||
}) => {
|
||||
const handleBlur = useCallback(() => {
|
||||
if (value === undefined || value === null) {
|
||||
if (value === undefined || value === null || Number.isNaN(value)) {
|
||||
onChange(defaultValue)
|
||||
return
|
||||
}
|
||||
@ -57,8 +57,9 @@ const InputNumberWithSlider: FC<InputNumberWithSliderProps> = ({
|
||||
min={min}
|
||||
max={max}
|
||||
step={1}
|
||||
onChange={onChange}
|
||||
onValueChange={onChange}
|
||||
disabled={readonly}
|
||||
aria-label="Number input slider"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -6,8 +6,8 @@ import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { MemoryRole } from '../../../types'
|
||||
@ -154,7 +154,7 @@ const MemoryConfig: FC<Props> = ({
|
||||
size="md"
|
||||
disabled={readonly}
|
||||
/>
|
||||
<div className="system-xs-medium-uppercase text-text-tertiary">{t(`${i18nPrefix}.windowSize`, { ns: 'workflow' })}</div>
|
||||
<div className="text-text-tertiary system-xs-medium-uppercase">{t(`${i18nPrefix}.windowSize`, { ns: 'workflow' })}</div>
|
||||
</div>
|
||||
<div className="flex h-8 items-center space-x-2">
|
||||
<Slider
|
||||
@ -163,8 +163,9 @@ const MemoryConfig: FC<Props> = ({
|
||||
min={WINDOW_SIZE_MIN}
|
||||
max={WINDOW_SIZE_MAX}
|
||||
step={1}
|
||||
onChange={handleWindowSizeChange}
|
||||
onValueChange={handleWindowSizeChange}
|
||||
disabled={readonly || !payload.window?.enabled}
|
||||
aria-label={t(`${i18nPrefix}.windowSize`, { ns: 'workflow' })}
|
||||
/>
|
||||
<Input
|
||||
value={(payload.window?.size || WINDOW_SIZE_DEFAULT) as number}
|
||||
|
||||
@ -3,8 +3,8 @@ import type {
|
||||
} from '@/app/components/workflow/types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
import Split from '@/app/components/workflow/nodes/_base/components/split'
|
||||
import { useRetryConfig } from './hooks'
|
||||
import s from './style.module.css'
|
||||
@ -70,9 +70,10 @@ const RetryOnPanel = ({
|
||||
<Slider
|
||||
className="mr-3 w-[108px]"
|
||||
value={retry_config?.max_retries || 3}
|
||||
onChange={handleMaxRetriesChange}
|
||||
onValueChange={handleMaxRetriesChange}
|
||||
min={1}
|
||||
max={10}
|
||||
aria-label={t('nodes.common.retry.maxRetries', { ns: 'workflow' })}
|
||||
/>
|
||||
<Input
|
||||
type="number"
|
||||
@ -91,9 +92,10 @@ const RetryOnPanel = ({
|
||||
<Slider
|
||||
className="mr-3 w-[108px]"
|
||||
value={retry_config?.retry_interval || 1000}
|
||||
onChange={handleRetryIntervalChange}
|
||||
onValueChange={handleRetryIntervalChange}
|
||||
min={100}
|
||||
max={5000}
|
||||
aria-label={t('nodes.common.retry.retryInterval', { ns: 'workflow' })}
|
||||
/>
|
||||
<Input
|
||||
type="number"
|
||||
|
||||
@ -5,8 +5,8 @@ import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Select from '@/app/components/base/select'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
import Field from '@/app/components/workflow/nodes/_base/components/field'
|
||||
import { ErrorHandleMode } from '@/app/components/workflow/types'
|
||||
import { MAX_PARALLEL_LIMIT } from '@/config'
|
||||
@ -57,7 +57,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
|
||||
title={t(`${i18nPrefix}.input`, { ns: 'workflow' })}
|
||||
required
|
||||
operations={(
|
||||
<div className="system-2xs-medium-uppercase flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 capitalize text-text-tertiary">Array</div>
|
||||
<div className="flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 capitalize text-text-tertiary system-2xs-medium-uppercase">Array</div>
|
||||
)}
|
||||
>
|
||||
<VarReferencePicker
|
||||
@ -76,7 +76,7 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
|
||||
title={t(`${i18nPrefix}.output`, { ns: 'workflow' })}
|
||||
required
|
||||
operations={(
|
||||
<div className="system-2xs-medium-uppercase flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 capitalize text-text-tertiary">Array</div>
|
||||
<div className="flex h-[18px] items-center rounded-[5px] border border-divider-deep px-1 capitalize text-text-tertiary system-2xs-medium-uppercase">Array</div>
|
||||
)}
|
||||
>
|
||||
<VarReferencePicker
|
||||
@ -103,10 +103,11 @@ const Panel: FC<NodePanelProps<IterationNodeType>> = ({
|
||||
<Input type="number" wrapperClassName="w-18 mr-4 " max={MAX_PARALLEL_LIMIT} min={MIN_ITERATION_PARALLEL_NUM} value={inputs.parallel_nums} onChange={(e) => { changeParallelNums(Number(e.target.value)) }} />
|
||||
<Slider
|
||||
value={inputs.parallel_nums}
|
||||
onChange={changeParallelNums}
|
||||
onValueChange={changeParallelNums}
|
||||
max={MAX_PARALLEL_LIMIT}
|
||||
min={MIN_ITERATION_PARALLEL_NUM}
|
||||
className=" mt-4 flex-1 shrink-0"
|
||||
className="mt-4 flex-1 shrink-0"
|
||||
aria-label={t(`${i18nPrefix}.MaxParallelismTitle`, { ns: 'workflow' })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ describe('IndexMethod', () => {
|
||||
|
||||
fireEvent.change(container.querySelector('input') as HTMLInputElement, { target: { value: '7' } })
|
||||
|
||||
expect(onKeywordNumberChange).toHaveBeenCalledWith(7)
|
||||
expect(onKeywordNumberChange).toHaveBeenCalledWith(7, expect.anything())
|
||||
})
|
||||
|
||||
it('should disable keyword controls when readonly is enabled', () => {
|
||||
|
||||
@ -9,8 +9,8 @@ import {
|
||||
HighQuality,
|
||||
} from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
import { Field } from '@/app/components/workflow/nodes/_base/components/layout'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import {
|
||||
@ -94,7 +94,7 @@ const IndexMethod = ({
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<div className="flex grow items-center">
|
||||
<div className="system-xs-medium truncate text-text-secondary">
|
||||
<div className="truncate text-text-secondary system-xs-medium">
|
||||
{t('form.numberOfKeywords', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
<Tooltip
|
||||
@ -107,7 +107,8 @@ const IndexMethod = ({
|
||||
disabled={readonly}
|
||||
className="mr-3 w-24 shrink-0"
|
||||
value={keywordNumber}
|
||||
onChange={onKeywordNumberChange}
|
||||
onValueChange={onKeywordNumberChange}
|
||||
aria-label={t('form.numberOfKeywords', { ns: 'datasetSettings' })}
|
||||
/>
|
||||
<Input
|
||||
disabled={readonly}
|
||||
|
||||
@ -93,11 +93,11 @@ describe('trigger-schedule components', () => {
|
||||
const onChange = vi.fn()
|
||||
render(<OnMinuteSelector value={15} onChange={onChange} />)
|
||||
|
||||
const slider = screen.getByRole('slider')
|
||||
const slider = screen.getByLabelText('workflow.nodes.triggerSchedule.onMinute')
|
||||
slider.focus()
|
||||
await user.keyboard('{ArrowRight}')
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith(16, 0)
|
||||
expect(onChange).toHaveBeenCalledWith(16, expect.objectContaining({ activeThumbIndex: 0 }))
|
||||
})
|
||||
|
||||
it('should keep at least one weekday selected', async () => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import * as React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Slider from '@/app/components/base/slider'
|
||||
import { Slider } from '@/app/components/base/ui/slider'
|
||||
|
||||
type OnMinuteSelectorProps = {
|
||||
value?: number
|
||||
@ -27,7 +27,8 @@ const OnMinuteSelector = ({ value = 0, onChange }: OnMinuteSelectorProps) => {
|
||||
min={0}
|
||||
max={59}
|
||||
step={1}
|
||||
onChange={onChange}
|
||||
onValueChange={onChange}
|
||||
aria-label={t('nodes.triggerSchedule.onMinute', { ns: 'workflow' })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user