@vertesia/ui 0.78.0 → 0.79.0

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.
Files changed (212) hide show
  1. package/lib/esm/core/components/SelectList.js +18 -13
  2. package/lib/esm/core/components/SelectList.js.map +1 -1
  3. package/lib/esm/core/components/SidePanel.js +1 -1
  4. package/lib/esm/core/components/SidePanel.js.map +1 -1
  5. package/lib/esm/core/components/shadcn/filters/filterBar.js +39 -12
  6. package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
  7. package/lib/esm/core/components/shadcn/index.js +1 -0
  8. package/lib/esm/core/components/shadcn/index.js.map +1 -1
  9. package/lib/esm/core/components/shadcn/resizeable.js +15 -0
  10. package/lib/esm/core/components/shadcn/resizeable.js.map +1 -0
  11. package/lib/esm/core/components/shadcn/tabs.js +11 -6
  12. package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
  13. package/lib/esm/core/components/table/index.js +1 -1
  14. package/lib/esm/core/components/table/index.js.map +1 -1
  15. package/lib/esm/features/facets/CollectionsFacetsNav.js +66 -0
  16. package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -0
  17. package/lib/esm/features/facets/DocumentsFacetsNav.js +19 -7
  18. package/lib/esm/features/facets/DocumentsFacetsNav.js.map +1 -1
  19. package/lib/esm/features/facets/EnvironmentFacet.js +1 -1
  20. package/lib/esm/features/facets/EnvironmentFacet.js.map +1 -1
  21. package/lib/esm/features/facets/InteractionsFacetsNav.js +82 -0
  22. package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -0
  23. package/lib/esm/features/facets/PromptsFacetsNav.js +80 -0
  24. package/lib/esm/features/facets/PromptsFacetsNav.js.map +1 -0
  25. package/lib/esm/features/facets/RunsFacetsNav.js +28 -6
  26. package/lib/esm/features/facets/RunsFacetsNav.js.map +1 -1
  27. package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js +7 -5
  28. package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -1
  29. package/lib/esm/features/facets/index.js +10 -8
  30. package/lib/esm/features/facets/index.js.map +1 -1
  31. package/lib/esm/features/facets/utils/SearchInterface.js +2 -0
  32. package/lib/esm/features/facets/utils/SearchInterface.js.map +1 -0
  33. package/lib/esm/features/facets/utils/StringFacet.js.map +1 -0
  34. package/lib/esm/features/facets/utils/StringListFacet.js.map +1 -0
  35. package/lib/esm/features/facets/utils/TypeFacet.js.map +1 -0
  36. package/lib/esm/features/facets/utils/VEnvironmentFacet.js.map +1 -0
  37. package/lib/esm/features/facets/utils/VInteractionFacet.js.map +1 -0
  38. package/lib/esm/features/facets/utils/VStringFacet.js.map +1 -0
  39. package/lib/esm/features/facets/{VTypeFacet.js → utils/VTypeFacet.js} +5 -3
  40. package/lib/esm/features/facets/utils/VTypeFacet.js.map +1 -0
  41. package/lib/esm/features/facets/{VUserFacet.js → utils/VUserFacet.js} +1 -1
  42. package/lib/esm/features/facets/utils/VUserFacet.js.map +1 -0
  43. package/lib/esm/features/facets/utils/utils.js.map +1 -0
  44. package/lib/esm/features/store/collections/EditCollectionView.js +14 -1
  45. package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
  46. package/lib/esm/features/store/collections/SelectCollection.js +47 -18
  47. package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
  48. package/lib/esm/features/store/objects/DocumentSearchResults.js +9 -5
  49. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  50. package/lib/esm/features/store/objects/components/ContentOverview.js +172 -78
  51. package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
  52. package/lib/esm/features/store/objects/components/DocumentIcon.js +6 -0
  53. package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
  54. package/lib/esm/features/store/objects/layout/documentLayout.js +3 -4
  55. package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
  56. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +2 -2
  57. package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
  58. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +1 -1
  59. package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
  60. package/lib/esm/features/store/types/ObjectSchemaEditor.js +1 -1
  61. package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
  62. package/lib/esm/features/user/UserInfo.js +33 -1
  63. package/lib/esm/features/user/UserInfo.js.map +1 -1
  64. package/lib/esm/shell/login/UserInfo.js +1 -1
  65. package/lib/esm/shell/login/UserInfo.js.map +1 -1
  66. package/lib/esm/widgets/schema-editor/index.js +0 -1
  67. package/lib/esm/widgets/schema-editor/index.js.map +1 -1
  68. package/lib/tsconfig.tsbuildinfo +1 -1
  69. package/lib/types/core/components/SelectList.d.ts +2 -1
  70. package/lib/types/core/components/SelectList.d.ts.map +1 -1
  71. package/lib/types/core/components/SidePanel.d.ts.map +1 -1
  72. package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  73. package/lib/types/core/components/shadcn/index.d.ts +1 -0
  74. package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
  75. package/lib/types/core/components/shadcn/resizeable.d.ts +9 -0
  76. package/lib/types/core/components/shadcn/resizeable.d.ts.map +1 -0
  77. package/lib/types/core/components/shadcn/tabs.d.ts +2 -1
  78. package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
  79. package/lib/types/features/facets/CollectionsFacetsNav.d.ts +14 -0
  80. package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -0
  81. package/lib/types/features/facets/DocumentsFacetsNav.d.ts +1 -1
  82. package/lib/types/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
  83. package/lib/types/features/facets/InteractionsFacetsNav.d.ts +13 -0
  84. package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -0
  85. package/lib/types/features/facets/PromptsFacetsNav.d.ts +15 -0
  86. package/lib/types/features/facets/PromptsFacetsNav.d.ts.map +1 -0
  87. package/lib/types/features/facets/RunsFacetsNav.d.ts +1 -1
  88. package/lib/types/features/facets/RunsFacetsNav.d.ts.map +1 -1
  89. package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts +1 -1
  90. package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
  91. package/lib/types/features/facets/index.d.ts +10 -8
  92. package/lib/types/features/facets/index.d.ts.map +1 -1
  93. package/lib/types/features/facets/{VFacetsNav.d.ts → utils/SearchInterface.d.ts} +1 -8
  94. package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -0
  95. package/lib/types/features/facets/utils/StringFacet.d.ts.map +1 -0
  96. package/lib/types/features/facets/utils/StringListFacet.d.ts.map +1 -0
  97. package/lib/types/features/facets/utils/TypeFacet.d.ts.map +1 -0
  98. package/lib/types/features/facets/utils/VEnvironmentFacet.d.ts.map +1 -0
  99. package/lib/types/features/facets/utils/VInteractionFacet.d.ts.map +1 -0
  100. package/lib/types/features/facets/utils/VStringFacet.d.ts.map +1 -0
  101. package/lib/types/features/facets/utils/VTypeFacet.d.ts.map +1 -0
  102. package/lib/types/features/facets/utils/VUserFacet.d.ts.map +1 -0
  103. package/lib/types/features/facets/utils/utils.d.ts.map +1 -0
  104. package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
  105. package/lib/types/features/store/collections/SelectCollection.d.ts +10 -8
  106. package/lib/types/features/store/collections/SelectCollection.d.ts.map +1 -1
  107. package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  108. package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  109. package/lib/types/features/store/objects/components/DocumentIcon.d.ts +4 -0
  110. package/lib/types/features/store/objects/components/DocumentIcon.d.ts.map +1 -1
  111. package/lib/types/features/store/objects/layout/documentLayout.d.ts.map +1 -1
  112. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +1 -3
  113. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  114. package/lib/types/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
  115. package/lib/types/features/user/UserInfo.d.ts +12 -1
  116. package/lib/types/features/user/UserInfo.d.ts.map +1 -1
  117. package/lib/types/widgets/schema-editor/index.d.ts +0 -1
  118. package/lib/types/widgets/schema-editor/index.d.ts.map +1 -1
  119. package/lib/vertesia-ui-core.js +1 -1
  120. package/lib/vertesia-ui-core.js.map +1 -1
  121. package/lib/vertesia-ui-features.js +1 -1
  122. package/lib/vertesia-ui-features.js.map +1 -1
  123. package/lib/vertesia-ui-shell.js +1 -1
  124. package/lib/vertesia-ui-shell.js.map +1 -1
  125. package/lib/vertesia-ui-widgets.js +1 -1
  126. package/lib/vertesia-ui-widgets.js.map +1 -1
  127. package/package.json +5 -4
  128. package/src/core/components/SelectList.tsx +11 -1
  129. package/src/core/components/SidePanel.tsx +13 -10
  130. package/src/core/components/shadcn/filters/filterBar.tsx +46 -20
  131. package/src/core/components/shadcn/index.ts +1 -0
  132. package/src/core/components/shadcn/resizeable.tsx +54 -0
  133. package/src/core/components/shadcn/tabs.tsx +16 -6
  134. package/src/core/components/table/index.tsx +1 -1
  135. package/src/features/facets/CollectionsFacetsNav.tsx +94 -0
  136. package/src/features/facets/DocumentsFacetsNav.tsx +22 -11
  137. package/src/features/facets/EnvironmentFacet.tsx +1 -1
  138. package/src/features/facets/InteractionsFacetsNav.tsx +111 -0
  139. package/src/features/facets/PromptsFacetsNav.tsx +110 -0
  140. package/src/features/facets/RunsFacetsNav.tsx +40 -9
  141. package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +10 -8
  142. package/src/features/facets/index.ts +11 -9
  143. package/src/features/facets/utils/SearchInterface.tsx +8 -0
  144. package/src/features/facets/{VTypeFacet.tsx → utils/VTypeFacet.tsx} +6 -3
  145. package/src/features/facets/{VUserFacet.tsx → utils/VUserFacet.tsx} +1 -1
  146. package/src/features/store/collections/EditCollectionView.tsx +14 -1
  147. package/src/features/store/collections/SelectCollection.tsx +160 -31
  148. package/src/features/store/objects/DocumentSearchResults.tsx +42 -37
  149. package/src/features/store/objects/components/ContentOverview.tsx +432 -261
  150. package/src/features/store/objects/components/DocumentIcon.tsx +31 -1
  151. package/src/features/store/objects/layout/documentLayout.tsx +3 -7
  152. package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +15 -8
  153. package/src/features/store/objects/upload/DocumentUploadModal.tsx +5 -6
  154. package/src/features/store/types/ObjectSchemaEditor.tsx +1 -1
  155. package/src/features/user/UserInfo.tsx +66 -3
  156. package/src/shell/login/UserInfo.tsx +1 -1
  157. package/src/widgets/schema-editor/index.ts +0 -1
  158. package/lib/esm/features/facets/FacetsNav.js +0 -8
  159. package/lib/esm/features/facets/FacetsNav.js.map +0 -1
  160. package/lib/esm/features/facets/StringFacet.js.map +0 -1
  161. package/lib/esm/features/facets/StringListFacet.js.map +0 -1
  162. package/lib/esm/features/facets/TypeFacet.js.map +0 -1
  163. package/lib/esm/features/facets/VEnvironmentFacet.js.map +0 -1
  164. package/lib/esm/features/facets/VFacetsNav.js +0 -48
  165. package/lib/esm/features/facets/VFacetsNav.js.map +0 -1
  166. package/lib/esm/features/facets/VInteractionFacet.js.map +0 -1
  167. package/lib/esm/features/facets/VStringFacet.js.map +0 -1
  168. package/lib/esm/features/facets/VTypeFacet.js.map +0 -1
  169. package/lib/esm/features/facets/VUserFacet.js.map +0 -1
  170. package/lib/esm/features/facets/utils.js.map +0 -1
  171. package/lib/esm/widgets/schema-editor/JSONSchemaEditorModal.js +0 -49
  172. package/lib/esm/widgets/schema-editor/JSONSchemaEditorModal.js.map +0 -1
  173. package/lib/types/features/facets/FacetsNav.d.ts +0 -7
  174. package/lib/types/features/facets/FacetsNav.d.ts.map +0 -1
  175. package/lib/types/features/facets/StringFacet.d.ts.map +0 -1
  176. package/lib/types/features/facets/StringListFacet.d.ts.map +0 -1
  177. package/lib/types/features/facets/TypeFacet.d.ts.map +0 -1
  178. package/lib/types/features/facets/VEnvironmentFacet.d.ts.map +0 -1
  179. package/lib/types/features/facets/VFacetsNav.d.ts.map +0 -1
  180. package/lib/types/features/facets/VInteractionFacet.d.ts.map +0 -1
  181. package/lib/types/features/facets/VStringFacet.d.ts.map +0 -1
  182. package/lib/types/features/facets/VTypeFacet.d.ts.map +0 -1
  183. package/lib/types/features/facets/VUserFacet.d.ts.map +0 -1
  184. package/lib/types/features/facets/utils.d.ts.map +0 -1
  185. package/lib/types/widgets/schema-editor/JSONSchemaEditorModal.d.ts +0 -10
  186. package/lib/types/widgets/schema-editor/JSONSchemaEditorModal.d.ts.map +0 -1
  187. package/src/features/facets/FacetsNav.tsx +0 -19
  188. package/src/features/facets/VFacetsNav.tsx +0 -81
  189. package/src/widgets/schema-editor/JSONSchemaEditorModal.tsx +0 -67
  190. /package/lib/esm/features/facets/{StringFacet.js → utils/StringFacet.js} +0 -0
  191. /package/lib/esm/features/facets/{StringListFacet.js → utils/StringListFacet.js} +0 -0
  192. /package/lib/esm/features/facets/{TypeFacet.js → utils/TypeFacet.js} +0 -0
  193. /package/lib/esm/features/facets/{VEnvironmentFacet.js → utils/VEnvironmentFacet.js} +0 -0
  194. /package/lib/esm/features/facets/{VInteractionFacet.js → utils/VInteractionFacet.js} +0 -0
  195. /package/lib/esm/features/facets/{VStringFacet.js → utils/VStringFacet.js} +0 -0
  196. /package/lib/esm/features/facets/{utils.js → utils/utils.js} +0 -0
  197. /package/lib/types/features/facets/{StringFacet.d.ts → utils/StringFacet.d.ts} +0 -0
  198. /package/lib/types/features/facets/{StringListFacet.d.ts → utils/StringListFacet.d.ts} +0 -0
  199. /package/lib/types/features/facets/{TypeFacet.d.ts → utils/TypeFacet.d.ts} +0 -0
  200. /package/lib/types/features/facets/{VEnvironmentFacet.d.ts → utils/VEnvironmentFacet.d.ts} +0 -0
  201. /package/lib/types/features/facets/{VInteractionFacet.d.ts → utils/VInteractionFacet.d.ts} +0 -0
  202. /package/lib/types/features/facets/{VStringFacet.d.ts → utils/VStringFacet.d.ts} +0 -0
  203. /package/lib/types/features/facets/{VTypeFacet.d.ts → utils/VTypeFacet.d.ts} +0 -0
  204. /package/lib/types/features/facets/{VUserFacet.d.ts → utils/VUserFacet.d.ts} +0 -0
  205. /package/lib/types/features/facets/{utils.d.ts → utils/utils.d.ts} +0 -0
  206. /package/src/features/facets/{StringFacet.tsx → utils/StringFacet.tsx} +0 -0
  207. /package/src/features/facets/{StringListFacet.tsx → utils/StringListFacet.tsx} +0 -0
  208. /package/src/features/facets/{TypeFacet.tsx → utils/TypeFacet.tsx} +0 -0
  209. /package/src/features/facets/{VEnvironmentFacet.tsx → utils/VEnvironmentFacet.tsx} +0 -0
  210. /package/src/features/facets/{VInteractionFacet.tsx → utils/VInteractionFacet.tsx} +0 -0
  211. /package/src/features/facets/{VStringFacet.tsx → utils/VStringFacet.tsx} +0 -0
  212. /package/src/features/facets/{utils.tsx → utils/utils.tsx} +0 -0
