118 lines
3.7 KiB
TypeScript
Raw Normal View History

import { LoadingOutlined, SearchOutlined } from '@ant-design/icons';
import { SearchBar } from '@components';
import React, { useState } from 'react';
import { useDebounce } from 'react-use';
2025-01-29 20:42:01 -05:00
import styled from 'styled-components/macro';
import DomainSearchResultItem from '@app/domainV2/DomainSearchResultItem';
import { REDESIGN_COLORS } from '@app/entityV2/shared/constants';
import ClickOutside from '@app/shared/ClickOutside';
import { useEntityRegistry } from '@app/useEntityRegistry';
import { useGetAutoCompleteResultsQuery } from '@graphql/search.generated';
import { EntityType } from '@types';
2025-01-29 20:42:01 -05:00
const DomainSearchWrapper = styled.div`
flex-shrink: 0;
position: relative;
`;
const ResultsWrapper = styled.div`
background-color: white;
border-radius: 5px;
box-shadow:
0 3px 6px -4px rgb(0 0 0 / 12%),
0 6px 16px 0 rgb(0 0 0 / 8%),
0 9px 28px 8px rgb(0 0 0 / 5%);
2025-01-29 20:42:01 -05:00
padding: 8px;
position: absolute;
max-height: 210px;
overflow: auto;
2025-04-22 17:50:57 -04:00
width: calc(100% - 8px);
left: 4px;
2025-01-29 20:42:01 -05:00
top: 55px;
z-index: 1;
`;
const LoadingWrapper = styled(ResultsWrapper)`
display: flex;
justify-content: center;
padding: 16px 0;
font-size: 16px;
`;
const InputWrapper = styled.div`
padding: 12px;
`;
2025-01-29 20:42:01 -05:00
const SearchIcon = styled(SearchOutlined)`
color: ${REDESIGN_COLORS.TEXT_HEADING_SUB_LINK};
padding: 16px;
width: 100%;
font-size: 20px;
`;
type Props = {
isCollapsed?: boolean;
unhideSidebar?: () => void;
};
function DomainSearch({ isCollapsed, unhideSidebar }: Props) {
const [searchInput, setSearchInput] = useState('');
2025-01-29 20:42:01 -05:00
const [query, setQuery] = useState('');
const [isSearchBarFocused, setIsSearchBarFocused] = useState(false);
const entityRegistry = useEntityRegistry();
useDebounce(() => setQuery(searchInput), 200, [searchInput]);
2025-01-29 20:42:01 -05:00
const { data, loading } = useGetAutoCompleteResultsQuery({
variables: {
input: {
type: EntityType.Domain,
query,
},
},
skip: !query,
});
const entities = data?.autoComplete?.entities || [];
return (
<DomainSearchWrapper>
{isCollapsed && unhideSidebar ? (
<SearchIcon onClick={unhideSidebar} />
) : (
<ClickOutside onClickOutside={() => setIsSearchBarFocused(false)}>
<InputWrapper>
<SearchBar
placeholder="Search"
value={searchInput}
onChange={setSearchInput}
onFocus={() => setIsSearchBarFocused(true)}
/>
</InputWrapper>
2025-01-29 20:42:01 -05:00
{loading && isSearchBarFocused && (
<LoadingWrapper>
<LoadingOutlined />
</LoadingWrapper>
)}
{!loading && isSearchBarFocused && !!entities?.length && (
<ResultsWrapper>
{entities?.map((entity) => (
<DomainSearchResultItem
key={entity.urn}
entity={entity}
entityRegistry={entityRegistry}
query={query}
onResultClick={() => setIsSearchBarFocused(false)}
/>
))}
</ResultsWrapper>
)}
</ClickOutside>
)}
</DomainSearchWrapper>
);
}
export default DomainSearch;