@vertesia/ui 1.1.0 → 1.1.1-dev.20260505.163000Z

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 (58) hide show
  1. package/lib/esm/features/agent/PayloadBuilder.js +13 -0
  2. package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
  3. package/lib/esm/features/agent/chat/DocumentPanel.js +1 -1
  4. package/lib/esm/features/agent/chat/DocumentPanel.js.map +1 -1
  5. package/lib/esm/features/facets/AgentRunnerFacetsNav.js +2 -2
  6. package/lib/esm/features/facets/AgentRunnerFacetsNav.js.map +1 -1
  7. package/lib/esm/features/facets/DocumentsFacetsNav.js +8 -5
  8. package/lib/esm/features/facets/DocumentsFacetsNav.js.map +1 -1
  9. package/lib/esm/features/facets/InteractionsFacetsNav.js.map +1 -1
  10. package/lib/esm/features/facets/RunsFacetsNav.js +2 -2
  11. package/lib/esm/features/facets/RunsFacetsNav.js.map +1 -1
  12. package/lib/esm/features/store/objects/DocumentSearchResults.js +2 -1
  13. package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
  14. package/lib/esm/features/store/objects/layout/documentLayout.js +2 -2
  15. package/lib/esm/features/store/objects/layout/documentLayout.js.map +1 -1
  16. package/lib/esm/features/store/objects/search/DocumentSearchContext.js +7 -1
  17. package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
  18. package/lib/esm/features/store/types/ContentObjectTypesSearch.js +2 -2
  19. package/lib/esm/features/store/types/ContentObjectTypesSearch.js.map +1 -1
  20. package/lib/esm/layout/FullHeightLayout.js +3 -0
  21. package/lib/esm/layout/FullHeightLayout.js.map +1 -1
  22. package/lib/tsconfig.tsbuildinfo +1 -1
  23. package/lib/types/features/agent/PayloadBuilder.d.ts +5 -0
  24. package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
  25. package/lib/types/features/facets/AgentRunnerFacetsNav.d.ts +3 -1
  26. package/lib/types/features/facets/AgentRunnerFacetsNav.d.ts.map +1 -1
  27. package/lib/types/features/facets/DocumentsFacetsNav.d.ts +2 -7
  28. package/lib/types/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
  29. package/lib/types/features/facets/InteractionsFacetsNav.d.ts +2 -3
  30. package/lib/types/features/facets/InteractionsFacetsNav.d.ts.map +1 -1
  31. package/lib/types/features/facets/RunsFacetsNav.d.ts +3 -1
  32. package/lib/types/features/facets/RunsFacetsNav.d.ts.map +1 -1
  33. package/lib/types/features/facets/utils/SearchInterface.d.ts +2 -0
  34. package/lib/types/features/facets/utils/SearchInterface.d.ts.map +1 -1
  35. package/lib/types/features/store/objects/DocumentSearchResults.d.ts.map +1 -1
  36. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +6 -6
  37. package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
  38. package/lib/types/features/store/types/ContentObjectTypesSearch.d.ts.map +1 -1
  39. package/lib/types/features/user/UserInfo.d.ts +2 -2
  40. package/lib/types/layout/FullHeightLayout.d.ts +1 -0
  41. package/lib/types/layout/FullHeightLayout.d.ts.map +1 -1
  42. package/lib/vertesia-ui-features.js +1 -1
  43. package/lib/vertesia-ui-features.js.map +1 -1
  44. package/lib/vertesia-ui-layout.js +1 -1
  45. package/lib/vertesia-ui-layout.js.map +1 -1
  46. package/package.json +6 -6
  47. package/src/features/agent/PayloadBuilder.tsx +16 -0
  48. package/src/features/agent/chat/DocumentPanel.tsx +1 -1
  49. package/src/features/facets/AgentRunnerFacetsNav.tsx +30 -8
  50. package/src/features/facets/DocumentsFacetsNav.tsx +11 -12
  51. package/src/features/facets/InteractionsFacetsNav.tsx +3 -4
  52. package/src/features/facets/RunsFacetsNav.tsx +31 -8
  53. package/src/features/facets/utils/SearchInterface.tsx +2 -0
  54. package/src/features/store/objects/DocumentSearchResults.tsx +25 -20
  55. package/src/features/store/objects/layout/documentLayout.tsx +4 -4
  56. package/src/features/store/objects/search/DocumentSearchContext.ts +10 -4
  57. package/src/features/store/types/ContentObjectTypesSearch.tsx +17 -12
  58. package/src/layout/FullHeightLayout.tsx +15 -0