@@ -1,46 +1,175 @@
1
- import { ErrorBox, useFetch, VSelectBox } from "@vertesia/ui/core";
2
- import { useUserSession } from "@vertesia/ui/session";
1
+ import { Check, ChevronsUpDown } from "lucide-react";
2
+ import { useCallback, useMemo, useState } from "react";
3
3
 
4
- interface SelectCollectionProps {
5
- value?: string; // Collection ID
6
- onChange: (collectionId: string | undefined, collection?: any) => void;
7
- disabled?: boolean;
8
- className?: string;
9
- }
4
+ import { CollectionItem } from "@vertesia/common";
5
+ import {
6
+ Button, cn, ErrorBox, useDebounce, useFetch,
7
+ Popover, PopoverContent, PopoverTrigger,
8
+ Command, CommandEmpty, CommandGroup, CommandItem, CommandInput
9
+ } from "@vertesia/ui/core";
10
+ import { useUserSession } from "@vertesia/ui/session";
10
11
 
11
12
  /**
12
13
  * A component to select a collection from a list of collections.
13
14
  * It fetches the collections from the store and displays them in a dropdown.
14
15
  * @param props - The properties for the component.
15
16
  * @returns A dropdown to select a collection.
16
- */
17
- export function SelectCollection({ onChange, value, disabled = false, className }: SelectCollectionProps) {
17
+ **/
18
+ interface SelectCollectionProps {
19
+ value?: string; // Collection ID
20
+ onChange: (collectionId: string | undefined, collection?: CollectionItem) => void;
21
+ disabled?: boolean;
22
+ placeholder?: string;
23
+ searchPlaceholder?: string;
24
+ }
25
+ export function SelectCollection({ onChange, value, disabled = false, placeholder = "Select a collection", searchPlaceholder = "Search collections" }: SelectCollectionProps) {
18
26
  const { client } = useUserSession();
19
- const { data: collections, error } = useFetch(() => client.store.collections.search({ dynamic: false }), []);
20
27
 
28
+ const [searchQuery, setSearchQuery] = useState('');
29
+ const [isSearching, setIsSearching] = useState(false);
30
+
31
+ // Debounce the search query to avoid excessive API calls
32
+ const debouncedSearchQuery = useDebounce(searchQuery, 300);
33
+
34
+ // Memoize the search function to prevent unnecessary re-renders
35
+ const searchCollections = useCallback(async (query: string) => {
36
+ setIsSearching(true);
37
+ const trimmedQuery = query.trim();
38
+
39
+ const collections = await client.store.collections.search({
40
+ dynamic: false,
41
+ name: trimmedQuery || undefined
42
+ });
43
+
44
+ setIsSearching(false);
45
+ return collections;
46
+ }, [client]);
47
+
48
+ // Fetch collections based on debounced search query
49
+ const { data: collections, error } = useFetch(
50
+ () => searchCollections(debouncedSearchQuery),
51
+ [debouncedSearchQuery, searchCollections]
52
+ );
53
+
54
+ // Memoize the selected collection to avoid recalculation on every render
55
+ const selectedCollection = useMemo(() => {
56
+ return collections?.find((collection: CollectionItem) => collection.id === value);
57
+ }, [collections, value]);
58
+
59
+ // Handle collection selection
60
+ const handleSelect = useCallback((collection: CollectionItem) => {
61
+ onChange(collection.id, collection);
62
+ }, [onChange]);
63
+
64
+ // Handle clear selection
65
+ const handleClear = useCallback(() => {
66
+ onChange(undefined, undefined);
67
+ }, [onChange]);
68
+
69
+ // Handle search input change
70
+ const handleSearchChange = useCallback((query: string) => {
71
+ setSearchQuery(query);
72
+ }, []);
73
+
74
+ // Show error state
21
75
  if (error) {
22
- return <ErrorBox title='Collection fetch failed'>{error.message}</ErrorBox>
76
+ return (
77
+ <ErrorBox title="Collection fetch failed">
78
+ {error.message}
79
+ </ErrorBox>
80
+ );
23
81
  }
24
82
 
25
- // Find the selected collection object from the ID
26
- const selectedCollection = value ? collections?.find(col => col.id === value) : undefined;
27
-
28
- const handleChange = (collection: any) => {
29
- // Call onChange with both the ID and the full collection object
30
- onChange(collection?.id, collection);
31
- };
83
+ const hasSearchQuery = searchQuery.trim().length > 0;
84
+ const showClearOption = selectedCollection && hasSearchQuery;
32
85
 
33
86
  return (
34
- <VSelectBox
35
- filterBy={"name"}
36
- value={selectedCollection}
37
- onChange={handleChange}
38
- placeholder="Select a collection"
39
- options={collections || []}
40
- optionLabel={(col: any) => col.name}
41
- by="id"
42
- className={className}
43
- disabled={disabled}
44
- />
87
+ <Popover>
88
+ <PopoverTrigger asChild>
89
+ <Button
90
+ variant="outline"
91
+ role="combobox"
92
+ aria-haspopup="listbox"
93
+ className={cn("w-full justify-between min-w-0")}
94
+ disabled={disabled}
95
+ >
96
+ <span className="truncate flex-1 text-left min-w-0">
97
+ {selectedCollection ? selectedCollection.name : placeholder}
98
+ </span>
99
+ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
100
+ </Button>
101
+ </PopoverTrigger>
102
+ <PopoverContent className="mt-2 mb-2 w-[var(--radix-popover-trigger-width)] p-0" align="start">
103
+ <Command shouldFilter={false}>
104
+ <div className="flex justify-between items-center border-b px-3" cmdk-input-wrapper="">
105
+ <CommandInput
106
+ placeholder={searchPlaceholder}
107
+ value={searchQuery}
108
+ onValueChange={handleSearchChange}
109
+ className="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
110
+ />
111
+ {
112
+ isSearching && (
113
+ <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
114
+ )
115
+ }
116
+ </div>
117
+ <CommandEmpty>
118
+ {
119
+ isSearching
120
+ ? "Searching..."
121
+ : hasSearchQuery
122
+ ? "No collections found."
123
+ : "No collections available."
124
+ }
125
+ </CommandEmpty>
126
+ <CommandGroup className="max-h-[300px] overflow-auto">
127
+ {
128
+ showClearOption && (
129
+ <CommandItem
130
+ value="__clear__"
131
+ onSelect={handleClear}
132
+ className="text-muted-foreground"
133
+ >
134
+ Clear selection
135
+ </CommandItem>
136
+ )
137
+ }
138
+ {
139
+ collections?.map((collection: CollectionItem) => (
140
+ <CommandItem
141
+ key={collection.id}
142
+ value={collection.id}
143
+ onSelect={() => handleSelect(collection)}
144
+ className={cn(
145
+ "flex items-center justify-between",
146
+ value === collection.id ? "bg-muted/20" : ""
147
+ )}
148
+ >
149
+ <div className="flex flex-col flex-1 min-w-0">
150
+ <span className="truncate font-medium">
151
+ {collection.name}
152
+ </span>
153
+ {
154
+ collection.description && (
155
+ <span className="text-sm text-muted-foreground truncate">
156
+ {collection.description}
157
+ </span>
158
+ )
159
+ }
160
+ </div>
161
+ <Check
162
+ className={cn(
163
+ "ml-2 h-4 w-4 shrink-0",
164
+ value === collection.id ? "opacity-100" : "opacity-0"
165
+ )}
166
+ />
167
+ </CommandItem>
168
+ ))
169
+ }
170
+ </CommandGroup>
171
+ </Command>
172
+ </PopoverContent>
173
+ </Popover>
45
174
  );
46
- }
175
+ }
@@ -1,7 +1,6 @@
1
1
  import { useRef, useState, useEffect } from "react";
