@snapdragonsnursery/react-components 1.17.2 → 1.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
// - maxHeight?: string // max height for dropdown (default: '160px')
|
|
35
35
|
|
|
36
36
|
import React from "react";
|
|
37
|
-
import { Users } from "lucide-react";
|
|
37
|
+
import { Users, Search } from "lucide-react";
|
|
38
38
|
import { cn } from "../lib/utils";
|
|
39
39
|
|
|
40
40
|
import {
|
|
@@ -62,6 +62,8 @@ export const EmployeeSelect = ({
|
|
|
62
62
|
allLabel = "All employees",
|
|
63
63
|
maxHeight = "160px",
|
|
64
64
|
}) => {
|
|
65
|
+
const [searchTerm, setSearchTerm] = React.useState("");
|
|
66
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
65
67
|
// Helper function to generate initials from full name
|
|
66
68
|
const getInitials = (name) => {
|
|
67
69
|
if (!name) return "??";
|
|
@@ -108,8 +110,21 @@ export const EmployeeSelect = ({
|
|
|
108
110
|
}))
|
|
109
111
|
.filter((e) => e.entraId); // Remove items without entra_id
|
|
110
112
|
|
|
113
|
+
// Apply search filter
|
|
114
|
+
const searchFiltered = mapped.filter((e) => {
|
|
115
|
+
if (!searchTerm) return true;
|
|
116
|
+
const searchLower = searchTerm.toLowerCase();
|
|
117
|
+
return (
|
|
118
|
+
e.fullName.toLowerCase().includes(searchLower) ||
|
|
119
|
+
e.siteName.toLowerCase().includes(searchLower) ||
|
|
120
|
+
e.roleName.toLowerCase().includes(searchLower) ||
|
|
121
|
+
e.employeeId.toLowerCase().includes(searchLower) ||
|
|
122
|
+
e.email.toLowerCase().includes(searchLower)
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
111
126
|
// Sort based on grouping
|
|
112
|
-
|
|
127
|
+
searchFiltered.sort((a, b) => {
|
|
113
128
|
if (groupBy === "site") {
|
|
114
129
|
const siteCompare = a.siteName.localeCompare(b.siteName);
|
|
115
130
|
if (siteCompare !== 0) return siteCompare;
|
|
@@ -123,8 +138,8 @@ export const EmployeeSelect = ({
|
|
|
123
138
|
return a.fullName.localeCompare(b.fullName);
|
|
124
139
|
});
|
|
125
140
|
|
|
126
|
-
return
|
|
127
|
-
}, [items, filter, groupBy]);
|
|
141
|
+
return searchFiltered;
|
|
142
|
+
}, [items, filter, groupBy, searchTerm]);
|
|
128
143
|
|
|
129
144
|
const selectedEmployee = processedItems.find((e) => e.entraId === value);
|
|
130
145
|
|
|
@@ -170,8 +185,12 @@ export const EmployeeSelect = ({
|
|
|
170
185
|
} else {
|
|
171
186
|
onChange?.(val);
|
|
172
187
|
}
|
|
188
|
+
setSearchTerm(""); // Clear search when selection is made
|
|
189
|
+
setIsOpen(false);
|
|
173
190
|
}}
|
|
174
191
|
disabled={disabled}
|
|
192
|
+
open={isOpen}
|
|
193
|
+
onOpenChange={setIsOpen}
|
|
175
194
|
>
|
|
176
195
|
<SelectTrigger className={cn("w-full", className)}>
|
|
177
196
|
<div className="flex items-center gap-2">
|
|
@@ -192,6 +211,20 @@ export const EmployeeSelect = ({
|
|
|
192
211
|
className="[&_[data-radix-select-viewport]]:max-h-[var(--select-max-height)] [&_[data-radix-select-viewport]]:overflow-y-auto [&>button[data-radix-select-scroll-up-button]]:hidden [&>button[data-radix-select-scroll-down-button]]:hidden"
|
|
193
212
|
style={{ "--select-max-height": maxHeight }}
|
|
194
213
|
>
|
|
214
|
+
{/* Search input */}
|
|
215
|
+
<div className="p-2 border-b">
|
|
216
|
+
<div className="relative">
|
|
217
|
+
<Search className="absolute left-2 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
|
218
|
+
<input
|
|
219
|
+
type="text"
|
|
220
|
+
placeholder="Search employees..."
|
|
221
|
+
value={searchTerm}
|
|
222
|
+
onChange={(e) => setSearchTerm(e.target.value)}
|
|
223
|
+
className="w-full pl-8 pr-3 py-2 text-sm border rounded-md focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 bg-background"
|
|
224
|
+
onClick={(e) => e.stopPropagation()}
|
|
225
|
+
/>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
195
228
|
{allowAll && <SelectItem value="__all__">{allLabel}</SelectItem>}
|
|
196
229
|
{groupBy === "site"
|
|
197
230
|
? // Group by site
|