Merge main HEAD (segment 5) into sandboxed-agent-rebase

Resolve 83 conflicts: 10 backend, 62 frontend, 11 config/lock files.
Preserve sandbox/agent/collaboration features while adopting main's
UI refactorings (Dialog/AlertDialog/Popover), model provider updates,
and enterprise features.

Made-with: Cursor
This commit is contained in:
Novice
2026-03-23 14:20:06 +08:00
1671 changed files with 124822 additions and 22302 deletions

View File

@ -43,8 +43,9 @@ describe('InputCombined', () => {
render(
<InputCombined type={DataType.number} value={42} onChange={handleChange} />,
)
const input = screen.getByDisplayValue('42')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
expect(input).toHaveValue('42')
})
it('should render date picker for time type', () => {
@ -96,19 +97,31 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={0} onChange={handleChange} />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '123' } })
expect(handleChange).toHaveBeenCalled()
})
it('should reset cleared number input to 0', () => {
const handleChange = vi.fn()
render(
<InputCombined type={DataType.number} value={42} onChange={handleChange} />,
)
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '' } })
expect(handleChange).toHaveBeenCalledWith(0)
})
it('should display current value for number type', () => {
const handleChange = vi.fn()
render(
<InputCombined type={DataType.number} value={999} onChange={handleChange} />,
)
expect(screen.getByDisplayValue('999')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('999')
})
it('should apply readOnly prop to number input', () => {
@ -117,7 +130,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={42} onChange={handleChange} readOnly />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toHaveAttribute('readonly')
})
})
@ -186,7 +199,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={null} onChange={handleChange} />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
})
@ -208,7 +221,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={0} onChange={handleChange} />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toHaveClass('rounded-l-md')
})
})
@ -230,7 +243,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={0} onChange={handleChange} />,
)
expect(screen.getByDisplayValue('0')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('0')
})
it('should handle negative number', () => {
@ -239,7 +252,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={-100} onChange={handleChange} />,
)
expect(screen.getByDisplayValue('-100')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('-100')
})
it('should handle special characters in string', () => {
@ -263,7 +276,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={42} onChange={handleChange} />,
)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
})
})
})

View File

@ -2,7 +2,14 @@
import type { FC } from 'react'
import * as React from 'react'
import Input from '@/app/components/base/input'
import { InputNumber } from '@/app/components/base/input-number'
import {
NumberField,
NumberFieldControls,
NumberFieldDecrement,
NumberFieldGroup,
NumberFieldIncrement,
NumberFieldInput,
} from '@/app/components/base/ui/number-field'
import { cn } from '@/utils/classnames'
import Datepicker from '../base/date-picker'
import { DataType } from '../types'
@ -36,15 +43,23 @@ const InputCombined: FC<Props> = ({
if (type === DataType.number) {
return (
<div className="grow text-[0]">
<InputNumber
className={cn(className, 'rounded-l-md')}
<NumberField
className="min-w-0"
value={value}
onChange={onChange}
size="regular"
controlWrapClassName="overflow-hidden"
controlClassName="pt-0 pb-0"
readOnly={readOnly}
/>
onValueChange={value => onChange(value ?? 0)}
>
<NumberFieldGroup size="regular">
<NumberFieldInput
size="regular"
className={cn(className, 'rounded-l-md')}
/>
<NumberFieldControls className="overflow-hidden">
<NumberFieldIncrement size="regular" className="pb-0 pt-0" />
<NumberFieldDecrement size="regular" className="pb-0 pt-0" />
</NumberFieldControls>
</NumberFieldGroup>
</NumberField>
</div>
)
}