-
Notifications
You must be signed in to change notification settings - Fork 524
/
Copy pathValueSetSelect.tsx
118 lines (108 loc) · 3.1 KB
/
ValueSetSelect.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { useQuery } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import useDebouncedState from "@/hooks/useDebouncedState";
import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import { Code, ValueSetSystem } from "@/types/questionnaire/code";
interface Props {
system: ValueSetSystem;
value?: Code | null;
onSelect: (value: Code) => void;
placeholder?: string;
disabled?: boolean;
count?: number;
searchPostFix?: string;
}
export default function ValueSetSelect({
system,
value,
onSelect,
placeholder = "Search...",
disabled,
count = 10,
searchPostFix = "",
}: Props) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [search, setSearch] = useDebouncedState("", 500);
const searchQuery = useQuery({
queryKey: ["valueset", system, "expand", count, search],
queryFn: query(routes.valueset.expand, {
pathParams: { system },
body: { count, search: search + searchPostFix },
}),
});
useEffect(() => {
if (open) {
setSearch("");
}
}, [open]);
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild disabled={disabled}>
<Button
variant="outline"
role="combobox"
className={cn(
"w-full justify-between truncate",
!value?.display && "text-gray-400",
)}
>
{value?.display || placeholder}
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px] p-0" align="start">
<Command filter={() => 1}>
<CommandInput
placeholder={placeholder}
className="outline-none border-none ring-0 shadow-none"
onValueChange={setSearch}
/>
<CommandList>
<CommandEmpty>
{search.length < 3
? t("min_char_length_error", { min_length: 3 })
: searchQuery.isFetching
? t("searching")
: t("no_results_found")}
</CommandEmpty>
<CommandGroup>
{searchQuery.data?.results.map((option) => (
<CommandItem
key={option.code}
value={option.code}
onSelect={() => {
onSelect({
code: option.code,
display: option.display || "",
system: option.system || "",
});
setOpen(false);
}}
>
<span>{option.display}</span>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}