Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions packages/ui/src/ui-component/input/Input.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useState, useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import { FormControl, OutlinedInput, InputBase, Popover } from '@mui/material'
import { FormControl, OutlinedInput, InputBase, Popover, InputAdornment, IconButton } from '@mui/material'
import { useTheme } from '@mui/material/styles'
import Visibility from '@mui/icons-material/Visibility'
import VisibilityOff from '@mui/icons-material/VisibilityOff'
import SelectVariable from '@/ui-component/json/SelectVariable'
import { getAvailableNodesForVariable } from '@/utils/genericHelper'

Expand All @@ -10,7 +12,13 @@ export const Input = ({ inputParam, value, nodes, edges, nodeId, onChange, onBlu
const [myValue, setMyValue] = useState(value ?? '')
const [anchorEl, setAnchorEl] = useState(null)
const [availableNodesForVariable, setAvailableNodesForVariable] = useState([])
const [isPasswordVisible, setIsPasswordVisible] = useState(false)
const ref = useRef(null)
const inputElementRef = useRef(null)
const selectionRangeRef = useRef({ start: null, end: null })

const isPasswordField = inputParam?.type === 'password'
const hasPasswordToggle = isPasswordField && !!inputParam?.enablePasswordToggle

const openPopOver = Boolean(anchorEl)

Expand Down Expand Up @@ -52,6 +60,28 @@ export const Input = ({ inputParam, value, nodes, edges, nodeId, onChange, onBlu
}
}, [myValue])

useEffect(() => {
if (!hasPasswordToggle) return
const { start, end } = selectionRangeRef.current
if (start === null || end === null || !inputElementRef.current) return

requestAnimationFrame(() => {
inputElementRef.current?.focus()
inputElementRef.current?.setSelectionRange(start, end)
})
}, [hasPasswordToggle, isPasswordVisible])

const handleTogglePasswordVisibility = () => {
const inputElement = inputElementRef.current
if (inputElement) {
selectionRangeRef.current = {
start: inputElement.selectionStart,
end: inputElement.selectionEnd
}
}
setIsPasswordVisible((prev) => !prev)
}

return (
<>
{inputParam.name === 'note' ? (
Expand Down Expand Up @@ -99,12 +129,13 @@ export const Input = ({ inputParam, value, nodes, edges, nodeId, onChange, onBlu
id={inputParam.name}
size='small'
disabled={disabled}
type={getInputType(inputParam.type)}
type={hasPasswordToggle ? (isPasswordVisible ? 'text' : 'password') : getInputType(inputParam.type)}
placeholder={inputParam.placeholder}
multiline={!!inputParam.rows}
rows={inputParam.rows ?? 1}
value={myValue}
name={inputParam.name}
inputRef={inputElementRef}
onChange={(e) => {
setMyValue(e.target.value)
onChange(e.target.value)
Expand All @@ -118,6 +149,20 @@ export const Input = ({ inputParam, value, nodes, edges, nodeId, onChange, onBlu
height: inputParam.rows ? '90px' : 'inherit'
}
}}
endAdornment={
hasPasswordToggle ? (
<InputAdornment position='end'>
<IconButton
edge='end'
onClick={handleTogglePasswordVisibility}
onMouseDown={(e) => e.preventDefault()}
aria-label={isPasswordVisible ? 'Hide password' : 'Show password'}
>
{isPasswordVisible ? <VisibilityOff fontSize='small' /> : <Visibility fontSize='small' />}
</IconButton>
</InputAdornment>
) : undefined
}
sx={{
'& .MuiOutlinedInput-notchedOutline': {
borderColor: theme.palette.grey[900] + 25
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/views/auth/signIn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ const SignInPage = () => {
label: 'Password',
name: 'password',
type: 'password',
placeholder: '********'
placeholder: '********',
enablePasswordToggle: true
}
const [usernameVal, setUsernameVal] = useState('')
const [passwordVal, setPasswordVal] = useState('')
Expand Down
Loading