2
2
  import { ColumnLayout, ContentObject, ContentObjectItem, ComplexSearchQuery } from '@vertesia/common';
3
3
  import {
4
-
5
4
  Button, Divider, ErrorBox, SidePanel, Spinner, useIntersectionObserver, useToast,
6
5
  FilterProvider, FilterBtn, FilterBar, FilterClear, Filter as BaseFilter
7
6
  } from '@vertesia/ui/core';
@@ -102,7 +101,7 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
102
101
  const [filters, setFilters] = useState<BaseFilter[]>([]);
103
102
 
104
103
  const loadMoreRef = useRef<HTMLDivElement>(null);
105
-
104
+
106
105
  // Trigger initial search when component mounts
107
106
  useEffect(() => {
108
107
  if (!isReady && objects.length === 0) {
@@ -151,10 +150,14 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
151
150
  } else if (query && query.full_text) {
152
151
  search.query.full_text = query.full_text;
153
152
  search.search().then(() => setIsReady(true));
154
- } else {
155
- delete search.query.vector;
156
- delete search.query.full_text;
157
- search.search().then(() => setIsReady(true));
153
+ } else if (query === undefined) {
154
+ // Only clear search if this is a user-initiated clear (not initialization)
155
+ // The VectorSearchWidget calls onChange(undefined) during initialization
156
+ if (isReady) {
157
+ delete search.query.vector;
158
+ delete search.query.full_text;
159
+ search.search().then(() => setIsReady(true));
160
+ }
158
161
  }
159
162
  };
160
163
 
@@ -207,47 +210,49 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
207
210
  {
208
211
  error && <ErrorBox title="Error">{error.message}</ErrorBox>
209
212
  }
210
- {
211
- allowFilter && (
212
- <FilterProvider
213
- filterGroups={filterGroups}
214
- filters={filters}
215
- setFilters={handleFilterChange}
216
- >
213
+ <div className="sticky top-0 z-10 bg-background pb-2">
214
+ {
215
+ allowFilter && (
216
+ <FilterProvider
217
+ filterGroups={filterGroups}
218
+ filters={filters}
219
+ setFilters={handleFilterChange}
220
+ >
221
+ <div className="flex flex-row gap-4 items-center justify-between w-full">
222
+ <div className="flex gap-2 items-center w-2/3">
223
+ {
224
+ allowSearch && <VectorSearchWidget onChange={handleVectorSearch} isLoading={isLoading} refresh={refreshTrigger} className="w-full" />
225
+ }
226
+ <FilterBtn />
227
+ </div>
228
+ <div className="flex gap-1 items-center">
229
+ <Button variant="outline" onClick={handleRefetch} alt="Refresh"><RefreshCw size={16} /></Button>
230
+ <ContentDispositionButton onUpdate={setIsGridView} />
231
+ </div>
232
+ </div>
233
+ <div className="flex gap-2 items-center">
234
+ <FilterBar />
235
+ <FilterClear />
236
+ </div>
237
+ </FilterProvider>
238
+ )
239
+ }
240
+ {
241
+ !allowFilter && (
217
242
  <div className="flex flex-row gap-4 items-center justify-between w-full">
218
243
  <div className="flex gap-2 items-center w-2/3">
219
244
  {
220
- allowSearch && <VectorSearchWidget onChange={handleVectorSearch} isLoading={isLoading} refresh={refreshTrigger} className="w-full" />
245
+ allowSearch && <VectorSearchWidget onChange={handleVectorSearch} isLoading={isLoading} refresh={refreshTrigger} />
221
246
  }
222
- <FilterBtn />
223
247
  </div>
224
248
  <div className="flex gap-1 items-center">
225
249
  <Button variant="outline" onClick={handleRefetch} alt="Refresh"><RefreshCw size={16} /></Button>
226
250
  <ContentDispositionButton onUpdate={setIsGridView} />
227
251
  </div>
228
252
  </div>
229
- <div className="flex gap-2 items-center">
230
- <FilterBar />
231
- <FilterClear />
232
- </div>
233
- </FilterProvider>
234
- )
235
- }
236
- {
237
- !allowFilter && (
238
- <div className="flex flex-row gap-4 items-center justify-between w-full">
239
- <div className="flex gap-2 items-center w-2/3">
240
- {
241
- allowSearch && <VectorSearchWidget onChange={handleVectorSearch} isLoading={isLoading} refresh={refreshTrigger} />
242
- }
243
- </div>
244
- <div className="flex gap-1 items-center">
245
- <Button variant="outline" onClick={handleRefetch} alt="Refresh"><RefreshCw size={16} /></Button>
246
- <ContentDispositionButton onUpdate={setIsGridView} />
247
- </div>
248
- </div>
249
- )
250
- }
253
+ )
254
+ }
255
+ </div>
251
256
  <DocumentTable
252
257
  objects={objects}
253
258
  isLoading={!objects.length && isLoading}