Skip to content

Commit 4b007b1

Browse files
authored
Merge branch 'staging' into create-logs-and-secure-missing-variables
2 parents 873b54b + f4391bf commit 4b007b1

File tree

8 files changed

+177
-157
lines changed

8 files changed

+177
-157
lines changed

app/components/Input.tsx

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,25 @@ import { getCategoryColorName, getCategoryColorValue, Graph } from "./model"
33
import { useEffect, useRef, useState } from "react"
44
import { PathNode } from "../page"
55
import { cn } from "@/lib/utils"
6-
import twcolors from 'tailwindcss/colors'
7-
8-
let colors = twcolors as any
6+
import { prepareArg } from "../utils"
97

108
interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
119
value?: string
1210
graph: Graph
1311
onValueChange: (node: PathNode) => void
14-
handelSubmit?: (node: any) => void
12+
handleSubmit?: (node: any) => void
1513
icon?: React.ReactNode
1614
node?: PathNode
1715
parentClassName?: string
1816
scrollToBottom?: () => void
1917
}
2018

21-
export default function Input({ value, onValueChange, handelSubmit, graph, icon, node, className, parentClassName, scrollToBottom, ...props }: Props) {
19+
export default function Input({ value, onValueChange, handleSubmit, graph, icon, node, className, parentClassName, scrollToBottom, ...props }: Props) {
2220

2321
const [open, setOpen] = useState(false)
2422
const [options, setOptions] = useState<any[]>([])
2523
const [selectedOption, setSelectedOption] = useState<number>(0)
26-
const inputRef = useRef<HTMLInputElement>(null)
24+
const [inputHeight, setInputHeight] = useState(0)
2725
const containerRef = useRef<HTMLDivElement>(null)
2826

2927
useEffect(() => {
@@ -35,6 +33,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
3533
}, [open])
3634

3735
useEffect(() => {
36+
let isLastRequest = true
3837
const timeout = setTimeout(async () => {
3938

4039
if (!value || node?.id) {
@@ -45,7 +44,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
4544
return
4645
}
4746

48-
const result = await fetch(`/api/repo/${graph.Id}/?prefix=${value}`, {
47+
const result = await fetch(`/api/repo/${prepareArg(graph.Id)}/?prefix=${prepareArg(value)}`, {
4948
method: 'POST'
5049
})
5150

@@ -58,6 +57,8 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
5857
return
5958
}
6059

60+
if (!isLastRequest) return
61+
6162
const json = await result.json()
6263
const { completions } = json.result
6364

@@ -70,17 +71,21 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
7071
}
7172
}, 500)
7273

73-
return () => clearTimeout(timeout)
74+
return () => {
75+
clearTimeout(timeout)
76+
isLastRequest = false
77+
}
7478
}, [value])
7579

76-
const handelKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
80+
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
81+
const container = containerRef.current
7782
switch (e.code) {
7883
case "Enter": {
7984
e.preventDefault()
8085
const option = options.find((o, i) => i === selectedOption)
8186
if (!option) return
82-
if (handelSubmit) {
83-
handelSubmit(option)
87+
if (handleSubmit) {
88+
handleSubmit(option)
8489
} else {
8590
if (!open) return
8691
onValueChange({ name: option.properties.name, id: option.id })
@@ -91,16 +96,22 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
9196
case "ArrowUp": {
9297
e.preventDefault()
9398
setSelectedOption(prev => {
94-
containerRef.current?.scrollTo({ behavior: 'smooth', top: (prev <= 0 ? options.length - 1 : prev - 1) * containerRef.current.children[0].clientHeight })
95-
return prev <= 0 ? options.length - 1 : prev - 1
99+
const newIndex = prev <= 0 ? options.length - 1 : prev - 1
100+
if (container) {
101+
container.scrollTo({ behavior: 'smooth', top: 64 * newIndex })
102+
}
103+
return newIndex
96104
})
97105
return
98106
}
99107
case "ArrowDown": {
100108
e.preventDefault()
101109
setSelectedOption(prev => {
102-
containerRef.current?.scrollTo({ behavior: 'smooth', top: ((prev + 1) % options.length) * containerRef.current.children[0].clientHeight })
103-
return (prev + 1) % options.length
110+
const newIndex = (prev + 1) % options.length
111+
if (container) {
112+
container.scrollTo({ behavior: 'smooth', top: Math.min(64 * newIndex, container.scrollHeight) })
113+
}
114+
return newIndex
104115
})
105116
return
106117
}
@@ -124,8 +135,12 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
124135
data-name='search-bar'
125136
>
126137
<input
127-
ref={inputRef}
128-
onKeyDown={handelKeyDown}
138+
ref={ref => {
139+
if (ref) {
140+
setInputHeight(ref.scrollHeight)
141+
}
142+
}}
143+
onKeyDown={handleKeyDown}
129144
className={cn("w-full border p-2 rounded-md pointer-events-auto", className)}
130145
value={value || ""}
131146
onChange={(e) => {
@@ -146,16 +161,25 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
146161
className="z-10 w-full bg-white absolute flex flex-col pointer-events-auto border rounded-md max-h-[50dvh] overflow-y-auto overflow-x-hidden p-2 gap-2"
147162
data-name='search-bar-list'
148163
style={{
149-
top: (inputRef.current?.clientHeight || 0) + 16
164+
top: inputHeight + 16
150165
}}
151166
>
152167
{
168+
options.length > 0 &&
153169
options.map((option, index) => {
154170
const label = option.labels[0]
155171
const name = option.properties.name
156172
const path = option.properties.path
157-
const colorName = getCategoryColorName(graph.CategoriesMap.get(label)!.index)
158-
const color = getCategoryColorValue(graph.CategoriesMap.get(label)!.index)
173+
let category = graph.CategoriesMap.get(label)
174+
175+
if (!category) {
176+
category = { name: label, index: graph.CategoriesMap.size, show: true }
177+
graph.CategoriesMap.set(label, category)
178+
graph.Categories.push(category)
179+
}
180+
181+
const colorName = getCategoryColorName(category.index)
182+
const color = getCategoryColorValue(category.index)
159183
return (
160184
<button
161185
className={cn(
@@ -165,7 +189,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
165189
onMouseEnter={() => setSelectedOption(index)}
166190
onClick={() => {
167191
onValueChange({ name: option.properties.name, id: option.id })
168-
handelSubmit && handelSubmit(option)
192+
handleSubmit && handleSubmit(option)
169193
setOpen(false)
170194
}}
171195
key={option.id}

0 commit comments

Comments
 (0)