Merge pull request #6968 from pooja-bruno/feat/env-var-search-ui-toggle

feat: add search functionality to environment variables. (#6659)
This commit is contained in:
Pooja
2026-01-30 17:52:05 +05:30
committed by GitHub
parent 5cdb8ae0a1
commit 017249e537
4 changed files with 108 additions and 55 deletions

View File

@@ -97,14 +97,14 @@ const StyledWrapper = styled.div`
align-items: center;
gap: 2px;
.search-container {
.search-input-wrapper {
position: relative;
top: 6px;
display: flex;
align-items: center;
.search-icon {
position: absolute;
left: 8px;
color: ${(props) => props.theme.colors.text.muted};
pointer-events: none;
}
@@ -132,7 +132,7 @@ const StyledWrapper = styled.div`
.clear-search {
position: absolute;
right: 8px;
right: 1px;
padding: 4px;
display: flex;
align-items: center;

View File

@@ -20,8 +20,10 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => {
const [newName, setNewName] = useState('');
const [nameError, setNameError] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const [isSearchExpanded, setIsSearchExpanded] = useState(false);
const debouncedSearchQuery = useDebounce(searchQuery, 300);
const inputRef = useRef(null);
const searchInputRef = useRef(null);
const validateEnvironmentName = (name) => {
if (!name || name.trim() === '') {
@@ -114,6 +116,23 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => {
}
};
const handleSearchIconClick = () => {
setIsSearchExpanded(true);
setTimeout(() => {
searchInputRef.current?.focus();
}, 50);
};
const handleClearSearch = () => {
setSearchQuery('');
};
const handleSearchBlur = () => {
if (searchQuery === '') {
setIsSearchExpanded(false);
}
};
return (
<StyledWrapper>
{openDeleteModal && (
@@ -165,29 +184,38 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => {
</div>
{nameError && isRenaming && <div className="title-error">{nameError}</div>}
<div className="actions">
<div className="search-container">
<IconSearch size={14} strokeWidth={1.5} className="search-icon" />
<input
type="text"
placeholder="Search variables..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
title="Clear search"
>
<IconX size={14} strokeWidth={1.5} />
</button>
)}
</div>
{isSearchExpanded ? (
<div className="search-input-wrapper">
<IconSearch size={14} strokeWidth={1.5} className="search-icon" />
<input
ref={searchInputRef}
type="text"
placeholder="Search variables..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onBlur={handleSearchBlur}
className="search-input"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
/>
{searchQuery && (
<button
className="clear-search"
onClick={handleClearSearch}
onMouseDown={(e) => e.preventDefault()}
title="Clear search"
>
<IconX size={14} strokeWidth={1.5} />
</button>
)}
</div>
) : (
<button onClick={handleSearchIconClick} title="Search variables">
<IconSearch size={15} strokeWidth={1.5} />
</button>
)}
<button onClick={handleRenameClick} title="Rename">
<IconEdit size={15} strokeWidth={1.5} />
</button>

View File

@@ -97,17 +97,14 @@ const StyledWrapper = styled.div`
align-items: center;
gap: 2px;
.search-container {
.search-input-wrapper {
position: relative;
top: 6px;
display: flex;
align-items: center;
// margin-right: 8px;
// margin-top: 8px;
.search-icon {
position: absolute;
// left: 10px;
left: 8px;
color: ${(props) => props.theme.colors.text.muted};
pointer-events: none;
}
@@ -135,7 +132,7 @@ const StyledWrapper = styled.div`
.clear-search {
position: absolute;
right: 8px;
right: 1px;
padding: 4px;
display: flex;
align-items: center;

View File

@@ -20,8 +20,10 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => {
const [newName, setNewName] = useState('');
const [nameError, setNameError] = useState('');
const [searchQuery, setSearchQuery] = useState('');
const [isSearchExpanded, setIsSearchExpanded] = useState(false);
const debouncedSearchQuery = useDebounce(searchQuery, 300);
const inputRef = useRef(null);
const searchInputRef = useRef(null);
const validateEnvironmentName = (name) => {
if (!name || name.trim() === '') {
@@ -113,6 +115,23 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => {
}
};
const handleSearchIconClick = () => {
setIsSearchExpanded(true);
setTimeout(() => {
searchInputRef.current?.focus();
}, 50);
};
const handleClearSearch = () => {
setSearchQuery('');
};
const handleSearchBlur = () => {
if (searchQuery === '') {
setIsSearchExpanded(false);
}
};
return (
<StyledWrapper>
{openDeleteModal && (
@@ -167,29 +186,38 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => {
</div>
{nameError && isRenaming && <div className="title-error">{nameError}</div>}
<div className="actions">
<div className="search-container">
<IconSearch size={14} strokeWidth={1.5} className="search-icon" />
<input
type="text"
placeholder="Search variables..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="search-input"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
/>
{searchQuery && (
<button
className="clear-search"
onClick={() => setSearchQuery('')}
title="Clear search"
>
<IconX size={14} strokeWidth={1.5} />
</button>
)}
</div>
{isSearchExpanded ? (
<div className="search-input-wrapper">
<IconSearch size={14} strokeWidth={1.5} className="search-icon" />
<input
ref={searchInputRef}
type="text"
placeholder="Search variables..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
onBlur={handleSearchBlur}
className="search-input"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
/>
{searchQuery && (
<button
className="clear-search"
onClick={handleClearSearch}
onMouseDown={(e) => e.preventDefault()}
title="Clear search"
>
<IconX size={14} strokeWidth={1.5} />
</button>
)}
</div>
) : (
<button onClick={handleSearchIconClick} title="Search variables">
<IconSearch size={15} strokeWidth={1.5} />
</button>
)}
<button onClick={handleRenameClick} title="Rename">
<IconEdit size={15} strokeWidth={1.5} />
</button>