@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.
- package/lib/esm/core/components/SelectList.js +18 -13
- package/lib/esm/core/components/SelectList.js.map +1 -1
- package/lib/esm/core/components/SidePanel.js +1 -1
- package/lib/esm/core/components/SidePanel.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/filterBar.js +39 -12
- package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/esm/core/components/shadcn/index.js +1 -0
- package/lib/esm/core/components/shadcn/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/resizeable.js +15 -0
- package/lib/esm/core/components/shadcn/resizeable.js.map +1 -0
- package/lib/esm/core/components/shadcn/tabs.js +11 -6
- package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
- package/lib/esm/core/components/table/index.js +1 -1
- package/lib/esm/core/components/table/index.js.map +1 -1
- package/lib/esm/features/facets/CollectionsFacetsNav.js +66 -0
- package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -0
- package/lib/esm/features/facets/DocumentsFacetsNav.js +19 -7
- package/lib/esm/features/facets/DocumentsFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/EnvironmentFacet.js +1 -1
- package/lib/esm/features/facets/EnvironmentFacet.js.map +1 -1
- package/lib/esm/features/facets/InteractionsFacetsNav.js +82 -0
- package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -0
- package/lib/esm/features/facets/PromptsFacetsNav.js +80 -0
- package/lib/esm/features/facets/PromptsFacetsNav.js.map +1 -0
- package/lib/esm/features/facets/RunsFacetsNav.js +28 -6
- package/lib/esm/features/facets/RunsFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js +7 -5
- package/lib/esm/features/facets/WorkflowExecutionsFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/index.js +10 -8
- package/lib/esm/features/facets/index.js.map +1 -1
- package/lib/esm/features/facets/utils/SearchInterface.js +2 -0
- package/lib/esm/features/facets/utils/SearchInterface.js.map +1 -0
- package/lib/esm/features/facets/utils/StringFacet.js.map +1 -0
- package/lib/esm/features/facets/utils/StringListFacet.js.map +1 -0
- package/lib/esm/features/facets/utils/TypeFacet.js.map +1 -0
- package/lib/esm/features/facets/utils/VEnvironmentFacet.js.map +1 -0
- package/lib/esm/features/facets/utils/VInteractionFacet.js.map +1 -0
- package/lib/esm/features/facets/utils/VStringFacet.js.map +1 -0
- package/lib/esm/features/facets/{VTypeFacet.js → utils/VTypeFacet.js} +5 -3
- package/lib/esm/features/facets/utils/VTypeFacet.js.map +1 -0
- package/lib/esm/features/facets/{VUserFacet.js → utils/VUserFacet.js} +1 -1
- package/lib/esm/features/facets/utils/VUserFacet.js.map +1 -0
- package/lib/esm/features/facets/utils/utils.js.map +1 -0
- package/lib/esm/features/store/collections/EditCollectionView.js +14 -1
- package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
- package/lib/esm/features/store/collections/SelectCollection.js +47 -18
- package/lib/esm/features/store/collections/SelectCollection.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentSearchResults.js +9 -5
- package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/esm/features/store/objects/components/ContentOverview.js +172 -78
- package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/esm/features/store/objects/components/DocumentIcon.js +6 -0
- package/lib/esm/features/store/objects/components/DocumentIcon.js.map +1 -1
- package/lib/esm/features/store/objects/layout/documentLayout.js +3 -4
- package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js +2 -2
- package/lib/esm/features/store/objects/selection/actions/AddToCollectionAction.js.map +1 -1
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js +1 -1
- package/lib/esm/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/esm/features/store/types/ObjectSchemaEditor.js +1 -1
- package/lib/esm/features/store/types/ObjectSchemaEditor.js.map +1 -1
- package/lib/esm/features/user/UserInfo.js +33 -1
- package/lib/esm/features/user/UserInfo.js.map +1 -1
- package/lib/esm/shell/login/UserInfo.js +1 -1
- package/lib/esm/shell/login/UserInfo.js.map +1 -1
- package/lib/esm/widgets/schema-editor/index.js +0 -1
- package/lib/esm/widgets/schema-editor/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/components/SelectList.d.ts +2 -1
- package/lib/types/core/components/SelectList.d.ts.map +1 -1
- package/lib/types/core/components/SidePanel.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/index.d.ts +1 -0
- package/lib/types/core/components/shadcn/index.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/resizeable.d.ts +9 -0
- package/lib/types/core/components/shadcn/resizeable.d.ts.map +1 -0
- package/lib/types/core/components/shadcn/tabs.d.ts +2 -1
- package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/types/features/facets/CollectionsFacetsNav.d.ts +14 -0
- package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -0
- package/lib/types/features/facets/DocumentsFacetsNav.d.ts +1 -1
- package/lib/types/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/facets/InteractionsFacetsNav.d.ts +13 -0
- package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -0
- package/lib/types/features/facets/PromptsFacetsNav.d.ts +15 -0
- package/lib/types/features/facets/PromptsFacetsNav.d.ts.map +1 -0
- package/lib/types/features/facets/RunsFacetsNav.d.ts +1 -1
- package/lib/types/features/facets/RunsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts +1 -1
- package/lib/types/features/facets/WorkflowExecutionsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/facets/index.d.ts +10 -8
- package/lib/types/features/facets/index.d.ts.map +1 -1
- package/lib/types/features/facets/{VFacetsNav.d.ts → utils/SearchInterface.d.ts} +1 -8
- package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -0
- package/lib/types/features/facets/utils/StringFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/StringListFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/TypeFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/VEnvironmentFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/VInteractionFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/VStringFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/VTypeFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/VUserFacet.d.ts.map +1 -0
- package/lib/types/features/facets/utils/utils.d.ts.map +1 -0
- package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
- package/lib/types/features/store/collections/SelectCollection.d.ts +10 -8
- package/lib/types/features/store/collections/SelectCollection.d.ts.map +1 -1
- package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/ContentOverview.d.ts.map +1 -1
- package/lib/types/features/store/objects/components/DocumentIcon.d.ts +4 -0
- package/lib/types/features/store/objects/components/DocumentIcon.d.ts.map +1 -1
- package/lib/types/features/store/objects/layout/documentLayout.d.ts.map +1 -1
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +1 -3
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/types/features/store/objects/upload/DocumentUploadModal.d.ts.map +1 -1
- package/lib/types/features/user/UserInfo.d.ts +12 -1
- package/lib/types/features/user/UserInfo.d.ts.map +1 -1
- package/lib/types/widgets/schema-editor/index.d.ts +0 -1
- package/lib/types/widgets/schema-editor/index.d.ts.map +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +1 -1
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-shell.js +1 -1
- package/lib/vertesia-ui-shell.js.map +1 -1
- package/lib/vertesia-ui-widgets.js +1 -1
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/package.json +5 -4
- package/src/core/components/SelectList.tsx +11 -1
- package/src/core/components/SidePanel.tsx +13 -10
- package/src/core/components/shadcn/filters/filterBar.tsx +46 -20
- package/src/core/components/shadcn/index.ts +1 -0
- package/src/core/components/shadcn/resizeable.tsx +54 -0
- package/src/core/components/shadcn/tabs.tsx +16 -6
- package/src/core/components/table/index.tsx +1 -1
- package/src/features/facets/CollectionsFacetsNav.tsx +94 -0
- package/src/features/facets/DocumentsFacetsNav.tsx +22 -11
- package/src/features/facets/EnvironmentFacet.tsx +1 -1
- package/src/features/facets/InteractionsFacetsNav.tsx +111 -0
- package/src/features/facets/PromptsFacetsNav.tsx +110 -0
- package/src/features/facets/RunsFacetsNav.tsx +40 -9
- package/src/features/facets/WorkflowExecutionsFacetsNav.tsx +10 -8
- package/src/features/facets/index.ts +11 -9
- package/src/features/facets/utils/SearchInterface.tsx +8 -0
- package/src/features/facets/{VTypeFacet.tsx → utils/VTypeFacet.tsx} +6 -3
- package/src/features/facets/{VUserFacet.tsx → utils/VUserFacet.tsx} +1 -1
- package/src/features/store/collections/EditCollectionView.tsx +14 -1
- package/src/features/store/collections/SelectCollection.tsx +160 -31
- package/src/features/store/objects/DocumentSearchResults.tsx +42 -37
- package/src/features/store/objects/components/ContentOverview.tsx +432 -261
- package/src/features/store/objects/components/DocumentIcon.tsx +31 -1
- package/src/features/store/objects/layout/documentLayout.tsx +3 -7
- package/src/features/store/objects/selection/actions/AddToCollectionAction.tsx +15 -8
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +5 -6
- package/src/features/store/types/ObjectSchemaEditor.tsx +1 -1
- package/src/features/user/UserInfo.tsx +66 -3
- package/src/shell/login/UserInfo.tsx +1 -1
- package/src/widgets/schema-editor/index.ts +0 -1
- package/lib/esm/features/facets/FacetsNav.js +0 -8
- package/lib/esm/features/facets/FacetsNav.js.map +0 -1
- package/lib/esm/features/facets/StringFacet.js.map +0 -1
- package/lib/esm/features/facets/StringListFacet.js.map +0 -1
- package/lib/esm/features/facets/TypeFacet.js.map +0 -1
- package/lib/esm/features/facets/VEnvironmentFacet.js.map +0 -1
- package/lib/esm/features/facets/VFacetsNav.js +0 -48
- package/lib/esm/features/facets/VFacetsNav.js.map +0 -1
- package/lib/esm/features/facets/VInteractionFacet.js.map +0 -1
- package/lib/esm/features/facets/VStringFacet.js.map +0 -1
- package/lib/esm/features/facets/VTypeFacet.js.map +0 -1
- package/lib/esm/features/facets/VUserFacet.js.map +0 -1
- package/lib/esm/features/facets/utils.js.map +0 -1
- package/lib/esm/widgets/schema-editor/JSONSchemaEditorModal.js +0 -49
- package/lib/esm/widgets/schema-editor/JSONSchemaEditorModal.js.map +0 -1
- package/lib/types/features/facets/FacetsNav.d.ts +0 -7
- package/lib/types/features/facets/FacetsNav.d.ts.map +0 -1
- package/lib/types/features/facets/StringFacet.d.ts.map +0 -1
- package/lib/types/features/facets/StringListFacet.d.ts.map +0 -1
- package/lib/types/features/facets/TypeFacet.d.ts.map +0 -1
- package/lib/types/features/facets/VEnvironmentFacet.d.ts.map +0 -1
- package/lib/types/features/facets/VFacetsNav.d.ts.map +0 -1
- package/lib/types/features/facets/VInteractionFacet.d.ts.map +0 -1
- package/lib/types/features/facets/VStringFacet.d.ts.map +0 -1
- package/lib/types/features/facets/VTypeFacet.d.ts.map +0 -1
- package/lib/types/features/facets/VUserFacet.d.ts.map +0 -1
- package/lib/types/features/facets/utils.d.ts.map +0 -1
- package/lib/types/widgets/schema-editor/JSONSchemaEditorModal.d.ts +0 -10
- package/lib/types/widgets/schema-editor/JSONSchemaEditorModal.d.ts.map +0 -1
- package/src/features/facets/FacetsNav.tsx +0 -19
- package/src/features/facets/VFacetsNav.tsx +0 -81
- package/src/widgets/schema-editor/JSONSchemaEditorModal.tsx +0 -67
- /package/lib/esm/features/facets/{StringFacet.js → utils/StringFacet.js} +0 -0
- /package/lib/esm/features/facets/{StringListFacet.js → utils/StringListFacet.js} +0 -0
- /package/lib/esm/features/facets/{TypeFacet.js → utils/TypeFacet.js} +0 -0
- /package/lib/esm/features/facets/{VEnvironmentFacet.js → utils/VEnvironmentFacet.js} +0 -0
- /package/lib/esm/features/facets/{VInteractionFacet.js → utils/VInteractionFacet.js} +0 -0
- /package/lib/esm/features/facets/{VStringFacet.js → utils/VStringFacet.js} +0 -0
- /package/lib/esm/features/facets/{utils.js → utils/utils.js} +0 -0
- /package/lib/types/features/facets/{StringFacet.d.ts → utils/StringFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{StringListFacet.d.ts → utils/StringListFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{TypeFacet.d.ts → utils/TypeFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{VEnvironmentFacet.d.ts → utils/VEnvironmentFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{VInteractionFacet.d.ts → utils/VInteractionFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{VStringFacet.d.ts → utils/VStringFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{VTypeFacet.d.ts → utils/VTypeFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{VUserFacet.d.ts → utils/VUserFacet.d.ts} +0 -0
- /package/lib/types/features/facets/{utils.d.ts → utils/utils.d.ts} +0 -0
- /package/src/features/facets/{StringFacet.tsx → utils/StringFacet.tsx} +0 -0
- /package/src/features/facets/{StringListFacet.tsx → utils/StringListFacet.tsx} +0 -0
- /package/src/features/facets/{TypeFacet.tsx → utils/TypeFacet.tsx} +0 -0
- /package/src/features/facets/{VEnvironmentFacet.tsx → utils/VEnvironmentFacet.tsx} +0 -0
- /package/src/features/facets/{VInteractionFacet.tsx → utils/VInteractionFacet.tsx} +0 -0
- /package/src/features/facets/{VStringFacet.tsx → utils/VStringFacet.tsx} +0 -0
- /package/src/features/facets/{utils.tsx → utils/utils.tsx} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertesia/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.79.0",
|
|
4
4
|
"description": "Vertesia UI components and and hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -56,13 +56,14 @@
|
|
|
56
56
|
"react-dom": "^19.1.0",
|
|
57
57
|
"react-error-boundary": "^6.0.0",
|
|
58
58
|
"react-markdown": "^10.1.0",
|
|
59
|
+
"react-resizable-panels": "^3.0.6",
|
|
59
60
|
"remark-gfm": "^4.0.1",
|
|
60
61
|
"tailwind-merge": "^3.3.0",
|
|
61
62
|
"ts-md5": "^1.3.1",
|
|
62
63
|
"unist-util-visit": "^5.0.0",
|
|
63
|
-
"@vertesia/client": "0.
|
|
64
|
-
"@vertesia/
|
|
65
|
-
"@vertesia/
|
|
64
|
+
"@vertesia/client": "0.79.0",
|
|
65
|
+
"@vertesia/json": "0.79.0",
|
|
66
|
+
"@vertesia/common": "0.79.0"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@eslint/js": "^9.27.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Check } from "lucide-react";
|
|
2
2
|
import clsx from "clsx";
|
|
3
3
|
import { ReactNode, useMemo, useState } from "react";
|
|
4
|
+
import { Input } from "./shadcn";
|
|
4
5
|
|
|
5
6
|
const Default_Option_Style = "flex-1 px-2 py-2 hover:bg-accent nowrap";
|
|
6
7
|
|
|
@@ -28,9 +29,12 @@ export interface SelectListProps<T> {
|
|
|
28
29
|
by?: (keyof T & string) | ((o1: T, o2: T) => boolean);
|
|
29
30
|
optionLayout?: (opt: T, selected: boolean) => OptionLayout;
|
|
30
31
|
noCheck?: boolean;
|
|
32
|
+
filterBy?: (filterValue: string) => (opt: T) => boolean;
|
|
31
33
|
}
|
|
32
|
-
export function SelectList<T>({ value, options, onChange, className, optionLayout, by, noCheck }: SelectListProps<T>) {
|
|
34
|
+
export function SelectList<T>({ value, options, onChange, className, optionLayout, by, noCheck, filterBy }: SelectListProps<T>) {
|
|
33
35
|
const [selected, setSelected] = useState(value);
|
|
36
|
+
const [filterValue, setFilterValue] = useState("");
|
|
37
|
+
|
|
34
38
|
const onSelect = (option: T) => {
|
|
35
39
|
setSelected(option);
|
|
36
40
|
onChange(option);
|
|
@@ -46,7 +50,13 @@ export function SelectList<T>({ value, options, onChange, className, optionLayou
|
|
|
46
50
|
}, [by]);
|
|
47
51
|
return (
|
|
48
52
|
<div className={clsx("", className)}>
|
|
53
|
+
{filterBy && (
|
|
54
|
+
<Input type="text" placeholder="Filter..." value={filterValue} onChange={(value) => setFilterValue(value)} />
|
|
55
|
+
)}
|
|
49
56
|
{options.map((option, i) => {
|
|
57
|
+
if (filterBy && !filterBy(filterValue)(option)) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
50
60
|
const isSelected = selected ? optionEquals(selected, option) : false;
|
|
51
61
|
let layout: OptionLayout;
|
|
52
62
|
if (optionLayout) {
|
|
@@ -53,7 +53,7 @@ export function SidePanel({ isOpen, title, onClose, children, panelWidth = 768,
|
|
|
53
53
|
onClick={onClose}
|
|
54
54
|
/>
|
|
55
55
|
)}
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
<div className="fixed inset-y-0 right-0 overflow-hidden">
|
|
58
58
|
<div className="absolute inset-0 overflow-hidden">
|
|
59
59
|
<div className="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 sm:pl-16">
|
|
@@ -71,17 +71,20 @@ export function SidePanel({ isOpen, title, onClose, children, panelWidth = 768,
|
|
|
71
71
|
className="absolute left-0 top-0 bottom-0 w-1 cursor-ew-resize hover:bg-indigo-500 transition-colors"
|
|
72
72
|
onMouseDown={handleDragStart}
|
|
73
73
|
/>
|
|
74
|
-
<div className="flex-1 flex flex-col overflow-y-scroll gap-4 bg-background py-
|
|
75
|
-
|
|
76
|
-
<div className="
|
|
77
|
-
<
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<
|
|
74
|
+
<div className="flex-1 flex flex-col overflow-y-scroll gap-4 bg-background py-2 shadow-xl">
|
|
75
|
+
{title && (
|
|
76
|
+
<div className="px-2 sm:px-4">
|
|
77
|
+
<div className="flex items-start justify-between">
|
|
78
|
+
<h2 className="w-full text-base font-semibold leading-6">
|
|
79
|
+
<div className="text-2xl">{title ?? ""}</div>
|
|
80
|
+
</h2>
|
|
81
|
+
<div className="ml-3 flex h-7 items-center">
|
|
82
|
+
<CloseButton onClose={onClose} />
|
|
83
|
+
</div>
|
|
82
84
|
</div>
|
|
83
85
|
</div>
|
|
84
|
-
|
|
86
|
+
)}
|
|
87
|
+
|
|
85
88
|
<div className="px-2 sm:px-4">
|
|
86
89
|
{children}
|
|
87
90
|
</div>
|
|
@@ -29,7 +29,8 @@ interface FilterProviderProps {
|
|
|
29
29
|
const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterProviderProps) => {
|
|
30
30
|
const url = new URL(window.location.href);
|
|
31
31
|
const searchParams = url.searchParams;
|
|
32
|
-
|
|
32
|
+
const [hasInitialized, setHasInitialized] = React.useState(false);
|
|
33
|
+
|
|
33
34
|
useEffect(() => {
|
|
34
35
|
try {
|
|
35
36
|
const params = new URLSearchParams(searchParams.toString());
|
|
@@ -42,16 +43,22 @@ const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterP
|
|
|
42
43
|
// Handle stringList with direct string array - always array format
|
|
43
44
|
values = `[${(filter.value as string[]).map(item => encodeURIComponent(item)).join(',')}]`;
|
|
44
45
|
} else if (Array.isArray(filter.value)) {
|
|
45
|
-
if (filter.multiple
|
|
46
|
-
// Handle multiple
|
|
47
|
-
values = `[${filter.value.map((item: any) => encodeURIComponent(item.value || '')).join(',')}]`;
|
|
46
|
+
if (filter.multiple) {
|
|
47
|
+
// Handle multiple filters - always use array format for multiple=true
|
|
48
|
+
values = `[${filter.value.map((item: any) => encodeURIComponent(item.value || item || '')).join(',')}]`;
|
|
49
|
+
} else if (filter.value.length > 1) {
|
|
50
|
+
// Handle multiple values for non-multiple filters
|
|
51
|
+
values = `[${filter.value.map((item: any) => encodeURIComponent(item.value || item || '')).join(',')}]`;
|
|
48
52
|
} else {
|
|
49
|
-
// Single value in array - don't use array format
|
|
53
|
+
// Single value in array for non-multiple filter - don't use array format
|
|
50
54
|
const firstValue = filter.value[0];
|
|
51
55
|
if (typeof firstValue === 'string') {
|
|
52
56
|
values = encodeURIComponent(firstValue);
|
|
57
|
+
} else if (typeof firstValue === 'object' && firstValue?.value !== undefined) {
|
|
58
|
+
// Handle FilterOption object
|
|
59
|
+
values = encodeURIComponent(String(firstValue.value));
|
|
53
60
|
} else {
|
|
54
|
-
values = encodeURIComponent(firstValue
|
|
61
|
+
values = encodeURIComponent(String(firstValue || ''));
|
|
55
62
|
}
|
|
56
63
|
}
|
|
57
64
|
} else {
|
|
@@ -73,14 +80,14 @@ const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterP
|
|
|
73
80
|
|
|
74
81
|
useEffect(() => {
|
|
75
82
|
const filtersParam = searchParams.get('filters');
|
|
76
|
-
if (filtersParam) {
|
|
83
|
+
if (filtersParam && filterGroups.length > 0 && !hasInitialized) {
|
|
77
84
|
try {
|
|
78
85
|
// Parse format with array indicators: filterName:value or filterName:[value1,value2]
|
|
79
86
|
const filterPairs = filtersParam.split(';');
|
|
80
87
|
const parsedFilters = filterPairs.map(pair => {
|
|
81
88
|
const [encodedName, valuesString] = pair.split(':');
|
|
82
89
|
const name = decodeURIComponent(encodedName);
|
|
83
|
-
|
|
90
|
+
|
|
84
91
|
let values: string[];
|
|
85
92
|
// Check if it's an array format [value1,value2]
|
|
86
93
|
if (valuesString.startsWith('[') && valuesString.endsWith(']')) {
|
|
@@ -100,8 +107,8 @@ const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterP
|
|
|
100
107
|
filterValue = values;
|
|
101
108
|
} else if (group?.type === 'text') {
|
|
102
109
|
// For text, return FilterOption array (single value for text inputs)
|
|
103
|
-
filterValue = values.length === 1 ? [{ value: values[0], label: values[0] }] :
|
|
104
|
-
|
|
110
|
+
filterValue = values.length === 1 ? [{ value: values[0], label: values[0] }] :
|
|
111
|
+
values.map(value => ({ value, label: value }));
|
|
105
112
|
} else {
|
|
106
113
|
// For other types, find options with labels
|
|
107
114
|
filterValue = values.map(value => {
|
|
@@ -123,21 +130,40 @@ const FilterProvider = ({ filters, setFilters, filterGroups, children }: FilterP
|
|
|
123
130
|
});
|
|
124
131
|
}
|
|
125
132
|
|
|
126
|
-
|
|
133
|
+
if (group?.multiple && !valuesString.startsWith('[') && !valuesString.endsWith(']')) {
|
|
134
|
+
if (group.type === 'stringList') {
|
|
135
|
+
filterValue = values;
|
|
136
|
+
} else {
|
|
137
|
+
if (!Array.isArray(filterValue)) {
|
|
138
|
+
filterValue = [filterValue];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Fallback: if group not found but we detected array format, assume it should be multiple
|
|
144
|
+
const shouldBeMultiple = group?.multiple || (!group && valuesString.startsWith('[') && valuesString.endsWith(']'));
|
|
145
|
+
|
|
146
|
+
const filter = {
|
|
127
147
|
name,
|
|
128
148
|
type: group?.type || 'select',
|
|
129
149
|
placeholder: group?.placeholder,
|
|
130
150
|
value: filterValue,
|
|
131
|
-
multiple:
|
|
151
|
+
multiple: shouldBeMultiple
|
|
132
152
|
};
|
|
153
|
+
|
|
154
|
+
return filter;
|
|
133
155
|
});
|
|
134
156
|
|
|
135
157
|
setFilters(parsedFilters);
|
|
158
|
+
setHasInitialized(true);
|
|
136
159
|
} catch (error) {
|
|
137
|
-
|
|
160
|
+
setHasInitialized(true);
|
|
138
161
|
}
|
|
162
|
+
} else if (filterGroups.length > 0 && !hasInitialized) {
|
|
163
|
+
// No URL params but we have groups - mark as initialized
|
|
164
|
+
setHasInitialized(true);
|
|
139
165
|
}
|
|
140
|
-
}, []);
|
|
166
|
+
}, [filterGroups, hasInitialized]);
|
|
141
167
|
|
|
142
168
|
return (
|
|
143
169
|
<FilterContext.Provider value={{ filters, setFilters, filterGroups }}>
|
|
@@ -287,7 +313,7 @@ const FilterBtn = ({ className }: { className?: string }) => {
|
|
|
287
313
|
{"Filter"}
|
|
288
314
|
</Button>
|
|
289
315
|
</PopoverTrigger>
|
|
290
|
-
<PopoverContent className="w-[300px] p-0" align="start">
|
|
316
|
+
<PopoverContent className="w-[300px] p-0" align="start" sideOffset={4}>
|
|
291
317
|
<Command>
|
|
292
318
|
{
|
|
293
319
|
filterGroups.find(group => group.name === selectedView)?.type === "select" && (
|
|
@@ -303,7 +329,7 @@ const FilterBtn = ({ className }: { className?: string }) => {
|
|
|
303
329
|
/>
|
|
304
330
|
)
|
|
305
331
|
}
|
|
306
|
-
<CommandList
|
|
332
|
+
<CommandList>
|
|
307
333
|
<CommandGroup>
|
|
308
334
|
{!selectedView ? getAvailableFilterGroups() : renderFilterOptions()}
|
|
309
335
|
</CommandGroup>
|
|
@@ -316,7 +342,7 @@ const FilterBtn = ({ className }: { className?: string }) => {
|
|
|
316
342
|
|
|
317
343
|
const FilterBar = ({ className }: { className?: string }) => {
|
|
318
344
|
const { filters, setFilters, filterGroups } = React.useContext(FilterContext);
|
|
319
|
-
|
|
345
|
+
|
|
320
346
|
return (
|
|
321
347
|
<div className={cn(className)}>
|
|
322
348
|
<Filters filters={filters} setFilters={setFilters} filterGroups={filterGroups} />
|
|
@@ -326,13 +352,13 @@ const FilterBar = ({ className }: { className?: string }) => {
|
|
|
326
352
|
|
|
327
353
|
const FilterClear = ({ className }: { className?: string }) => {
|
|
328
354
|
const { filters, setFilters } = React.useContext(FilterContext);
|
|
329
|
-
|
|
355
|
+
|
|
330
356
|
const hasActiveFilters = filters.filter((filter) => filter.value?.length > 0).length > 0;
|
|
331
|
-
|
|
357
|
+
|
|
332
358
|
if (!hasActiveFilters) {
|
|
333
359
|
return null;
|
|
334
360
|
}
|
|
335
|
-
|
|
361
|
+
|
|
336
362
|
return (
|
|
337
363
|
<Button
|
|
338
364
|
variant="outline"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { GripVerticalIcon } from "lucide-react"
|
|
3
|
+
import * as ResizablePrimitive from "react-resizable-panels"
|
|
4
|
+
|
|
5
|
+
import { cn } from "../libs/utils"
|
|
6
|
+
|
|
7
|
+
function ResizablePanelGroup({
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) {
|
|
11
|
+
return (
|
|
12
|
+
<ResizablePrimitive.PanelGroup
|
|
13
|
+
data-slot="resizable-panel-group"
|
|
14
|
+
className={cn(
|
|
15
|
+
"flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
|
|
16
|
+
className
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ResizablePanel({
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof ResizablePrimitive.Panel>) {
|
|
26
|
+
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function ResizableHandle({
|
|
30
|
+
withHandle,
|
|
31
|
+
className,
|
|
32
|
+
...props
|
|
33
|
+
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
|
|
34
|
+
withHandle?: boolean
|
|
35
|
+
}) {
|
|
36
|
+
return (
|
|
37
|
+
<ResizablePrimitive.PanelResizeHandle
|
|
38
|
+
data-slot="resizable-handle"
|
|
39
|
+
className={cn(
|
|
40
|
+
"bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90",
|
|
41
|
+
className
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
{withHandle && (
|
|
46
|
+
<div className="bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border">
|
|
47
|
+
<GripVerticalIcon className="size-2.5" />
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
50
|
+
</ResizablePrimitive.PanelResizeHandle>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
|
|
@@ -12,13 +12,15 @@ const TabsContext = React.createContext<{
|
|
|
12
12
|
setTab?: (name: string) => void;
|
|
13
13
|
responsive?: boolean;
|
|
14
14
|
variant?: "tabs" | "pills";
|
|
15
|
+
updateHash?: boolean;
|
|
15
16
|
}>({
|
|
16
17
|
size: undefined,
|
|
17
18
|
tabs: undefined,
|
|
18
19
|
current: undefined,
|
|
19
20
|
setTab: undefined,
|
|
20
21
|
responsive: false,
|
|
21
|
-
variant: "tabs"
|
|
22
|
+
variant: "tabs",
|
|
23
|
+
updateHash: true
|
|
22
24
|
});
|
|
23
25
|
|
|
24
26
|
interface TabsProps {
|
|
@@ -31,6 +33,7 @@ interface TabsProps {
|
|
|
31
33
|
onTabChange?: (tabName: string) => void;
|
|
32
34
|
responsive?: boolean;
|
|
33
35
|
variant?: "tabs" | "pills";
|
|
36
|
+
updateHash?: boolean;
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
const VTabs = ({
|
|
@@ -42,7 +45,8 @@ const VTabs = ({
|
|
|
42
45
|
children,
|
|
43
46
|
onTabChange,
|
|
44
47
|
responsive = false,
|
|
45
|
-
variant = "tabs"
|
|
48
|
+
variant = "tabs",
|
|
49
|
+
updateHash = true
|
|
46
50
|
}: TabsProps) => {
|
|
47
51
|
// Initialize value
|
|
48
52
|
const [value, setValue] = React.useState(() => {
|
|
@@ -99,6 +103,12 @@ const VTabs = ({
|
|
|
99
103
|
|
|
100
104
|
const handleValueChange = (newValue: string) => {
|
|
101
105
|
setValue(newValue);
|
|
106
|
+
|
|
107
|
+
// Update the URL hash when tab changes (only if updateHash is true and not controlled by parent)
|
|
108
|
+
if (updateHash && !current) {
|
|
109
|
+
window.location.hash = newValue;
|
|
110
|
+
}
|
|
111
|
+
|
|
102
112
|
if (onTabChange) {
|
|
103
113
|
onTabChange(newValue);
|
|
104
114
|
}
|
|
@@ -109,7 +119,7 @@ const VTabs = ({
|
|
|
109
119
|
}, [handleValueChange]);
|
|
110
120
|
|
|
111
121
|
return (
|
|
112
|
-
<TabsContext.Provider value={{ tabs, size: fullWidth ? tabs.length : 0, current: value, setTab, responsive: responsive, variant }}>
|
|
122
|
+
<TabsContext.Provider value={{ tabs, size: fullWidth ? tabs.length : 0, current: value, setTab, responsive: responsive, variant, updateHash }}>
|
|
113
123
|
<TabsPrimitive.Root
|
|
114
124
|
defaultValue={value || tabs[0]?.name}
|
|
115
125
|
value={value}
|
|
@@ -123,7 +133,7 @@ const VTabs = ({
|
|
|
123
133
|
};
|
|
124
134
|
|
|
125
135
|
const VTabsBar = ({ className }: { className?: string }) => {
|
|
126
|
-
const { tabs, size, current, setTab, responsive, variant } = React.useContext(TabsContext);
|
|
136
|
+
const { tabs, size, current, setTab, responsive, variant, updateHash } = React.useContext(TabsContext);
|
|
127
137
|
|
|
128
138
|
const fullWidth = size !== 0;
|
|
129
139
|
|
|
@@ -132,13 +142,13 @@ const VTabsBar = ({ className }: { className?: string }) => {
|
|
|
132
142
|
|
|
133
143
|
const tab = tabs.find(t => t.name === tabName);
|
|
134
144
|
|
|
135
|
-
if (tab?.href) {
|
|
145
|
+
if (tab?.href && updateHash) {
|
|
136
146
|
window.history.pushState(null, '', tab.href);
|
|
137
147
|
}
|
|
138
148
|
|
|
139
149
|
setTab(tabName);
|
|
140
150
|
|
|
141
|
-
}, [tabs, setTab]);
|
|
151
|
+
}, [tabs, setTab, updateHash]);
|
|
142
152
|
|
|
143
153
|
if (!tabs || !setTab) {
|
|
144
154
|
console.warn("TabsBar: No tabs provided or setTab not available");
|
|
@@ -23,7 +23,7 @@ export function RowSkeleton({ columns }: { columns: number }) {
|
|
|
23
23
|
<tr className="hover:bg-muted">
|
|
24
24
|
{Array(columns).fill(0).map((_, index) =>
|
|
25
25
|
<td key={index}>
|
|
26
|
-
<div className="animate-pulse rounded-xs h-5 bg-
|
|
26
|
+
<div className="animate-pulse rounded-xs h-5 bg-muted"></div>
|
|
27
27
|
</td>
|
|
28
28
|
)}
|
|
29
29
|
</tr>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Filter as BaseFilter, FilterProvider, FilterBtn, FilterBar, FilterClear, FilterGroup } from '@vertesia/ui/core';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { SearchInterface } from './utils/SearchInterface';
|
|
4
|
+
|
|
5
|
+
interface CollectionsFacetsNavProps {
|
|
6
|
+
facets: {
|
|
7
|
+
type?: any[];
|
|
8
|
+
dynamic?: any[];
|
|
9
|
+
};
|
|
10
|
+
search: SearchInterface;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Hook to create filter groups for collections
|
|
14
|
+
export function useCollectionsFilterGroups(facets: CollectionsFacetsNavProps['facets']): FilterGroup[] {
|
|
15
|
+
void facets;
|
|
16
|
+
const customFilterGroups: FilterGroup[] = [];
|
|
17
|
+
|
|
18
|
+
// Add name filter as text type
|
|
19
|
+
const nameFilterGroup = {
|
|
20
|
+
name: 'name',
|
|
21
|
+
placeholder: 'Name',
|
|
22
|
+
type: 'text' as const,
|
|
23
|
+
multiple: false
|
|
24
|
+
};
|
|
25
|
+
customFilterGroups.push(nameFilterGroup);
|
|
26
|
+
|
|
27
|
+
return customFilterGroups;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Hook to create filter change handler for collections
|
|
31
|
+
export function useCollectionsFilterHandler(search: SearchInterface) {
|
|
32
|
+
return (newFilters: BaseFilter[]) => {
|
|
33
|
+
if (newFilters.length === 0) {
|
|
34
|
+
// Clear filters without applying defaults - user wants to remove all filters
|
|
35
|
+
search.clearFilters(true);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Clear all filters first, then apply new ones
|
|
40
|
+
search.clearFilters(false);
|
|
41
|
+
|
|
42
|
+
newFilters.forEach(filter => {
|
|
43
|
+
if (filter.value && filter.value.length > 0) {
|
|
44
|
+
const filterName = filter.name;
|
|
45
|
+
let filterValue;
|
|
46
|
+
if (filter.type === 'stringList') {
|
|
47
|
+
filterValue = filter.value.map(v => typeof v === 'string' ? v : v.value);
|
|
48
|
+
} else if (filter.multiple) {
|
|
49
|
+
filterValue = Array.isArray(filter.value)
|
|
50
|
+
? filter.value.map((v: any) => typeof v === 'object' && v.value ? v.value : v)
|
|
51
|
+
: [typeof filter.value === 'object' && (filter.value as any).value ? (filter.value as any).value : filter.value];
|
|
52
|
+
} else {
|
|
53
|
+
// Single value - don't wrap in array
|
|
54
|
+
filterValue = Array.isArray(filter.value) && filter.value[0] && typeof filter.value[0] === 'object'
|
|
55
|
+
? (filter.value[0] as any).value
|
|
56
|
+
: Array.isArray(filter.value) && filter.value[0]
|
|
57
|
+
? filter.value[0]
|
|
58
|
+
: filter.value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
search.query[filterName] = filterValue;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
search.search();
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Component for collections filtering
|
|
70
|
+
export function CollectionsFacetsNav({ facets, search }: CollectionsFacetsNavProps) {
|
|
71
|
+
const [filters, setFilters] = useState<BaseFilter[]>([]);
|
|
72
|
+
const filterGroups = useCollectionsFilterGroups(facets);
|
|
73
|
+
const handleFilterLogic = useCollectionsFilterHandler(search);
|
|
74
|
+
|
|
75
|
+
const handleFilterChange: React.Dispatch<React.SetStateAction<BaseFilter[]>> = (value) => {
|
|
76
|
+
const newFilters = typeof value === 'function' ? value(filters) : value;
|
|
77
|
+
setFilters(newFilters);
|
|
78
|
+
handleFilterLogic(newFilters);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<FilterProvider
|
|
83
|
+
filterGroups={filterGroups}
|
|
84
|
+
filters={filters}
|
|
85
|
+
setFilters={handleFilterChange}
|
|
86
|
+
>
|
|
87
|
+
<div className="flex gap-2 items-center">
|
|
88
|
+
<FilterBtn />
|
|
89
|
+
<FilterBar />
|
|
90
|
+
<FilterClear />
|
|
91
|
+
</div>
|
|
92
|
+
</FilterProvider>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Filter as BaseFilter, FilterProvider, FilterBtn, FilterBar, FilterClear, FilterGroup } from '@vertesia/ui/core';
|
|
2
2
|
import { useUserSession } from '@vertesia/ui/session';
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import { VStringFacet } from './VStringFacet';
|
|
5
|
-
import { VTypeFacet } from './VTypeFacet';
|
|
6
|
-
import { SearchInterface } from './
|
|
4
|
+
import { VStringFacet } from './utils/VStringFacet';
|
|
5
|
+
import { VTypeFacet } from './utils/VTypeFacet';
|
|
6
|
+
import { SearchInterface } from './utils/SearchInterface';
|
|
7
7
|
|
|
8
8
|
interface DocumentsFacetsNavProps {
|
|
9
9
|
facets: {
|
|
@@ -22,7 +22,14 @@ export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets'
|
|
|
22
22
|
const customFilterGroups: FilterGroup[] = [];
|
|
23
23
|
|
|
24
24
|
customFilterGroups.push({
|
|
25
|
-
placeholder: '
|
|
25
|
+
placeholder: 'ID',
|
|
26
|
+
name: 'id',
|
|
27
|
+
type: 'text',
|
|
28
|
+
options: [],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
customFilterGroups.push({
|
|
32
|
+
placeholder: 'Name',
|
|
26
33
|
name: 'name',
|
|
27
34
|
type: 'text',
|
|
28
35
|
options: [],
|
|
@@ -94,7 +101,7 @@ export function useDocumentFilterHandler(search: SearchInterface) {
|
|
|
94
101
|
newFilters.forEach(filter => {
|
|
95
102
|
if (filter.value && filter.value.length > 0) {
|
|
96
103
|
const filterName = filter.name;
|
|
97
|
-
|
|
104
|
+
|
|
98
105
|
let filterValue;
|
|
99
106
|
if (filter.type === 'date' && filter.multiple) {
|
|
100
107
|
// Handle date range filters
|
|
@@ -117,21 +124,25 @@ export function useDocumentFilterHandler(search: SearchInterface) {
|
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
126
|
} else if (filter.multiple) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
if (Array.isArray(filter.value)) {
|
|
128
|
+
filterValue = filter.value.map((v: any) => typeof v === 'object' && v.value ? v.value : v);
|
|
129
|
+
} else {
|
|
130
|
+
const singleValue = typeof filter.value === 'object' && (filter.value as any).value ? (filter.value as any).value : filter.value;
|
|
131
|
+
filterValue = [singleValue];
|
|
132
|
+
}
|
|
123
133
|
} else {
|
|
124
134
|
// Single value - don't wrap in array
|
|
125
135
|
filterValue = Array.isArray(filter.value) && filter.value[0] && typeof filter.value[0] === 'object'
|
|
126
136
|
? (filter.value[0] as any).value
|
|
127
|
-
: Array.isArray(filter.value) && filter.value[0]
|
|
137
|
+
: Array.isArray(filter.value) && filter.value[0]
|
|
128
138
|
? filter.value[0]
|
|
129
139
|
: filter.value;
|
|
130
140
|
}
|
|
131
|
-
|
|
141
|
+
|
|
132
142
|
if (filterName === 'name') {
|
|
133
|
-
search.query.search_term = filterValue;
|
|
134
143
|
search.query.name = filterValue;
|
|
144
|
+
} else if (filterName === 'id') {
|
|
145
|
+
search.query.id = filterValue;
|
|
135
146
|
} else {
|
|
136
147
|
search.query[filterName] = filterValue;
|
|
137
148
|
}
|
|
@@ -3,7 +3,7 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { FacetBucket, FacetNameBucket } from '@vertesia/common';
|
|
4
4
|
import { SelectBox } from '@vertesia/ui/core';
|
|
5
5
|
import { useUserSession } from '@vertesia/ui/session';
|
|
6
|
-
import { facetOptionNameLabel } from './utils';
|
|
6
|
+
import { facetOptionNameLabel } from './utils/utils';
|
|
7
7
|
|
|
8
8
|
interface EnvironmentFacetProps {
|
|
9
9
|
search: any;
|