mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 08:33:20 +00:00
(feat/search): redirect to sources
This commit is contained in:
@@ -39,9 +39,9 @@ const Main = styled.div`
|
|||||||
|
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
`
|
`
|
||||||
const TextField = styled.input<{inputWidth:string}>`
|
const TextField = styled.input<{ inputWidth: string }>`
|
||||||
padding: 6px 6px;
|
padding: 6px 6px;
|
||||||
width: ${({inputWidth}) => inputWidth};
|
width: ${({ inputWidth }) => inputWidth};
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: inline;
|
display: inline;
|
||||||
color: ${props => props.theme.primary.text};
|
color: ${props => props.theme.primary.text};
|
||||||
@@ -67,7 +67,7 @@ const SearchResults = styled.div`
|
|||||||
opacity: 90%;
|
opacity: 90%;
|
||||||
border: 1px solid rgba(0, 0, 0, .1);
|
border: 1px solid rgba(0, 0, 0, .1);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 15px;
|
padding: 8px;
|
||||||
width: 576px;
|
width: 576px;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
height: 25vh;
|
height: 25vh;
|
||||||
@@ -87,7 +87,8 @@ const SearchResults = styled.div`
|
|||||||
`
|
`
|
||||||
const Title = styled.h3`
|
const Title = styled.h3`
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: rgb(107, 114, 128);
|
color: ${props => props.theme.primary.text};
|
||||||
|
opacity: 0.8;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -96,6 +97,17 @@ const Title = styled.h3`
|
|||||||
const Content = styled.div`
|
const Content = styled.div`
|
||||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
`
|
`
|
||||||
|
const ResultWrapper = styled.div`
|
||||||
|
padding: 4px 8px 4px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
&.contains-source:hover{
|
||||||
|
background-color: rgba(0, 92, 197, 0.15);
|
||||||
|
${Title} {
|
||||||
|
color: rgb(0, 126, 230);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
const Markdown = styled.div`
|
const Markdown = styled.div`
|
||||||
line-height:20px;
|
line-height:20px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -112,7 +124,8 @@ font-size: 12px;
|
|||||||
h1,h2 {
|
h1,h2 {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: rgb(31, 41, 55);
|
color: ${(props) => props.theme.text};
|
||||||
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -150,17 +163,18 @@ const Toolkit = styled.kbd`
|
|||||||
top: 4px;
|
top: 4px;
|
||||||
background-color: ${(props) => props.theme.primary.bg};
|
background-color: ${(props) => props.theme.primary.bg};
|
||||||
color: ${(props) => props.theme.secondary.text};
|
color: ${(props) => props.theme.secondary.text};
|
||||||
|
font-weight: 600;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
border: 1px solid ${(props) => props.theme.secondary.text};
|
border: 1px solid ${(props) => props.theme.secondary.text};
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
`
|
`
|
||||||
export const SearchBar = ({
|
export const SearchBar = ({
|
||||||
apiKey = "79bcbf0e-3dd1-4ac3-b893-e41b3d40ec8d",
|
apiKey = "74039c6d-bff7-44ce-ae55-2973cbf13837",
|
||||||
apiHost = "http://127.0.0.1:7091",
|
apiHost = "https://gptcloud.arc53.com",
|
||||||
theme = "dark",
|
theme = "dark",
|
||||||
placeholder = "Search or Ask AI...",
|
placeholder = "Search or Ask AI...",
|
||||||
width="240px"
|
width = "240px"
|
||||||
}: SearchBarProps) => {
|
}: SearchBarProps) => {
|
||||||
const [input, setInput] = React.useState<string>("");
|
const [input, setInput] = React.useState<string>("");
|
||||||
const [isWidgetOpen, setIsWidgetOpen] = React.useState<boolean>(false);
|
const [isWidgetOpen, setIsWidgetOpen] = React.useState<boolean>(false);
|
||||||
@@ -193,8 +207,8 @@ export const SearchBar = ({
|
|||||||
}, [input])
|
}, [input])
|
||||||
|
|
||||||
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
event.preventDefault();
|
if (event.ctrlKey && event.key === 'k') {
|
||||||
if (event.ctrlKey && event.key === 'k'){
|
event.preventDefault();
|
||||||
setIsWidgetOpen(true);
|
setIsWidgetOpen(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -208,7 +222,7 @@ export const SearchBar = ({
|
|||||||
<Container>
|
<Container>
|
||||||
<TextField
|
<TextField
|
||||||
inputWidth={width}
|
inputWidth={width}
|
||||||
onFocus={()=>setIsResultVisible(true)}
|
onFocus={() => setIsResultVisible(true)}
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
onKeyDown={(e) => handleKeyDown(e)}
|
onKeyDown={(e) => handleKeyDown(e)}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
@@ -218,16 +232,24 @@ export const SearchBar = ({
|
|||||||
{
|
{
|
||||||
input.length > 0 && results.length > 0 && isResultVisible && (
|
input.length > 0 && results.length > 0 && isResultVisible && (
|
||||||
<SearchResults ref={resultsRef}>
|
<SearchResults ref={resultsRef}>
|
||||||
{results.map((res) => (
|
{results.map((res) => {
|
||||||
<div>
|
const containsSource = res.source !== 'local'
|
||||||
<Title>{res.title}</Title>
|
return (
|
||||||
<Content>
|
<ResultWrapper
|
||||||
<Markdown
|
onClick={() => {
|
||||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(md.render(res.text)) }}
|
if (!containsSource) return;
|
||||||
/>
|
window.open(res.source, '_blank', 'noopener, noreferrer')
|
||||||
</Content>
|
}}
|
||||||
</div>
|
className={containsSource ? "contains-source" : ""}>
|
||||||
))
|
<Title>{res.title}</Title>
|
||||||
|
<Content>
|
||||||
|
<Markdown
|
||||||
|
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(md.render((res.text + "...").substring(0, 256) + "...")) }}
|
||||||
|
/>
|
||||||
|
</Content>
|
||||||
|
</ResultWrapper>
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</SearchResults>
|
</SearchResults>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -51,5 +51,6 @@ export interface SearchBarProps {
|
|||||||
|
|
||||||
export interface Result {
|
export interface Result {
|
||||||
text:string;
|
text:string;
|
||||||
title:string
|
title:string;
|
||||||
|
source:string;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user