From 4d61ecacb30162148976d8bc70ffe57c4486d039 Mon Sep 17 00:00:00 2001 From: Pragadesh-45 <54320162+Pragadesh-45@users.noreply.github.com> Date: Thu, 26 Feb 2026 12:27:03 +0530 Subject: [PATCH] Fix Environment Search Behavior, UI Updates, and Result Handling (#7287) --- .../StyledWrapper.js | 30 ++ .../EnvironmentVariablesTable/index.js | 278 ++++++++++-------- .../CollapsibleSection/StyledWrapper.js | 1 + .../EnvironmentDetails/index.js | 7 +- .../EnvironmentList/StyledWrapper.js | 60 ++-- .../EnvironmentList/index.js | 66 ++++- .../EnvironmentDetails/index.js | 7 +- .../EnvironmentList/StyledWrapper.js | 61 ++-- .../EnvironmentList/index.js | 66 ++++- .../src/providers/ReduxStore/slices/app.js | 18 +- 10 files changed, 379 insertions(+), 215 deletions(-) diff --git a/packages/bruno-app/src/components/EnvironmentVariablesTable/StyledWrapper.js b/packages/bruno-app/src/components/EnvironmentVariablesTable/StyledWrapper.js index dafdae4d8..c0fde00ec 100644 --- a/packages/bruno-app/src/components/EnvironmentVariablesTable/StyledWrapper.js +++ b/packages/bruno-app/src/components/EnvironmentVariablesTable/StyledWrapper.js @@ -96,6 +96,36 @@ const Wrapper = styled.div` max-width: 200px !important; } + .name-cell-wrapper { + position: relative; + width: 100%; + + .name-highlight-overlay { + position: absolute; + inset: 0; + pointer-events: none; + white-space: pre; + overflow: hidden; + font-size: inherit; + line-height: inherit; + color: ${(props) => props.theme.text}; + } + } + + .search-highlight { + background: ${(props) => props.theme.colors.accent}55; + color: inherit; + border-radius: 2px; + padding: 0 1px; + } + + .no-results { + padding: 24px; + text-align: center; + font-size: ${(props) => props.theme.font.size.sm}; + color: ${(props) => props.theme.colors.text.muted}; + } + input[type='text'] { width: 100%; border: 1px solid transparent; diff --git a/packages/bruno-app/src/components/EnvironmentVariablesTable/index.js b/packages/bruno-app/src/components/EnvironmentVariablesTable/index.js index c1f05712a..cd216e8f0 100644 --- a/packages/bruno-app/src/components/EnvironmentVariablesTable/index.js +++ b/packages/bruno-app/src/components/EnvironmentVariablesTable/index.js @@ -31,6 +31,15 @@ const TableRow = React.memo( } ); +const highlightText = (text, query) => { + if (!query?.trim() || !text) return text; + const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi'); + const parts = text.split(regex); + return parts.map((part, i) => + regex.test(part) ? {part} : part + ); +}; + const EnvironmentVariablesTable = ({ environment, collection, @@ -42,7 +51,8 @@ const EnvironmentVariablesTable = ({ renderExtraValueContent, searchQuery = '' }) => { - const { storedTheme } = useTheme(); + const { storedTheme, theme } = useTheme(); + const valueMatchBg = theme?.colors?.accent ? `${theme.colors.accent}1a` : undefined; const { globalEnvironments, activeGlobalEnvironmentUid } = useSelector((state) => state.globalEnvironments); const hasDraftForThisEnv = draft?.environmentUid === environment.uid; @@ -50,6 +60,7 @@ const EnvironmentVariablesTable = ({ const [tableHeight, setTableHeight] = useState(MIN_H); const [columnWidths, setColumnWidths] = useState({ name: '30%', value: 'auto' }); const [resizing, setResizing] = useState(null); + const [focusedNameIndex, setFocusedNameIndex] = useState(null); const handleResizeStart = useCallback((e, columnKey) => { e.preventDefault(); @@ -407,139 +418,160 @@ const EnvironmentVariablesTable = ({ const query = searchQuery.toLowerCase().trim(); - return allVariables.filter(({ variable, index }) => { - const isLastRow = index === formik.values.length - 1; - const isEmptyRow = !variable.name || variable.name.trim() === ''; - if (isLastRow && isEmptyRow) { - return true; - } - + return allVariables.filter(({ variable }) => { const nameMatch = variable.name ? variable.name.toLowerCase().includes(query) : false; const valueMatch = typeof variable.value === 'string' ? variable.value.toLowerCase().includes(query) : false; - return !!(nameMatch || valueMatch); }); }, [formik.values, searchQuery]); + const isSearchActive = !!searchQuery?.trim(); + return ( - ( - - - - Name -
0 ? `${tableHeight}px` : undefined }} - onMouseDown={(e) => handleResizeStart(e, 'name')} - /> - - Value - Secret - - - )} - fixedItemHeight={35} - computeItemKey={(virtualIndex, item) => `${environment.uid}-${item.index}`} - itemContent={(virtualIndex, { variable, index: actualIndex }) => { - const isLastRow = actualIndex === formik.values.length - 1; - const isEmptyRow = !variable.name || variable.name.trim() === ''; - const isLastEmptyRow = isLastRow && isEmptyRow; - - return ( - <> - - {!isLastEmptyRow && ( - - )} - + {isSearchActive && filteredVariables.length === 0 ? ( +
No results found for “{searchQuery.trim()}”
+ ) : ( + ( + + -
- handleNameChange(actualIndex, e)} - onBlur={() => handleNameBlur(actualIndex)} - onKeyDown={(e) => handleNameKeyDown(actualIndex, e)} - /> - -
+ Name +
0 ? `${tableHeight}px` : undefined }} + onMouseDown={(e) => handleResizeStart(e, 'name')} + /> - -
- { - formik.setFieldValue(`${actualIndex}.value`, newValue, true); - // Clear ephemeral metadata when user manually edits the value - if (variable.ephemeral) { - formik.setFieldValue(`${actualIndex}.ephemeral`, undefined, false); - formik.setFieldValue(`${actualIndex}.persistedValue`, undefined, false); - } - }} - onSave={handleSave} - /> -
- {typeof variable.value !== 'string' && ( - - - Value + Secret + + + )} + fixedItemHeight={35} + computeItemKey={(virtualIndex, item) => `${environment.uid}-${item.index}`} + itemContent={(virtualIndex, { variable, index: actualIndex }) => { + const isLastRow = actualIndex === formik.values.length - 1; + const isEmptyRow = !variable.name || variable.name.trim() === ''; + const isLastEmptyRow = isLastRow && isEmptyRow; + const activeQuery = searchQuery?.trim().toLowerCase(); + const valueMatchesOnly = activeQuery + && !(variable.name?.toLowerCase().includes(activeQuery)) + && typeof variable.value === 'string' + && variable.value.toLowerCase().includes(activeQuery); + + return ( + <> + + {!isLastEmptyRow && ( + - - )} - {renderExtraValueContent && renderExtraValueContent(variable)} - - - {!isLastEmptyRow && ( - - )} - - - {!isLastEmptyRow && ( - - )} - - - ); - }} - /> + )} + + +
+
+ handleNameChange(actualIndex, e)} + onFocus={() => !isSearchActive && setFocusedNameIndex(actualIndex)} + onBlur={() => { + setFocusedNameIndex(null); if (!isSearchActive) handleNameBlur(actualIndex); + }} + onKeyDown={isSearchActive ? undefined : (e) => handleNameKeyDown(actualIndex, e)} + style={searchQuery?.trim() && focusedNameIndex !== actualIndex ? { color: 'transparent' } : undefined} + /> + {searchQuery?.trim() && focusedNameIndex !== actualIndex && ( +
+ {highlightText(variable.name || '', searchQuery)} +
+ )} +
+ +
+ + +
+ { + formik.setFieldValue(`${actualIndex}.value`, newValue, true); + // Clear ephemeral metadata when user manually edits the value + if (variable.ephemeral) { + formik.setFieldValue(`${actualIndex}.ephemeral`, undefined, false); + formik.setFieldValue(`${actualIndex}.persistedValue`, undefined, false); + } + }} + onSave={handleSave} + /> +
+ {typeof variable.value !== 'string' && ( + + + + + )} + {renderExtraValueContent && renderExtraValueContent(variable)} + + + {!isLastEmptyRow && ( + + )} + + + {!isLastEmptyRow && ( + + )} + + + ); + }} + /> + )}
diff --git a/packages/bruno-app/src/components/Environments/CollapsibleSection/StyledWrapper.js b/packages/bruno-app/src/components/Environments/CollapsibleSection/StyledWrapper.js index a16375965..57bec15a3 100644 --- a/packages/bruno-app/src/components/Environments/CollapsibleSection/StyledWrapper.js +++ b/packages/bruno-app/src/components/Environments/CollapsibleSection/StyledWrapper.js @@ -55,6 +55,7 @@ const StyledWrapper = styled.div` } .section-title { + padding-right: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; diff --git a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/index.js b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/index.js index 2a7f5ea56..d6cca70c9 100644 --- a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/index.js +++ b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/index.js @@ -1,7 +1,6 @@ import { IconCopy, IconEdit, IconTrash, IconCheck, IconX, IconSearch } from '@tabler/icons'; import { useState, useRef } from 'react'; import { useDispatch } from 'react-redux'; -import useDebounce from 'hooks/useDebounce'; import { renameEnvironment, updateEnvironmentColor } from 'providers/ReduxStore/slices/collections/actions'; import { validateName, validateNameError } from 'utils/common/regex'; import toast from 'react-hot-toast'; @@ -11,7 +10,7 @@ import EnvironmentVariables from './EnvironmentVariables'; import ColorPicker from 'components/ColorPicker'; import StyledWrapper from './StyledWrapper'; -const EnvironmentDetails = ({ environment, setIsModified, collection }) => { +const EnvironmentDetails = ({ environment, setIsModified, collection, searchQuery, setSearchQuery, isSearchExpanded, setIsSearchExpanded, debouncedSearchQuery, searchInputRef }) => { const dispatch = useDispatch(); const environments = collection?.environments || []; @@ -20,11 +19,7 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => { const [isRenaming, setIsRenaming] = useState(false); 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() === '') { diff --git a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/StyledWrapper.js b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/StyledWrapper.js index 4dc305394..87ba75d63 100644 --- a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/StyledWrapper.js +++ b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/StyledWrapper.js @@ -32,19 +32,6 @@ const StyledWrapper = styled.div` flex-direction: column; } - .sidebar-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 16px 16px 12px 16px; - - .title { - font-size: ${(props) => props.theme.font.size.base}; - font-weight: 500; - color: ${(props) => props.theme.text}; - margin: 0; - } - .btn-action { display: flex; align-items: center; @@ -66,35 +53,54 @@ const StyledWrapper = styled.div` } } - .search-container { + .env-list-search { position: relative; - padding: 0 12px 12px 12px; - - .search-icon { + display: flex; + align-items: center; + margin: 0 4px 6px 4px; + + .env-list-search-icon { position: absolute; - left: 20px; - top: 50%; - transform: translateY(-100%); + left: 8px; color: ${(props) => props.theme.colors.text.muted}; pointer-events: none; } - - .search-input { + + .env-list-search-input { width: 100%; - padding: 6px 8px 6px 28px; + padding: 5px 24px 5px 26px; font-size: 12px; background: transparent; border: 1px solid ${(props) => props.theme.border.border1}; border-radius: 5px; color: ${(props) => props.theme.text}; - transition: all 0.15s ease; - + transition: border-color 0.15s ease; + &::placeholder { color: ${(props) => props.theme.colors.text.muted}; } &:focus { outline: none; + border-color: ${(props) => props.theme.colors.accent}; + } + } + + .env-list-search-clear { + position: absolute; + right: 4px; + display: flex; + align-items: center; + justify-content: center; + padding: 2px; + background: transparent; + border: none; + cursor: pointer; + color: ${(props) => props.theme.colors.text.muted}; + border-radius: 3px; + + &:hover { + color: ${(props) => props.theme.text}; } } } @@ -130,6 +136,10 @@ const StyledWrapper = styled.div` background: ${(props) => props.theme.sidebar.collection.item.hoverBg}; color: ${(props) => props.theme.text}; } + + &.active { + color: ${(props) => props.theme.colors.accent}; + } } .environment-item { diff --git a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/index.js b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/index.js index 4c2b2d07e..231ceee25 100644 --- a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/index.js +++ b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/index.js @@ -1,6 +1,7 @@ import React, { useEffect, useState, useRef, useCallback } from 'react'; import usePrevious from 'hooks/usePrevious'; import useOnClickOutside from 'hooks/useOnClickOutside'; +import useDebounce from 'hooks/useDebounce'; import EnvironmentDetails from './EnvironmentDetails'; import { IconDownload, IconUpload, IconSearch, IconPlus, IconCheck, IconX, IconFileAlert } from '@tabler/icons'; import Button from 'ui/Button'; @@ -23,6 +24,7 @@ import { deleteDotEnvFile } from 'providers/ReduxStore/slices/collections/actions'; import { setEnvironmentsDraft, clearEnvironmentsDraft } from 'providers/ReduxStore/slices/collections'; +import { setEnvVarSearchQuery, setEnvVarSearchExpanded } from 'providers/ReduxStore/slices/app'; import { validateName, validateNameError } from 'utils/common/regex'; import toast from 'react-hot-toast'; import classnames from 'classnames'; @@ -40,9 +42,15 @@ const EnvironmentList = ({ setShowExportModal }) => { const dispatch = useDispatch(); + const envSearchQuery = useSelector((state) => state.app.envVarSearch?.collection?.query ?? ''); + const isEnvSearchExpanded = useSelector((state) => state.app.envVarSearch?.collection?.expanded ?? false); + const setEnvSearchQuery = (q) => dispatch(setEnvVarSearchQuery({ context: 'collection', query: q })); + const setIsEnvSearchExpanded = (v) => dispatch(setEnvVarSearchExpanded({ context: 'collection', expanded: v })); const [openImportModal, setOpenImportModal] = useState(false); const [searchText, setSearchText] = useState(''); + const [isEnvListSearchExpanded, setIsEnvListSearchExpanded] = useState(false); + const envListSearchInputRef = useRef(null); const [isCreatingInline, setIsCreatingInline] = useState(false); const [renamingEnvUid, setRenamingEnvUid] = useState(null); const [newEnvName, setNewEnvName] = useState(''); @@ -65,6 +73,9 @@ const EnvironmentList = ({ const dotEnvInputRef = useRef(null); const dotEnvCreateContainerRef = useRef(null); + const debouncedEnvSearchQuery = useDebounce(envSearchQuery, 300); + const envSearchInputRef = useRef(null); + const dotEnvFiles = useSelector((state) => { const coll = state.collections.collections.find((c) => c.uid === collection?.uid); return coll?.dotEnvFiles || EMPTY_ARRAY; @@ -497,6 +508,12 @@ const EnvironmentList = ({ setIsModified={setIsModified} originalEnvironmentVariables={originalEnvironmentVariables} collection={collection} + searchQuery={envSearchQuery} + setSearchQuery={setEnvSearchQuery} + isSearchExpanded={isEnvSearchExpanded} + setIsSearchExpanded={setIsEnvSearchExpanded} + debouncedSearchQuery={debouncedEnvSearchQuery} + searchInputRef={envSearchInputRef} /> ); } @@ -531,20 +548,6 @@ const EnvironmentList = ({ )}
-
-

Variables

-
- -
- - setSearchText(e.target.value)} - className="search-input" - /> -
setEnvironmentsExpanded(!environmentsExpanded)} actions={( <> + @@ -565,6 +581,28 @@ const EnvironmentList = ({ )} > + {isEnvListSearchExpanded && ( +
+ + setSearchText(e.target.value)} + className="env-list-search-input" + autoComplete="off" + autoCorrect="off" + autoCapitalize="off" + spellCheck="false" + /> + {searchText && ( + + )} +
+ )}
{filteredEnvironments.map((env) => (
{ +const EnvironmentDetails = ({ environment, setIsModified, collection, searchQuery, setSearchQuery, isSearchExpanded, setIsSearchExpanded, debouncedSearchQuery, searchInputRef }) => { const dispatch = useDispatch(); const globalEnvs = useSelector((state) => state?.globalEnvironments?.globalEnvironments); @@ -20,11 +19,7 @@ const EnvironmentDetails = ({ environment, setIsModified, collection }) => { const [isRenaming, setIsRenaming] = useState(false); 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() === '') { diff --git a/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/StyledWrapper.js b/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/StyledWrapper.js index c36d77868..52f9f2f60 100644 --- a/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/StyledWrapper.js +++ b/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/StyledWrapper.js @@ -32,19 +32,7 @@ const StyledWrapper = styled.div` flex-direction: column; } - .sidebar-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 16px 16px 12px 16px; - - .title { - font-size: ${(props) => props.theme.font.size.base}; - font-weight: 500; - color: ${(props) => props.theme.text}; - margin: 0; - } - + .btn-action { display: flex; align-items: center; @@ -66,35 +54,54 @@ const StyledWrapper = styled.div` } } - .search-container { + .env-list-search { position: relative; - padding: 0 12px 12px 12px; - - .search-icon { + display: flex; + align-items: center; + margin: 0 4px 6px 4px; + + .env-list-search-icon { position: absolute; - left: 20px; - top: 50%; - transform: translateY(-100%); + left: 8px; color: ${(props) => props.theme.colors.text.muted}; pointer-events: none; } - - .search-input { + + .env-list-search-input { width: 100%; - padding: 6px 8px 6px 28px; + padding: 5px 24px 5px 26px; font-size: 12px; background: transparent; border: 1px solid ${(props) => props.theme.border.border1}; border-radius: 5px; color: ${(props) => props.theme.text}; - transition: all 0.15s ease; - + transition: border-color 0.15s ease; + &::placeholder { color: ${(props) => props.theme.colors.text.muted}; } &:focus { outline: none; + border-color: ${(props) => props.theme.colors.accent}; + } + } + + .env-list-search-clear { + position: absolute; + right: 4px; + display: flex; + align-items: center; + justify-content: center; + padding: 2px; + background: transparent; + border: none; + cursor: pointer; + color: ${(props) => props.theme.colors.text.muted}; + border-radius: 3px; + + &:hover { + color: ${(props) => props.theme.text}; } } } @@ -130,6 +137,10 @@ const StyledWrapper = styled.div` background: ${(props) => props.theme.sidebar.collection.item.hoverBg}; color: ${(props) => props.theme.text}; } + + &.active { + color: ${(props) => props.theme.colors.accent}; + } } .environment-item { diff --git a/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/index.js b/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/index.js index d514aa1f5..47db76f4e 100644 --- a/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/index.js +++ b/packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/index.js @@ -1,6 +1,7 @@ import React, { useEffect, useState, useRef, useCallback } from 'react'; import usePrevious from 'hooks/usePrevious'; import useOnClickOutside from 'hooks/useOnClickOutside'; +import useDebounce from 'hooks/useDebounce'; import EnvironmentDetails from './EnvironmentDetails'; import { IconDownload, IconUpload, IconSearch, IconPlus, IconCheck, IconX, IconFileAlert } from '@tabler/icons'; import Button from 'ui/Button'; @@ -20,6 +21,7 @@ import { createWorkspaceDotEnvFile, deleteWorkspaceDotEnvFile } from 'providers/ReduxStore/slices/workspaces/actions'; +import { setEnvVarSearchQuery, setEnvVarSearchExpanded } from 'providers/ReduxStore/slices/app'; import { validateName, validateNameError } from 'utils/common/regex'; import toast from 'react-hot-toast'; import classnames from 'classnames'; @@ -39,9 +41,15 @@ const EnvironmentList = ({ }) => { const dispatch = useDispatch(); const globalEnvs = useSelector((state) => state?.globalEnvironments?.globalEnvironments); + const envSearchQuery = useSelector((state) => state.app.envVarSearch?.global?.query ?? ''); + const isEnvSearchExpanded = useSelector((state) => state.app.envVarSearch?.global?.expanded ?? false); + const setEnvSearchQuery = (q) => dispatch(setEnvVarSearchQuery({ context: 'global', query: q })); + const setIsEnvSearchExpanded = (v) => dispatch(setEnvVarSearchExpanded({ context: 'global', expanded: v })); const [openImportModal, setOpenImportModal] = useState(false); const [searchText, setSearchText] = useState(''); + const [isEnvListSearchExpanded, setIsEnvListSearchExpanded] = useState(false); + const envListSearchInputRef = useRef(null); const [isCreatingInline, setIsCreatingInline] = useState(false); const [renamingEnvUid, setRenamingEnvUid] = useState(null); const [newEnvName, setNewEnvName] = useState(''); @@ -64,6 +72,9 @@ const EnvironmentList = ({ const dotEnvInputRef = useRef(null); const dotEnvCreateContainerRef = useRef(null); + const debouncedEnvSearchQuery = useDebounce(envSearchQuery, 300); + const envSearchInputRef = useRef(null); + const dotEnvFiles = useSelector((state) => { const ws = state.workspaces.workspaces.find((w) => w.uid === workspace?.uid); return ws?.dotEnvFiles || EMPTY_ARRAY; @@ -493,6 +504,12 @@ const EnvironmentList = ({ setIsModified={setIsModified} originalEnvironmentVariables={originalEnvironmentVariables} collection={collection} + searchQuery={envSearchQuery} + setSearchQuery={setEnvSearchQuery} + isSearchExpanded={isEnvSearchExpanded} + setIsSearchExpanded={setIsEnvSearchExpanded} + debouncedSearchQuery={debouncedEnvSearchQuery} + searchInputRef={envSearchInputRef} /> ); } @@ -525,20 +542,6 @@ const EnvironmentList = ({ )}
-
-

Variables

-
- -
- - setSearchText(e.target.value)} - className="search-input" - /> -
setEnvironmentsExpanded(!environmentsExpanded)} actions={( <> + @@ -559,6 +575,28 @@ const EnvironmentList = ({ )} > + {isEnvListSearchExpanded && ( +
+ + setSearchText(e.target.value)} + className="env-list-search-input" + autoComplete="off" + autoCorrect="off" + autoCapitalize="off" + spellCheck="false" + /> + {searchText && ( + + )} +
+ )}
{filteredEnvironments.map((env) => (
{ // Update clipboard UI state state.clipboard.hasCopiedItems = action.payload.hasCopiedItems; + }, + setEnvVarSearchQuery: (state, { payload: { context, query } }) => { + if (!state.envVarSearch[context]) return; + state.envVarSearch[context].query = query; + }, + setEnvVarSearchExpanded: (state, { payload: { context, expanded } }) => { + if (!state.envVarSearch[context]) return; + state.envVarSearch[context].expanded = expanded; } }, extraReducers: (builder) => { @@ -182,7 +194,9 @@ export const { updateGitOperationProgress, removeGitOperationProgress, setGitVersion, - setClipboard + setClipboard, + setEnvVarSearchQuery, + setEnvVarSearchExpanded } = appSlice.actions; export const savePreferences = (preferences) => (dispatch, getState) => {