@@ -1 +1 @@
1
- {"version":3,"file":"vertesia-ui-layout.js","sources":["esm/layout/FullHeightLayout.js","esm/layout/SidebarContext.js","esm/layout/TitleBar.js","esm/i18n/instance.js","esm/layout/Navbar.js","esm/i18n/index.js","esm/layout/Sidebar.js","esm/layout/AppLayout.js","esm/layout/RegionTag.js"],"sourcesContent":["import { jsx as _jsx } from \"react/jsx-runtime\";\nimport clsx from 'clsx';\nexport function FullHeightLayout({ className, children }) {\n return (_jsx(\"div\", { className: clsx(\"flex flex-col\", \"h-full\", \"overflow-y-auto\", \"px-2\", className), children: children }));\n}\nFullHeightLayout.Fixed = function Fixed({ heightClass, className, children }) {\n return (_jsx(\"div\", { className: clsx(\"w-full\", heightClass, className), children: children }));\n};\nFullHeightLayout.Body = function Body({ className, children }) {\n return (_jsx(\"div\", { className: clsx(\"grow overflow-auto\", \"min-h-0\", \"p-2\", className), children: children }));\n};\nFullHeightLayout.VR = function VDivider({}) {\n return (_jsx(\"div\", { className: \"w-[1px] border border-red-200\" }));\n};\nFullHeightLayout.HR = function HDivider({}) {\n return (_jsx(\"div\", { className: \"w-full h-1 border-b border-red-200\" }));\n};\nFullHeightLayout.Tab = function Tab({ children }) {\n return (_jsx(\"div\", { className: \"flex flex-col h-full\", children: children }));\n};\n//# sourceMappingURL=FullHeightLayout.js.map","import { createContext, useContext } from \"react\";\nexport const SidebarContext = createContext({\n isOpen: false,\n toggleMobile: () => void 0,\n toggleDesktop: () => void 0,\n});\nexport function useSidebarToggle() {\n return useContext(SidebarContext);\n}\n//# sourceMappingURL=SidebarContext.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nexport function TitleBar({ title }) {\n return _jsx(\"div\", { className: 'self-center text-lg font-semibold', children: title });\n}\n//# sourceMappingURL=TitleBar.js.map","import i18next from 'i18next';\nimport { initReactI18next } from 'react-i18next';\nimport ar from './locales/ar.json';\nimport de from './locales/de.json';\nimport en from './locales/en.json';\nimport es from './locales/es.json';\nimport fr from './locales/fr.json';\nimport it from './locales/it.json';\nimport ja from './locales/ja.json';\nimport ko from './locales/ko.json';\nimport pt from './locales/pt.json';\nimport ru from './locales/ru.json';\nimport tr from './locales/tr.json';\nimport zh from './locales/zh.json';\nimport zhTW from './locales/zh-TW.json';\nexport const NAMESPACE = 'vertesia.ui';\n// Scoped instance — does NOT touch the global i18next singleton\nconst i18nInstance = i18next.createInstance();\nvoid i18nInstance.use(initReactI18next).init({\n resources: {\n ar: { [NAMESPACE]: ar },\n de: { [NAMESPACE]: de },\n en: { [NAMESPACE]: en },\n es: { [NAMESPACE]: es },\n fr: { [NAMESPACE]: fr },\n it: { [NAMESPACE]: it },\n ja: { [NAMESPACE]: ja },\n ko: { [NAMESPACE]: ko },\n pt: { [NAMESPACE]: pt },\n ru: { [NAMESPACE]: ru },\n tr: { [NAMESPACE]: tr },\n zh: { [NAMESPACE]: zh },\n 'zh-TW': { [NAMESPACE]: zhTW },\n },\n fallbackLng: 'en',\n ns: [NAMESPACE],\n defaultNS: NAMESPACE,\n interpolation: {\n escapeValue: false, // React already escapes\n },\n react: {\n useSuspense: false, // Translations are bundled, no async loading\n },\n});\nexport { i18nInstance };\n//# sourceMappingURL=instance.js.map","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\nimport { Menu, Search } from 'lucide-react';\nimport { Button } from '@vertesia/ui/core';\nimport { useSidebarToggle } from './SidebarContext.js';\nimport { TitleBar } from './TitleBar.js';\nimport { useUITranslation } from '../i18n/index.js';\nexport function Navbar({ children, logo, onSearch, title }) {\n return (_jsxs(\"div\", { className: \"sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b px-4 shadow-2xs sm:gap-x-6 sm:px-6 lg:px-8\", children: [_jsx(HamburgerButton, {}), _jsx(\"div\", { className: \"lg:hidden\", children: logo }), onSearch && _jsx(NavbarSeparator, { visible: 'mobile' }), _jsxs(\"div\", { className: \"flex flex-1 gap-x-4 self-stretch lg:gap-x-6\", children: [_jsx(TitleBar, { title: title }), onSearch && _jsx(SearchBox, { onSearch: onSearch }), _jsx(\"div\", { className: \"flex items-center gap-x-4 lg:gap-x-6 ml-auto\", children: children })] })] }));\n}\nfunction SearchBox({}) {\n const { t } = useUITranslation();\n return (_jsxs(\"form\", { className: \"relative flex flex-1\", action: \"#\", method: \"GET\", children: [_jsx(\"label\", { htmlFor: \"search-field\", className: \"sr-only\", children: t('layout.search') }), _jsx(Search, { className: \"pointer-events-none absolute inset-y-0 left-0 h-full w-5 text-gray-400\", \"aria-hidden\": \"true\" }), _jsx(\"input\", { id: \"search-field\", className: \"block h-full w-full border-0 py-0 pl-8 pr-0 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm\", placeholder: t('layout.searchPlaceholder'), type: \"search\", name: \"search\" })] }));\n}\nexport function HamburgerButton() {\n const { toggleDesktop, toggleMobile } = useSidebarToggle();\n const toggle = () => {\n if (window.innerWidth < 1024) {\n toggleMobile();\n }\n else {\n toggleDesktop();\n }\n };\n return (_jsx(_Fragment, { children: _jsx(Button, { variant: 'ghost', size: 'icon', onClick: () => toggle(), className: \"p-2 rounded-full transition-colors w-full text-center \", children: _jsx(Menu, { \"aria-hidden\": \"true\", size: 24 }) }) }));\n}\nexport function NavbarSeparator({ visible }) {\n let visibility = \"\";\n if (visible) {\n visibility = visible === \"mobile\" ? \"lg:hidden\" : \"hidden lg:block\";\n }\n return (_jsx(\"div\", { className: `h-6 w-px bg-gray-900/10 dark:bg-slate-900/0.1 ${visibility}`, \"aria-hidden\": \"true\" }));\n}\nexport function NavbarIconButton({ title, icon: Icon, onClick }) {\n return (_jsxs(\"button\", { type: \"button\", className: \"-m-2.5 p-2.5 text-gray-400 dark:text-slate-50 hover:text-gray-500\", onClick: onClick, children: [_jsx(\"span\", { className: \"sr-only\", children: title }), _jsx(Icon, { className: \"size-6\", \"aria-hidden\": \"true\", title: title })] }));\n}\nexport function NavbarButton({ children, onClick }) {\n return (_jsx(Button, { onClick: onClick, children: children }));\n}\nexport function NavbarLink({ href, onClick, children }) {\n return (_jsx(\"a\", { className: \"dark:text-slate-50\", href: href, onClick: onClick, children: children }));\n}\n//# sourceMappingURL=Navbar.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect } from 'react';\nimport { I18nextProvider, useTranslation } from 'react-i18next';\nimport { i18nInstance, NAMESPACE } from './instance.js';\nfunction detectLanguage(lng) {\n return lng ?? navigator.language?.split('-')[0] ?? 'en';\n}\nexport function I18nProvider({ lng, children }) {\n // Set language synchronously on first render to avoid flash of wrong language\n const language = detectLanguage(lng);\n if (i18nInstance.language !== language) {\n void i18nInstance.changeLanguage(language);\n }\n // Also react to prop changes\n useEffect(() => {\n const lang = detectLanguage(lng);\n if (i18nInstance.language !== lang) {\n void i18nInstance.changeLanguage(lang);\n }\n }, [lng]);\n return (_jsx(I18nextProvider, { i18n: i18nInstance, children: children }));\n}\n/**\n * Hook for components inside @vertesia/ui to get translation functions.\n * Always binds to the 'vertesia.ui' namespace on the scoped instance.\n */\nexport function useUITranslation() {\n return useTranslation(NAMESPACE, { i18n: i18nInstance });\n}\nexport { i18nInstance, NAMESPACE } from './instance.js';\n//# sourceMappingURL=index.js.map","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\nimport clsx from 'clsx';\nimport { useSidebarToggle } from './SidebarContext';\nimport { Dot } from 'lucide-react';\nimport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@vertesia/ui/core';\nimport { Nav } from \"@vertesia/ui/router\";\nexport function Sidebar({ children, logo, className }) {\n return (_jsxs(\"div\", { className: clsx(className || \"bg-indigo-600 dark:bg-indigo-950\", \"flex flex-col h-full\"), children: [logo &&\n _jsx(\"div\", { className: \"-mx-2 flex h-auto my-4 shrink-0 self-start\", children: logo }), _jsx(\"div\", { className: \"flex-1 min-h-0 overflow-hidden px-0 lg:px-2\", children: _jsx(\"nav\", { className: \"h-full flex flex-col\", children: _jsx(\"ul\", { role: \"list\", className: \"flex flex-col gap-y-2 overflow-y-auto h-full\", children: children }) }) })] }));\n}\nexport function SidebarSection({ children, title, action, isFooter = false, className }) {\n const { isOpen } = useSidebarToggle();\n let header = isOpen ? _jsxs(_Fragment, { children: [title || \"\", action] }) : _jsx(Dot, { className: 'size-6' });\n return (_jsxs(\"li\", { className: isFooter ? 'mt-auto' : '', children: [title && _jsx(\"div\", { className: \"text-xs font-medium h-8 flex items-center gap-x-2 px-2 text-sidebar-foreground/70\", children: header }), _jsx(\"ul\", { \"data-sidebar\": \"menu\", className: clsx(\"flex w-full min-w-0 flex-col gap-1\", className), children: children })] }));\n}\nexport function SidebarTooltip({ children, text }) {\n const { isOpen } = useSidebarToggle();\n return (isOpen ? _jsx(_Fragment, { children: children }) :\n _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: children }), _jsx(TooltipContent, { side: 'right', children: text })] }) }));\n}\nexport function SidebarItem({ external, className, tools, children, icon: Icon, href, to, current, onClick, replace }) {\n const { toggleMobile } = useSidebarToggle();\n const _closeSideBar = () => {\n setTimeout(() => {\n toggleMobile(false);\n }, 100);\n };\n const onClickWrapper = (event) => {\n if (external) {\n window.open(href, '_blank');\n event.preventDefault(); // Prevent default link behavior\n event.stopPropagation(); // Stop the event from propagating\n }\n else if (onClick) {\n onClick(event);\n }\n };\n return (_jsx(\"li\", { children: _jsx(Nav, { to: to, onClick: _closeSideBar, replace: replace, children: _jsx(SidebarTooltip, { text: children, children: _jsxs(\"a\", { href: href, onClick: onClickWrapper, className: clsx(current\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:text-sidebar-accent-foreground hover:bg-sidebar-accent', 'group flex gap-x-3 rounded-md px-2 py-1.5 text-sm items-center h-8', className), children: [Icon &&\n _jsx(Icon, { className: clsx(current\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:text-sidebar-accent-foreground hover:bg-sidebar-accent', 'size-4 shrink-0'), \"aria-hidden\": \"true\" }), children, tools && _jsx(\"div\", { className: 'flex items-center ml-auto', children: tools })] }) }) }) }));\n}\n//# sourceMappingURL=Sidebar.js.map","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\nimport clsx from 'clsx';\nimport { useEffect, useState } from 'react';\nimport { SidePanel } from '@vertesia/ui/core';\n// import { FullHeightLayout } from './FullHeightLayout.js'\nimport { Navbar } from './Navbar.js';\nimport { Sidebar } from './Sidebar.js';\nimport { SidebarContext } from './SidebarContext.js';\nexport function AppLayout({ sidebarClassName, className, title, children, logo, navbar, sidebar, mainNav }) {\n if (localStorage.getItem('desktopSidebarOpen') === null) {\n localStorage.setItem('desktopSidebarOpen', 'true');\n }\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(localStorage.getItem('desktopSidebarOpen') === 'true');\n const [isLargeScreen, setIsLargeScreen] = useState(window.innerWidth >= 1024);\n useEffect(() => {\n const handleResize = () => {\n setIsLargeScreen(window.innerWidth >= 1024);\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n const sidebarContextValue = {\n isOpen: isLargeScreen ? desktopSidebarOpen : sidebarOpen,\n toggleDesktop: (value) => {\n if (value === undefined) {\n setDesktopSidebarOpen(!desktopSidebarOpen);\n }\n else {\n setDesktopSidebarOpen(value);\n }\n localStorage.setItem('desktopSidebarOpen', JSON.stringify(!desktopSidebarOpen));\n },\n toggleMobile: (value) => {\n if (value === undefined) {\n setSidebarOpen(!sidebarOpen);\n }\n else {\n setSidebarOpen(value);\n }\n },\n };\n return (_jsx(_Fragment, { children: _jsx(\"div\", { className: 'flex flex-col h-screen overflow-y-hidden', children: _jsxs(SidebarContext.Provider, { value: sidebarContextValue, children: [_jsx(\"div\", { className: 'w-full', children: mainNav }), _jsxs(\"div\", { className: 'flex h-full overflow-y-auto w-full', children: [_jsx(\"div\", { className: \"lg:hidden\", children: _jsx(SidePanel, { className: 'bg-sidebar', isOpen: sidebarOpen, onClose: () => setSidebarOpen(false), side: \"left\", panelWidth: 288, resizable: false, backdrop: true, children: _jsx(Sidebar, { logo: logo, className: sidebarClassName, children: sidebar }) }) }), _jsx(\"div\", { className: `hidden lg:block relative transition-all duration-300 ${desktopSidebarOpen ? 'w-72' : 'w-12'}`, children: _jsx(Sidebar, { logo: logo, className: sidebarClassName, children: sidebar }) }), _jsxs(\"div\", { className: \"w-full h-full overflow-y-hidden\", children: [navbar ? (_jsx(Navbar, { title: title, logo: logo, children: navbar })) : null, _jsx(\"main\", { className: clsx(\"flex-1 h-full w-full relative flex flex-col\", className), children: children })] })] })] }) }) }));\n}\n//# sourceMappingURL=AppLayout.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { cn } from '@vertesia/ui/core';\nimport { Env } from '@vertesia/ui/env';\nconst regionLabels = {\n eu: 'EU',\n jp: 'JP',\n};\nexport function RegionTag({ className }) {\n const region = Env.region;\n // Only show for non-US regions (US is default, no need to display)\n if (!region || region === 'us')\n return null;\n return (_jsx(\"div\", { className: cn('text-[0.6rem] font-semibold px-1.5 rounded-3xl leading-4', 'bg-info text-white', className), children: regionLabels[region] ?? region.toUpperCase() }));\n}\n//# sourceMappingURL=RegionTag.js.map"],"names":["FullHeightLayout","className","children","_jsx","clsx","Fixed","heightClass","Body","VR","HR","Tab","SidebarContext","createContext","isOpen","toggleMobile","toggleDesktop","useSidebarToggle","useContext","TitleBar","title","NAMESPACE","i18nInstance","i18next","createInstance","Navbar","logo","onSearch","_jsxs","HamburgerButton","NavbarSeparator","visible","SearchBox","t","useTranslation","i18n","action","method","htmlFor","Search","id","placeholder","type","name","_Fragment","Button","variant","size","onClick","window","innerWidth","Menu","visibility","NavbarIconButton","icon","Icon","NavbarButton","NavbarLink","href","Sidebar","role","SidebarSection","isFooter","header","Dot","SidebarTooltip","text","TooltipProvider","Tooltip","TooltipTrigger","asChild","TooltipContent","side","SidebarItem","external","tools","to","current","replace","Nav","setTimeout","event","open","preventDefault","stopPropagation","AppLayout","sidebarClassName","navbar","sidebar","mainNav","localStorage","getItem","setItem","sidebarOpen","setSidebarOpen","useState","desktopSidebarOpen","setDesktopSidebarOpen","isLargeScreen","setIsLargeScreen","useEffect","handleResize","addEventListener","removeEventListener","sidebarContextValue","value","undefined","JSON","stringify","Provider","SidePanel","onClose","panelWidth","resizable","backdrop","use","initReactI18next","init","resources","ar","de","en","es","fr","it","ja","ko","pt","ru","tr","zh","fallbackLng","ns","defaultNS","interpolation","escapeValue","react","useSuspense","regionLabels","eu","jp","RegionTag","region","Env","cn","toUpperCase"],"mappings":"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"}
1
+ {"version":3,"file":"vertesia-ui-layout.js","sources":["esm/layout/FullHeightLayout.js","esm/layout/SidebarContext.js","esm/layout/TitleBar.js","esm/i18n/instance.js","esm/layout/Navbar.js","esm/i18n/index.js","esm/layout/Sidebar.js","esm/layout/AppLayout.js","esm/layout/RegionTag.js"],"sourcesContent":["import { jsx as _jsx } from \"react/jsx-runtime\";\nimport clsx from 'clsx';\nexport function FullHeightLayout({ className, children }) {\n return (_jsx(\"div\", { className: clsx(\"flex flex-col\", \"h-full\", \"overflow-y-auto\", \"px-2\", className), children: children }));\n}\nFullHeightLayout.Fixed = function Fixed({ heightClass, className, children }) {\n return (_jsx(\"div\", { className: clsx(\"w-full\", heightClass, className), children: children }));\n};\nFullHeightLayout.Body = function Body({ className, children }) {\n return (_jsx(\"div\", { className: clsx(\"grow overflow-auto\", \"min-h-0\", \"p-2\", className), children: children }));\n};\nFullHeightLayout.VR = function VDivider({}) {\n return (_jsx(\"div\", { className: \"w-[1px] border border-red-200\" }));\n};\nFullHeightLayout.HR = function HDivider({}) {\n return (_jsx(\"div\", { className: \"w-full h-1 border-b border-red-200\" }));\n};\nFullHeightLayout.Flex = function Flex({ className, children }) {\n return (_jsx(\"div\", { className: clsx(\"grow flex flex-col\", \"overflow-hidden min-h-0\", \"p-2\", className), children: children }));\n};\nFullHeightLayout.Tab = function Tab({ children }) {\n return (_jsx(\"div\", { className: \"flex flex-col h-full\", children: children }));\n};\n//# sourceMappingURL=FullHeightLayout.js.map","import { createContext, useContext } from \"react\";\nexport const SidebarContext = createContext({\n isOpen: false,\n toggleMobile: () => void 0,\n toggleDesktop: () => void 0,\n});\nexport function useSidebarToggle() {\n return useContext(SidebarContext);\n}\n//# sourceMappingURL=SidebarContext.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nexport function TitleBar({ title }) {\n return _jsx(\"div\", { className: 'self-center text-lg font-semibold', children: title });\n}\n//# sourceMappingURL=TitleBar.js.map","import i18next from 'i18next';\nimport { initReactI18next } from 'react-i18next';\nimport ar from './locales/ar.json';\nimport de from './locales/de.json';\nimport en from './locales/en.json';\nimport es from './locales/es.json';\nimport fr from './locales/fr.json';\nimport it from './locales/it.json';\nimport ja from './locales/ja.json';\nimport ko from './locales/ko.json';\nimport pt from './locales/pt.json';\nimport ru from './locales/ru.json';\nimport tr from './locales/tr.json';\nimport zh from './locales/zh.json';\nimport zhTW from './locales/zh-TW.json';\nexport const NAMESPACE = 'vertesia.ui';\n// Scoped instance — does NOT touch the global i18next singleton\nconst i18nInstance = i18next.createInstance();\nvoid i18nInstance.use(initReactI18next).init({\n resources: {\n ar: { [NAMESPACE]: ar },\n de: { [NAMESPACE]: de },\n en: { [NAMESPACE]: en },\n es: { [NAMESPACE]: es },\n fr: { [NAMESPACE]: fr },\n it: { [NAMESPACE]: it },\n ja: { [NAMESPACE]: ja },\n ko: { [NAMESPACE]: ko },\n pt: { [NAMESPACE]: pt },\n ru: { [NAMESPACE]: ru },\n tr: { [NAMESPACE]: tr },\n zh: { [NAMESPACE]: zh },\n 'zh-TW': { [NAMESPACE]: zhTW },\n },\n fallbackLng: 'en',\n ns: [NAMESPACE],\n defaultNS: NAMESPACE,\n interpolation: {\n escapeValue: false, // React already escapes\n },\n react: {\n useSuspense: false, // Translations are bundled, no async loading\n },\n});\nexport { i18nInstance };\n//# sourceMappingURL=instance.js.map","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\nimport { Menu, Search } from 'lucide-react';\nimport { Button } from '@vertesia/ui/core';\nimport { useSidebarToggle } from './SidebarContext.js';\nimport { TitleBar } from './TitleBar.js';\nimport { useUITranslation } from '../i18n/index.js';\nexport function Navbar({ children, logo, onSearch, title }) {\n return (_jsxs(\"div\", { className: \"sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b px-4 shadow-2xs sm:gap-x-6 sm:px-6 lg:px-8\", children: [_jsx(HamburgerButton, {}), _jsx(\"div\", { className: \"lg:hidden\", children: logo }), onSearch && _jsx(NavbarSeparator, { visible: 'mobile' }), _jsxs(\"div\", { className: \"flex flex-1 gap-x-4 self-stretch lg:gap-x-6\", children: [_jsx(TitleBar, { title: title }), onSearch && _jsx(SearchBox, { onSearch: onSearch }), _jsx(\"div\", { className: \"flex items-center gap-x-4 lg:gap-x-6 ml-auto\", children: children })] })] }));\n}\nfunction SearchBox({}) {\n const { t } = useUITranslation();\n return (_jsxs(\"form\", { className: \"relative flex flex-1\", action: \"#\", method: \"GET\", children: [_jsx(\"label\", { htmlFor: \"search-field\", className: \"sr-only\", children: t('layout.search') }), _jsx(Search, { className: \"pointer-events-none absolute inset-y-0 left-0 h-full w-5 text-gray-400\", \"aria-hidden\": \"true\" }), _jsx(\"input\", { id: \"search-field\", className: \"block h-full w-full border-0 py-0 pl-8 pr-0 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm\", placeholder: t('layout.searchPlaceholder'), type: \"search\", name: \"search\" })] }));\n}\nexport function HamburgerButton() {\n const { toggleDesktop, toggleMobile } = useSidebarToggle();\n const toggle = () => {\n if (window.innerWidth < 1024) {\n toggleMobile();\n }\n else {\n toggleDesktop();\n }\n };\n return (_jsx(_Fragment, { children: _jsx(Button, { variant: 'ghost', size: 'icon', onClick: () => toggle(), className: \"p-2 rounded-full transition-colors w-full text-center \", children: _jsx(Menu, { \"aria-hidden\": \"true\", size: 24 }) }) }));\n}\nexport function NavbarSeparator({ visible }) {\n let visibility = \"\";\n if (visible) {\n visibility = visible === \"mobile\" ? \"lg:hidden\" : \"hidden lg:block\";\n }\n return (_jsx(\"div\", { className: `h-6 w-px bg-gray-900/10 dark:bg-slate-900/0.1 ${visibility}`, \"aria-hidden\": \"true\" }));\n}\nexport function NavbarIconButton({ title, icon: Icon, onClick }) {\n return (_jsxs(\"button\", { type: \"button\", className: \"-m-2.5 p-2.5 text-gray-400 dark:text-slate-50 hover:text-gray-500\", onClick: onClick, children: [_jsx(\"span\", { className: \"sr-only\", children: title }), _jsx(Icon, { className: \"size-6\", \"aria-hidden\": \"true\", title: title })] }));\n}\nexport function NavbarButton({ children, onClick }) {\n return (_jsx(Button, { onClick: onClick, children: children }));\n}\nexport function NavbarLink({ href, onClick, children }) {\n return (_jsx(\"a\", { className: \"dark:text-slate-50\", href: href, onClick: onClick, children: children }));\n}\n//# sourceMappingURL=Navbar.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useEffect } from 'react';\nimport { I18nextProvider, useTranslation } from 'react-i18next';\nimport { i18nInstance, NAMESPACE } from './instance.js';\nfunction detectLanguage(lng) {\n return lng ?? navigator.language?.split('-')[0] ?? 'en';\n}\nexport function I18nProvider({ lng, children }) {\n // Set language synchronously on first render to avoid flash of wrong language\n const language = detectLanguage(lng);\n if (i18nInstance.language !== language) {\n void i18nInstance.changeLanguage(language);\n }\n // Also react to prop changes\n useEffect(() => {\n const lang = detectLanguage(lng);\n if (i18nInstance.language !== lang) {\n void i18nInstance.changeLanguage(lang);\n }\n }, [lng]);\n return (_jsx(I18nextProvider, { i18n: i18nInstance, children: children }));\n}\n/**\n * Hook for components inside @vertesia/ui to get translation functions.\n * Always binds to the 'vertesia.ui' namespace on the scoped instance.\n */\nexport function useUITranslation() {\n return useTranslation(NAMESPACE, { i18n: i18nInstance });\n}\nexport { i18nInstance, NAMESPACE } from './instance.js';\n//# sourceMappingURL=index.js.map","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\nimport clsx from 'clsx';\nimport { useSidebarToggle } from './SidebarContext';\nimport { Dot } from 'lucide-react';\nimport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@vertesia/ui/core';\nimport { Nav } from \"@vertesia/ui/router\";\nexport function Sidebar({ children, logo, className }) {\n return (_jsxs(\"div\", { className: clsx(className || \"bg-indigo-600 dark:bg-indigo-950\", \"flex flex-col h-full\"), children: [logo &&\n _jsx(\"div\", { className: \"-mx-2 flex h-auto my-4 shrink-0 self-start\", children: logo }), _jsx(\"div\", { className: \"flex-1 min-h-0 overflow-hidden px-0 lg:px-2\", children: _jsx(\"nav\", { className: \"h-full flex flex-col\", children: _jsx(\"ul\", { role: \"list\", className: \"flex flex-col gap-y-2 overflow-y-auto h-full\", children: children }) }) })] }));\n}\nexport function SidebarSection({ children, title, action, isFooter = false, className }) {\n const { isOpen } = useSidebarToggle();\n let header = isOpen ? _jsxs(_Fragment, { children: [title || \"\", action] }) : _jsx(Dot, { className: 'size-6' });\n return (_jsxs(\"li\", { className: isFooter ? 'mt-auto' : '', children: [title && _jsx(\"div\", { className: \"text-xs font-medium h-8 flex items-center gap-x-2 px-2 text-sidebar-foreground/70\", children: header }), _jsx(\"ul\", { \"data-sidebar\": \"menu\", className: clsx(\"flex w-full min-w-0 flex-col gap-1\", className), children: children })] }));\n}\nexport function SidebarTooltip({ children, text }) {\n const { isOpen } = useSidebarToggle();\n return (isOpen ? _jsx(_Fragment, { children: children }) :\n _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: children }), _jsx(TooltipContent, { side: 'right', children: text })] }) }));\n}\nexport function SidebarItem({ external, className, tools, children, icon: Icon, href, to, current, onClick, replace }) {\n const { toggleMobile } = useSidebarToggle();\n const _closeSideBar = () => {\n setTimeout(() => {\n toggleMobile(false);\n }, 100);\n };\n const onClickWrapper = (event) => {\n if (external) {\n window.open(href, '_blank');\n event.preventDefault(); // Prevent default link behavior\n event.stopPropagation(); // Stop the event from propagating\n }\n else if (onClick) {\n onClick(event);\n }\n };\n return (_jsx(\"li\", { children: _jsx(Nav, { to: to, onClick: _closeSideBar, replace: replace, children: _jsx(SidebarTooltip, { text: children, children: _jsxs(\"a\", { href: href, onClick: onClickWrapper, className: clsx(current\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:text-sidebar-accent-foreground hover:bg-sidebar-accent', 'group flex gap-x-3 rounded-md px-2 py-1.5 text-sm items-center h-8', className), children: [Icon &&\n _jsx(Icon, { className: clsx(current\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:text-sidebar-accent-foreground hover:bg-sidebar-accent', 'size-4 shrink-0'), \"aria-hidden\": \"true\" }), children, tools && _jsx(\"div\", { className: 'flex items-center ml-auto', children: tools })] }) }) }) }));\n}\n//# sourceMappingURL=Sidebar.js.map","import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from \"react/jsx-runtime\";\nimport clsx from 'clsx';\nimport { useEffect, useState } from 'react';\nimport { SidePanel } from '@vertesia/ui/core';\n// import { FullHeightLayout } from './FullHeightLayout.js'\nimport { Navbar } from './Navbar.js';\nimport { Sidebar } from './Sidebar.js';\nimport { SidebarContext } from './SidebarContext.js';\nexport function AppLayout({ sidebarClassName, className, title, children, logo, navbar, sidebar, mainNav }) {\n if (localStorage.getItem('desktopSidebarOpen') === null) {\n localStorage.setItem('desktopSidebarOpen', 'true');\n }\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [desktopSidebarOpen, setDesktopSidebarOpen] = useState(localStorage.getItem('desktopSidebarOpen') === 'true');\n const [isLargeScreen, setIsLargeScreen] = useState(window.innerWidth >= 1024);\n useEffect(() => {\n const handleResize = () => {\n setIsLargeScreen(window.innerWidth >= 1024);\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n const sidebarContextValue = {\n isOpen: isLargeScreen ? desktopSidebarOpen : sidebarOpen,\n toggleDesktop: (value) => {\n if (value === undefined) {\n setDesktopSidebarOpen(!desktopSidebarOpen);\n }\n else {\n setDesktopSidebarOpen(value);\n }\n localStorage.setItem('desktopSidebarOpen', JSON.stringify(!desktopSidebarOpen));\n },\n toggleMobile: (value) => {\n if (value === undefined) {\n setSidebarOpen(!sidebarOpen);\n }\n else {\n setSidebarOpen(value);\n }\n },\n };\n return (_jsx(_Fragment, { children: _jsx(\"div\", { className: 'flex flex-col h-screen overflow-y-hidden', children: _jsxs(SidebarContext.Provider, { value: sidebarContextValue, children: [_jsx(\"div\", { className: 'w-full', children: mainNav }), _jsxs(\"div\", { className: 'flex h-full overflow-y-auto w-full', children: [_jsx(\"div\", { className: \"lg:hidden\", children: _jsx(SidePanel, { className: 'bg-sidebar', isOpen: sidebarOpen, onClose: () => setSidebarOpen(false), side: \"left\", panelWidth: 288, resizable: false, backdrop: true, children: _jsx(Sidebar, { logo: logo, className: sidebarClassName, children: sidebar }) }) }), _jsx(\"div\", { className: `hidden lg:block relative transition-all duration-300 ${desktopSidebarOpen ? 'w-72' : 'w-12'}`, children: _jsx(Sidebar, { logo: logo, className: sidebarClassName, children: sidebar }) }), _jsxs(\"div\", { className: \"w-full h-full overflow-y-hidden\", children: [navbar ? (_jsx(Navbar, { title: title, logo: logo, children: navbar })) : null, _jsx(\"main\", { className: clsx(\"flex-1 h-full w-full relative flex flex-col\", className), children: children })] })] })] }) }) }));\n}\n//# sourceMappingURL=AppLayout.js.map","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { cn } from '@vertesia/ui/core';\nimport { Env } from '@vertesia/ui/env';\nconst regionLabels = {\n eu: 'EU',\n jp: 'JP',\n};\nexport function RegionTag({ className }) {\n const region = Env.region;\n // Only show for non-US regions (US is default, no need to display)\n if (!region || region === 'us')\n return null;\n return (_jsx(\"div\", { className: cn('text-[0.6rem] font-semibold px-1.5 rounded-3xl leading-4', 'bg-info text-white', className), children: regionLabels[region] ?? region.toUpperCase() }));\n}\n//# sourceMappingURL=RegionTag.js.map"],"names":["FullHeightLayout","className","children","_jsx","clsx","Fixed","heightClass","Body","VR","HR","Flex","Tab","SidebarContext","createContext","isOpen","toggleMobile","toggleDesktop","useSidebarToggle","useContext","TitleBar","title","NAMESPACE","i18nInstance","i18next","createInstance","Navbar","logo","onSearch","_jsxs","HamburgerButton","NavbarSeparator","visible","SearchBox","t","useTranslation","i18n","action","method","htmlFor","Search","id","placeholder","type","name","_Fragment","Button","variant","size","onClick","window","innerWidth","Menu","visibility","NavbarIconButton","icon","Icon","NavbarButton","NavbarLink","href","Sidebar","role","SidebarSection","isFooter","header","Dot","SidebarTooltip","text","TooltipProvider","Tooltip","TooltipTrigger","asChild","TooltipContent","side","SidebarItem","external","tools","to","current","replace","Nav","setTimeout","event","open","preventDefault","stopPropagation","AppLayout","sidebarClassName","navbar","sidebar","mainNav","localStorage","getItem","setItem","sidebarOpen","setSidebarOpen","useState","desktopSidebarOpen","setDesktopSidebarOpen","isLargeScreen","setIsLargeScreen","useEffect","handleResize","addEventListener","removeEventListener","sidebarContextValue","value","undefined","JSON","stringify","Provider","SidePanel","onClose","panelWidth","resizable","backdrop","use","initReactI18next","init","resources","ar","de","en","es","fr","it","ja","ko","pt","ru","tr","zh","fallbackLng","ns","defaultNS","interpolation","escapeValue","react","useSuspense","regionLabels","eu","jp","RegionTag","region","Env","cn","toUpperCase"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertesia/ui",
3
- "version": "1.1.0",
3
+ "version": "1.1.1-dev.20260505.163000Z",
4
4
  "description": "Vertesia UI components and and hooks",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -86,10 +86,10 @@
86
86
  "vega": "^6.2.0",
87
87
  "vega-embed": "^7.1.0",
88
88
  "vega-lite": "^6.4.1",
89
- "@vertesia/fusion-ux": "1.1.0",
90
- "@vertesia/json": "1.1.0",
91
- "@vertesia/common": "1.1.0",
92
- "@vertesia/client": "1.1.0"
89
+ "@vertesia/client": "1.1.1-dev.20260505.163000Z",
90
+ "@vertesia/common": "1.1.1-dev.20260505.163000Z",
91
+ "@vertesia/fusion-ux": "1.1.1-dev.20260505.163000Z",
92
+ "@vertesia/json": "1.1.1-dev.20260505.163000Z"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@eslint/compat": "^2.0.2",
@@ -100,7 +100,7 @@
100
100
  "@rollup/plugin-terser": "^0.4.4",
101
101
  "@types/hast": "^3.0.4",
102
102
  "@types/lodash-es": "^4.17.12",
103
- "@types/node": "^25.6.0",
103
+ "@types/node": "^24.1.0",
104
104
  "@types/papaparse": "^5.5.2",
105
105
  "@types/react": "^19.2.3",
106
106
  "@types/react-dom": "^19.2.3",
@@ -6,6 +6,7 @@ import Ajv, { ValidateFunction } from "ajv";
6
6
  import React, { createContext, useContext, useState, useSyncExternalStore } from "react";
7
7
 
8
8
  export type WorkflowMode = 'start' | 'schedule';
9
+ type ModelOptions = NonNullable<WorkflowInteractionVars["config"]["model_options"]>;
9
10
 
10
11
  export interface ScheduledWorkflowConfig {
11
12
  name: string;
@@ -47,6 +48,7 @@ export class PayloadBuilder {
47
48
  _interaction: InCodeInteraction | undefined;
48
49
  _environment: ExecutionEnvironmentRef | undefined;
49
50
  _model: string = '';
51
+ _model_options: ModelOptions | undefined;
50
52
  _tool_names: string[] = [];
51
53
  _data: JSONObject | undefined;
52
54
  _mode: WorkflowMode = 'start';
@@ -79,6 +81,7 @@ export class PayloadBuilder {
79
81
  builder._data = this._data;
80
82
  builder._environment = this._environment;
81
83
  builder._model = this._model;
84
+ builder._model_options = this._model_options ? { ...this._model_options } as ModelOptions : undefined;
82
85
  builder._tool_names = [...this._tool_names];
83
86
  builder._interactive = this._interactive;
84
87
  builder._debug_mode = this._debug_mode;
@@ -251,6 +254,7 @@ export class PayloadBuilder {
251
254
  this._non_blocking_subagents = context.non_blocking_subagents ?? true;
252
255
  this._checkpoint_tokens = context.checkpoint_tokens;
253
256
  this._user_channels = context.user_channels;
257
+ this._model_options = context.config?.model_options as ModelOptions | undefined;
254
258
  this.collection = context.collection_id ?? undefined;
255
259
 
256
260
  // we need to trigger the setter to deal with default models
@@ -273,6 +277,7 @@ export class PayloadBuilder {
273
277
  // Reset the validator when schema changes
274
278
  this._inputValidator = undefined;
275
279
  if (interaction && !this._preserveRunValues) {
280
+ this._model_options = interaction.model_options as ModelOptions | undefined;
276
281
  if (interaction.runtime?.environment) {
277
282
  const envId = interaction.runtime.environment;
278
283
  this.vertesia.environments.retrieve(envId).then((environment) => this.environment = environment);
@@ -313,6 +318,15 @@ export class PayloadBuilder {
313
318
  }
314
319
  }
315
320
 
321
+ get model_options() {
322
+ return this._model_options;
323
+ }
324
+
325
+ set model_options(modelOptions: ModelOptions | undefined) {
326
+ this._model_options = modelOptions;
327
+ this.onStateChanged();
328
+ }
329
+
316
330
  get tool_names() {
317
331
  return this._tool_names;
318
332
  }
@@ -350,6 +364,7 @@ export class PayloadBuilder {
350
364
  setInteraction(interaction: InCodeInteraction | undefined) { this.interaction = interaction; }
351
365
  setEnvironment(environment: ExecutionEnvironmentRef | undefined) { this.environment = environment; }
352
366
  setModel(model: string | undefined) { this.model = model; }
367
+ setModelOptions(modelOptions: ModelOptions | undefined) { this.model_options = modelOptions; }
353
368
  setToolNames(tools: string[]) { this.tool_names = tools; }
354
369
  setCollection(collection: string | undefined) { this.collection = collection; }
355
370
  setInteractive(interactive: boolean) { this.interactive = interactive; }
@@ -427,6 +442,7 @@ export class PayloadBuilder {
427
442
  this._collection = undefined;
428
443
  this._preserveRunValues = false;
429
444
  this._model = '';
445
+ this._model_options = undefined;
430
446
  this._environment = undefined;
431
447
  this._tool_names = [];
432
448
  this._interaction = undefined;
@@ -44,7 +44,7 @@ function DocumentPanelComponent({
44
44
  client.store.objects.getObjectText(docId),
45
45
  client.store.objects.retrieve(docId),
46
46
  ]);
47
- setContent(textResult.text);
47
+ setContent(textResult.text ?? null);
48
48
  const name = obj.name;
49
49
  setDocName(name);
50
50
  if (name) onUpdateDocumentTitle?.(docId, name);
@@ -13,6 +13,8 @@ interface AgentRunnerFacetsNavProps {
13
13
  interactions?: any[];
14
14
  };
15
15
  search: SearchInterface;
16
+ actions?: React.ReactNode[];
17
+ selectionCount?: number;
16
18
  }
17
19
 
18
20
  // Hook to create filter groups for agent runners
@@ -95,7 +97,7 @@ export function createAgentRunnerFilterHandler(search: SearchInterface) {
95
97
  }
96
98
 
97
99
  // Legacy component for backward compatibility
98
- export function AgentRunnerFacetsNav({ facets, search }: AgentRunnerFacetsNavProps) {
100
+ export function AgentRunnerFacetsNav({ facets, search, selectionCount, actions }: AgentRunnerFacetsNavProps) {
99
101
  const [filters, setFilters] = useState<BaseFilter[]>([]);
100
102
  const didMountRef = useRef(false);
101
103
  const skipNextSearchRef = useRef(
@@ -128,15 +130,35 @@ export function AgentRunnerFacetsNav({ facets, search }: AgentRunnerFacetsNavPro
128
130
  filters={filters}
129
131
  setFilters={setFilters}
130
132
  >
131
- <div className='flex justify-between mb-1'>
132
- <div className='flex gap-2 items-center'>
133
+ <div className='gap-2 items-center w-full'>
134
+ <div className='flex justify-between mb-1'>
133
135
  <FilterBtn />
134
- <FilterBar />
135
- <FilterClear />
136
+ <div className='flex justify-end'>
137
+ {!selectionCount && (
138
+ <div className="flex items-center justify-between px-2 py-1">
139
+ <div className="text-sm text-muted-foreground">
140
+ {search.initialized ? `${search.totalCount} agent runs` : 'Loading agent runs...'}
141
+ </div>
142
+ </div>
143
+ )}
144
+ {actions && actions.length > 0 ? (
145
+ <div className='flex items-center gap-2 mb-1 mr-2'>
146
+ {actions.map((action, index) => (
147
+ <div key={index}>{action}</div>
148
+ ))}
149
+ </div>
150
+ ) : null}
151
+ <Button onClick={handleRefetch} variant='outline' title="Refresh">
152
+ <RefreshCw className="size-5" />
153
+ </Button>
154
+ </div>
136
155
  </div>
137
- <Button onClick={handleRefetch} variant='outline' title="Refresh">
138
- <RefreshCw className="size-5" />
139
- </Button>
156
+ {filters.length > 0 && (
157
+ <div className='flex items-center gap-2 mb-1'>
158
+ <FilterBar />
159
+ <FilterClear />
160
+ </div>
161
+ )}
140
162
  </div>
141
163
 
142
164
  </FilterProvider>
@@ -1,21 +1,20 @@
1
1
  import { Filter as BaseFilter, FilterProvider, FilterBtn, FilterBar, FilterClear, FilterGroup, useIsInModal } from '@vertesia/ui/core';
2
2
  import { useState } from 'react';
3
+ import { ComputedFacetResponse } from '@vertesia/common';
3
4
  import { useTypeRegistry } from '../store/types/TypeRegistryProvider.js';
4
5
  import { VStringFacet } from './utils/VStringFacet';
5
6
  import { VTypeFacet } from './utils/VTypeFacet';
6
7
  import { SearchInterface } from './utils/SearchInterface';
7
8
 
8
9
  interface DocumentsFacetsNavProps {
9
- facets: {
10
- type?: any[];
11
- status?: any[];
12
- role?: any[];
13
- location?: any[];
14
- tags?: string[];
15
- };
10
+ facets: ComputedFacetResponse;
16
11
  search: SearchInterface;
17
12
  }
18
13
 
14
+ function getBuckets(value: ComputedFacetResponse[string]) {
15
+ return Array.isArray(value) ? value : [];
16
+ }
17
+
19
18
  // Hook to create filter groups for documents
20
19
  export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets']): FilterGroup[] {
21
20
  const { registry: typeRegistry } = useTypeRegistry();
@@ -37,7 +36,7 @@ export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets'
37
36
 
38
37
  if (facets.type) {
39
38
  const typeFilterGroup = VTypeFacet({
40
- buckets: facets.type || [],
39
+ buckets: getBuckets(facets.type),
41
40
  typeRegistry: typeRegistry,
42
41
  type: 'select',
43
42
  multiple: true
@@ -48,7 +47,7 @@ export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets'
48
47
  if (facets.status) {
49
48
  const statusFilterGroup = VStringFacet({
50
49
  search: null as any, // This will be provided by the search context
51
- buckets: facets.status || [],
50
+ buckets: getBuckets(facets.status),
52
51
  name: 'status',
53
52
  placeholder: 'Status',
54
53
  type: 'select',
@@ -62,9 +61,9 @@ export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets'
62
61
  name: 'tags',
63
62
  placeholder: 'Tags',
64
63
  type: 'stringList',
65
- options: facets.tags.map((tag: string) => ({
66
- label: tag,
67
- value: tag
64
+ options: getBuckets(facets.tags).map((tag) => ({
65
+ label: tag._id,
66
+ value: tag._id
68
67
  }))
69
68
  });
70
69
  }
@@ -1,11 +1,10 @@
1
1
  import { Filter as BaseFilter, FilterProvider, FilterBtn, FilterBar, FilterClear, FilterGroup } from '@vertesia/ui/core';
2
+ import type { ComputedFacetResponse } from '@vertesia/common';
2
3
  import { useState } from 'react';
3
4
  import { SearchInterface } from './utils/SearchInterface';
4
5
 
5
6
  interface InteractionsFacetsNavProps {
6
- facets: {
7
- tags?: any[];
8
- };
7
+ facets: ComputedFacetResponse;
9
8
  search: SearchInterface;
10
9
  env?: string | null;
11
10
  }
@@ -118,4 +117,4 @@ export function InteractionsFacetsNav({ facets, search }: InteractionsFacetsNavP
118
117
  </div>
119
118
  </FilterProvider>
120
119
  );
121
- }
120
+ }
@@ -19,6 +19,8 @@ interface RunsFacetsNavProps {
19
19
  created_by?: any[];
20
20
  };
21
21
  search: SearchInterface;
22
+ actions?: React.ReactNode[];
23
+ selectionCount?: number;
22
24
  }
23
25
 
24
26
  // Hook to create filter groups for runs
@@ -181,7 +183,7 @@ export function useRunsFilterHandler(search: SearchInterface) {
181
183
  }
182
184
 
183
185
  // Legacy component for backward compatibility
184
- export function RunsFacetsNav({ facets, search }: RunsFacetsNavProps) {
186
+ export function RunsFacetsNav({ facets, search, actions, selectionCount }: RunsFacetsNavProps) {
185
187
  const [filters, setFilters] = useState<BaseFilter[]>([]);
186
188
  const filterGroups = useRunsFilterGroups(facets);
187
189
  const handleFilterLogic = useRunsFilterHandler(search);
@@ -202,15 +204,36 @@ export function RunsFacetsNav({ facets, search }: RunsFacetsNavProps) {
202
204
  filters={filters}
203
205
  setFilters={handleFilterChange}
204
206
  >
205
- <div className='flex justify-between mb-1 sticky top-2 py-2 z-10 bg-background'>
206
- <div className='flex gap-2 items-center'>
207
+ <div className='gap-2 items-center w-full'>
208
+ <div className='flex justify-between mb-1'>
207
209
  <FilterBtn />
208
- <FilterBar />
209
- <FilterClear />
210
+ <div className='flex justify-end'>
211
+ {!selectionCount && (
212
+ <div className="flex items-center justify-between px-2 py-1">
213
+ <div className="text-sm text-muted">
214
+ {search.initialized ? `${search.totalCount} calls` : 'Loading calls...'}
215
+ </div>
216
+ </div>
217
+ )}
218
+ {actions && actions.length > 0 ? (
219
+ <div className='flex items-center gap-2 mb-1 mr-2'>
220
+ {actions.map((action, index) => (
221
+ <div key={index}>{action}</div>
222
+ ))}
223
+ </div>
224
+ ) : null}
225
+ <Button onClick={handleRefetch} variant='outline' title="Refresh">
226
+ <RefreshCw className="size-5" />
227
+ </Button>
228
+ </div>
210
229
  </div>
211
- <Button onClick={handleRefetch} variant='outline' title="Refresh">
212
- <RefreshCw className="size-5" />
213
- </Button>
230
+ {filters.length > 0 && (
231
+ <div className='flex items-center gap-2 mb-1'>
232
+ <FilterBar />
233
+ <FilterClear />
234
+ </div>
235
+ )}
236
+
214
237
  </div>
215
238
  </FilterProvider>
216
239
  );
@@ -8,5 +8,7 @@ export interface SearchInterface {
8
8
  search(applyDefaults?: boolean): Promise<boolean | undefined>;
9
9
  setDefaultKeys(keys: defaultKeys[]): void;
10
10
  readonly isRunning: boolean;
11
+ readonly initialized?: boolean;
12
+ readonly totalCount?: number;
11
13
  query: Record<string, any>;
12
14
  }
@@ -119,6 +119,7 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
119
119
  const [filters, setFilters] = useState<BaseFilter[]>([]);
120
120
 
121
121
  const loadMoreRef = useRef<HTMLDivElement>(null);
122
+ const scrollRef = useRef<HTMLDivElement>(null);
122
123
 
123
124
  // Trigger initial search when component mounts
124
125
  useEffect(() => {
@@ -248,7 +249,7 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
248
249
  }
249
250
 
250
251
  return (
251
- <div className="flex flex-col gap-y-2">
252
+ <div className="flex flex-col gap-y-2 flex-1 min-h-0 ">
252
253
  <OverviewDrawer object={selectedObject} onClose={() => setSelectedObject(null)} />
253
254
  {
254
255
  error && <ErrorBox title={t('store.error')}>{error.message}</ErrorBox>
@@ -265,26 +266,30 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
265
266
  handleRefetch={handleRefetch}
266
267
  setIsGridView={setIsGridView}
267
268
  />
268
- <DocumentTable
269
- objects={objects}
270
- isLoading={!objects.length && isLoading}
271
- layout={actualLayout}
272
- onRowClick={onRowClick}
273
- previewObject={previewObject}
274
- selectedObject={selectedObject}
275
- onUpload={onUpload}
276
- isGridView={isGridView}
277
- collectionId={searchContext.collectionId} // Pass the collection ID from context
278
- />
279
- {hasMore ? (
280
- <div ref={loadMoreRef} className="w-full flex justify-center" >
281
- <Spinner size='xl' />
282
- </div>
283
- ) : (
284
- <div className="text-muted text-center text-sm py-1">
285
- {`All ${objects.length} objects loaded.`}
269
+ <div className="flex flex-col w-full flex-1 min-h-0 border rounded-md mb-2">
270
+ <div ref={scrollRef} className="flex-1 min-h-0 overflow-y-auto">
271
+ <DocumentTable
272
+ objects={objects}
273
+ isLoading={!objects.length && isLoading}
274
+ layout={actualLayout}
275
+ onRowClick={onRowClick}
276
+ previewObject={previewObject}
277
+ selectedObject={selectedObject}
278
+ onUpload={onUpload}
279
+ isGridView={isGridView}
280
+ collectionId={searchContext.collectionId}
281
+ />
282
+ {hasMore ? (
283
+ <div ref={loadMoreRef} className="w-full flex justify-center" >
284
+ <Spinner size='xl' />
285
+ </div>
286
+ ) : (
287
+ <div className="text-muted text-center text-sm py-1">
288
+ {`All ${objects.length} objects loaded.`}
289
+ </div>
290
+ )}
286
291
  </div>
287
- )}
292
+ </div>
288
293
  </div>
289
294
  );
290
295
  }
@@ -1,5 +1,5 @@
1
1
  import { ColumnLayout, ContentObjectItem } from "@vertesia/common";
2
- import { Table, TBody } from "@vertesia/ui/core";
2
+ import { Table, TBody, THead } from "@vertesia/ui/core";
3
3
  import { useUITranslation } from '../../../../i18n/index.js';
4
4
  import { CheckIcon } from "lucide-react";
5
5
  import { ChangeEvent } from "react";
@@ -24,15 +24,15 @@ interface ViewProps {
24
24
  export function DocumentTableView({ objects, selection, isLoading, columns, onRowClick, highlightRow, selectedObject, toggleAll, onSelectionChange }: ViewProps) {
25
25
  const { t } = useUITranslation();
26
26
  return (
27
- <Table className="w-full border-t">
28
- <thead>
27
+ <Table className="w-full">
28
+ <THead>
29
29
  <tr>
30
30
  {selection && <th><input type="checkbox" onChange={toggleAll} /></th>}
31
31
  {columns.map((col) => (
32
32
  <th key={col.name}>{col.name}</th>
33
33
  ))}
34
34
  </tr>
35
- </thead>
35
+ </THead>
36
36
  <TBody isLoading={isLoading} columns={columns.length + 1}>
37
37
  {
38
38
  objects?.map((obj: ContentObjectItem) => {
@@ -1,8 +1,8 @@
1
1
  import { createContext, useContext } from 'react';
2
2
 
3
3
  import { SharedState, useWatchSharedState } from '@vertesia/ui/core';
4
- import { ComputeFacetsResponse, ZenoClient } from '@vertesia/client';
5
- import { ComplexSearchPayload, ComplexSearchQuery, ComputeObjectFacetPayload, ContentObjectItem, FacetBucket, FacetSpec, ObjectSearchQuery } from '@vertesia/common';
4
+ import { ZenoClient } from '@vertesia/client';
5
+ import { ComplexSearchPayload, ComplexSearchQuery, ComputeObjectFacetPayload, ComputedFacetResponse, ContentObjectItem, FacetBucket, FacetSpec, ObjectSearchQuery } from '@vertesia/common';
6
6
  import { SearchInterface } from '@vertesia/ui/features'
7
7
 
8
8
  interface DocumentSearchResult {
@@ -16,7 +16,7 @@ interface DocumentSearchResult {
16
16
  export class DocumentSearch implements SearchInterface {
17
17
 
18
18
  collectionId?: string;
19
- facets = new SharedState<ComputeFacetsResponse>({});
19
+ facets = new SharedState<ComputedFacetResponse>({});
20
20
  result = new SharedState<DocumentSearchResult>({ objects: [], isLoading: false });
21
21
 
22
22
  facetSpecs: FacetSpec[] = [];
@@ -79,7 +79,8 @@ export class DocumentSearch implements SearchInterface {
79
79
  }
80
80
 
81
81
  getFacetBuckets(name: string): FacetBucket[] {
82
- return (this.facets.value as any)[name]?.buckets || [];
82
+ const value = this.facets.value[name];
83
+ return Array.isArray(value) ? value : [];
83
84
  }
84
85
 
85
86
  resetFacets() {
@@ -161,6 +162,11 @@ export class DocumentSearch implements SearchInterface {
161
162
 
162
163
  return true;
163
164
  }).catch((err) => {
165
+ // index_not_found_exception means the data store has no index yet — treat as empty
166
+ if (err?.status === 404) {
167
+ this.result.value = { isLoading: false, objects: [], hasMore: false };
168
+ return false;
169
+ }
164
170
  this.result.value = {
165
171
  error: err,
166
172
  isLoading: false,
@@ -96,22 +96,27 @@ export function ContentObjectTypesSearch({ isDirty = false }: ContentObjectTypes
96
96
  };
97
97
 
98
98
  return (
99
- <div className="flex flex-col gap-4 h-full">
99
+ <div className="flex flex-col flex-1 min-h-0">
100
100
  <div className="flex flex-shrink-0 gap-4">
101
101
  <Input placeholder={t('store.filterByName')} value={searchTerm} onChange={setSearchTerm} />
102
102
  <SelectBox className="w-60" isClearable options={Object.values(ChunkableOptions)} value={chunkable} onChange={onChunkableChange} placeholder={t('store.isChunkable')} />
103
103
  </div>
104
- <div className="flex-1 overflow-y-auto">
105
- {
106
- (!isLoading && objects?.length === 0) ? (
107
- <EmptyCollection title={t('store.noType')} buttonLabel={t('store.createType')} onClick={onOpenCreateModal}>
108
- {t('store.getStartedTypes')}
109
- </EmptyCollection >
110
- ) : (
111
- <ContentObjectTypesTable objects={objects} isLoading={isLoading} />
112
- )
113
- }
114
- <CreateOrUpdateTypeModal okLabel="Create" title={t('store.createType')} isOpen={showCreateModal} onClose={onCloseCreateModal} />
104
+ <div className="flex flex-col w-full flex-1 min-h-0 border rounded-md my-2">
105
+ <div className="flex-1 min-h-0 overflow-y-auto">
106
+ {
107
+ (!isLoading && objects?.length === 0) ? (
108
+ <EmptyCollection title={t('store.noType')} buttonLabel={t('store.createType')} onClick={onOpenCreateModal}>
109
+ {t('store.getStartedTypes')}
110
+ </EmptyCollection >
111
+ ) : (
112
+ <>
113
+ <ContentObjectTypesTable objects={objects} isLoading={isLoading} />
114
+ <div ref={loadMoreRef} className="h-4 w-full" />
115
+ </>
116
+ )
117
+ }
118
+ <CreateOrUpdateTypeModal okLabel="Create" title={t('store.createType')} isOpen={showCreateModal} onClose={onCloseCreateModal} />
119
+ </div>
115
120
  </div>
116
121
  </div>
117
122
  )