@vertesia/ui 0.74.0 → 0.76.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/Center.js +1 -1
- package/lib/esm/core/components/Center.js.map +1 -1
- package/lib/esm/core/components/Overlay.js +57 -0
- package/lib/esm/core/components/Overlay.js.map +1 -0
- package/lib/esm/core/components/SidePanel.js +6 -6
- package/lib/esm/core/components/SidePanel.js.map +1 -1
- package/lib/esm/core/components/index.js +1 -0
- package/lib/esm/core/components/index.js.map +1 -1
- package/lib/esm/core/components/shadcn/tabs.js +43 -5
- package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
- package/lib/esm/features/agent/PayloadBuilder.js +9 -2
- package/lib/esm/features/agent/PayloadBuilder.js.map +1 -1
- package/lib/esm/features/facets/DocumentsFacetsNav.js +4 -2
- package/lib/esm/features/facets/DocumentsFacetsNav.js.map +1 -1
- package/lib/esm/features/facets/VTypeFacet.js +2 -1
- package/lib/esm/features/facets/VTypeFacet.js.map +1 -1
- package/lib/esm/features/magic-pdf/TextPageView.js +2 -4
- package/lib/esm/features/magic-pdf/TextPageView.js.map +1 -1
- package/lib/esm/features/store/collections/CreateCollection.js +1 -1
- package/lib/esm/features/store/collections/CreateCollection.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentPreviewPanel.js +2 -4
- package/lib/esm/features/store/objects/DocumentPreviewPanel.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentSearchResults.js +19 -21
- package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/esm/features/store/objects/components/ContentOverview.js +2 -4
- package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/esm/features/store/objects/components/VectorSearchWidget.js +51 -46
- package/lib/esm/features/store/objects/components/VectorSearchWidget.js.map +1 -1
- package/lib/esm/features/store/objects/search/DocumentSearchContext.js +50 -34
- package/lib/esm/features/store/objects/search/DocumentSearchContext.js.map +1 -1
- package/lib/esm/features/store/objects/search/DocumentSearchProvider.js +1 -3
- package/lib/esm/features/store/objects/search/DocumentSearchProvider.js.map +1 -1
- package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js +4 -11
- package/lib/esm/features/store/objects/upload/useSmartFileUploadProcessing.js.map +1 -1
- package/lib/esm/features/user/UserInfo.js +2 -2
- package/lib/esm/features/user/UserInfo.js.map +1 -1
- package/lib/esm/session/UserSessionProvider.js +6 -3
- package/lib/esm/session/UserSessionProvider.js.map +1 -1
- package/lib/esm/session/auth/composable.js +3 -3
- package/lib/esm/session/auth/composable.js.map +1 -1
- package/lib/esm/session/auth/firebase.js +7 -0
- package/lib/esm/session/auth/firebase.js.map +1 -1
- package/lib/esm/session/auth/useAuthState.js +0 -3
- package/lib/esm/session/auth/useAuthState.js.map +1 -1
- package/lib/esm/shell/apps/StandaloneApp.js +1 -1
- package/lib/esm/shell/apps/StandaloneApp.js.map +1 -1
- package/lib/esm/shell/login/EnterpriseSigninButton.js +3 -0
- package/lib/esm/shell/login/EnterpriseSigninButton.js.map +1 -1
- package/lib/esm/shell/login/InviteAcceptModal.js +1 -1
- package/lib/esm/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/esm/widgets/form/ManagedObject.js +1 -1
- package/lib/esm/widgets/index.js +1 -0
- package/lib/esm/widgets/index.js.map +1 -1
- package/lib/esm/widgets/markdown/MarkdownRenderer.js +24 -0
- package/lib/esm/widgets/markdown/MarkdownRenderer.js.map +1 -0
- package/lib/esm/widgets/markdown/index.js +2 -0
- package/lib/esm/widgets/markdown/index.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/components/Overlay.d.ts +25 -0
- package/lib/types/core/components/Overlay.d.ts.map +1 -0
- package/lib/types/core/components/SidePanel.d.ts +3 -1
- package/lib/types/core/components/SidePanel.d.ts.map +1 -1
- package/lib/types/core/components/index.d.ts +1 -0
- package/lib/types/core/components/index.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/types/env/index.d.ts +2 -2
- package/lib/types/env/index.d.ts.map +1 -1
- package/lib/types/features/agent/PayloadBuilder.d.ts.map +1 -1
- package/lib/types/features/facets/DocumentsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/facets/VTypeFacet.d.ts.map +1 -1
- package/lib/types/features/magic-pdf/TextPageView.d.ts.map +1 -1
- package/lib/types/features/store/objects/DocumentPreviewPanel.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/VectorSearchWidget.d.ts +4 -3
- package/lib/types/features/store/objects/components/VectorSearchWidget.d.ts.map +1 -1
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts +5 -2
- package/lib/types/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/types/features/store/objects/search/DocumentSearchProvider.d.ts +2 -4
- package/lib/types/features/store/objects/search/DocumentSearchProvider.d.ts.map +1 -1
- package/lib/types/features/store/objects/upload/useSmartFileUploadProcessing.d.ts.map +1 -1
- package/lib/types/session/UserSessionProvider.d.ts.map +1 -1
- package/lib/types/session/auth/composable.d.ts +1 -1
- package/lib/types/session/auth/composable.d.ts.map +1 -1
- package/lib/types/session/auth/firebase.d.ts.map +1 -1
- package/lib/types/session/auth/useAuthState.d.ts.map +1 -1
- package/lib/types/shell/login/EnterpriseSigninButton.d.ts.map +1 -1
- package/lib/types/widgets/index.d.ts +1 -0
- package/lib/types/widgets/index.d.ts.map +1 -1
- package/lib/types/widgets/markdown/MarkdownRenderer.d.ts +9 -0
- package/lib/types/widgets/markdown/MarkdownRenderer.d.ts.map +1 -0
- package/lib/types/widgets/markdown/index.d.ts +2 -0
- package/lib/types/widgets/markdown/index.d.ts.map +1 -0
- 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-session.js +1 -1
- package/lib/vertesia-ui-session.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 +6 -4
- package/src/core/components/Center.tsx +1 -1
- package/src/core/components/Overlay.tsx +129 -0
- package/src/core/components/SidePanel.tsx +38 -33
- package/src/core/components/index.ts +1 -0
- package/src/core/components/shadcn/tabs.tsx +48 -5
- package/src/env/index.ts +1 -1
- package/src/features/agent/PayloadBuilder.tsx +8 -2
- package/src/features/facets/DocumentsFacetsNav.tsx +4 -2
- package/src/features/facets/VTypeFacet.tsx +2 -1
- package/src/features/magic-pdf/TextPageView.tsx +3 -4
- package/src/features/store/collections/CreateCollection.tsx +1 -1
- package/src/features/store/objects/DocumentPreviewPanel.tsx +2 -4
- package/src/features/store/objects/DocumentSearchResults.tsx +24 -26
- package/src/features/store/objects/components/ContentOverview.tsx +3 -6
- package/src/features/store/objects/components/VectorSearchWidget.tsx +88 -60
- package/src/features/store/objects/search/DocumentSearchContext.ts +57 -36
- package/src/features/store/objects/search/DocumentSearchProvider.tsx +2 -6
- package/src/features/store/objects/upload/useSmartFileUploadProcessing.ts +6 -12
- package/src/features/user/UserInfo.tsx +2 -2
- package/src/session/UserSessionProvider.tsx +5 -3
- package/src/session/auth/composable.ts +3 -3
- package/src/session/auth/firebase.ts +8 -0
- package/src/session/auth/useAuthState.ts +0 -4
- package/src/shell/apps/StandaloneApp.tsx +1 -1
- package/src/shell/login/EnterpriseSigninButton.tsx +3 -0
- package/src/shell/login/InviteAcceptModal.tsx +1 -1
- package/src/widgets/form/ManagedObject.ts +1 -1
- package/src/widgets/index.ts +1 -0
- package/src/widgets/markdown/MarkdownRenderer.tsx +45 -0
- package/src/widgets/markdown/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertesia/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.76.0",
|
|
4
4
|
"description": "Vertesia UI components and and hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"debounce": "^2.2.0",
|
|
44
44
|
"fast-xml-parser": "^5.2.3",
|
|
45
45
|
"firebase": "^10.12.2",
|
|
46
|
+
"framer-motion": "^12.23.12",
|
|
46
47
|
"json-schema": "^0.4.0",
|
|
47
48
|
"jwt-decode": "^4.0.0",
|
|
48
49
|
"lodash-es": "^4.17.21",
|
|
@@ -58,9 +59,10 @@
|
|
|
58
59
|
"remark-gfm": "^4.0.1",
|
|
59
60
|
"tailwind-merge": "^3.3.0",
|
|
60
61
|
"ts-md5": "^1.3.1",
|
|
61
|
-
"
|
|
62
|
-
"@vertesia/client": "0.
|
|
63
|
-
"@vertesia/json": "0.
|
|
62
|
+
"unist-util-visit": "^5.0.0",
|
|
63
|
+
"@vertesia/client": "0.76.0",
|
|
64
|
+
"@vertesia/json": "0.76.0",
|
|
65
|
+
"@vertesia/common": "0.76.0"
|
|
64
66
|
},
|
|
65
67
|
"devDependencies": {
|
|
66
68
|
"@eslint/js": "^9.27.0",
|
|
@@ -7,6 +7,6 @@ interface CenterProps {
|
|
|
7
7
|
}
|
|
8
8
|
export function Center({ className, children }: CenterProps) {
|
|
9
9
|
return (
|
|
10
|
-
<div className={clsx('flex items-
|
|
10
|
+
<div className={clsx('flex items-center justify-center', className)}>{children}</div>
|
|
11
11
|
)
|
|
12
12
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { motion } from "framer-motion"
|
|
2
|
+
import { X } from "lucide-react"
|
|
3
|
+
import { useState, ReactNode } from "react"
|
|
4
|
+
|
|
5
|
+
import { Button } from "./Button"
|
|
6
|
+
|
|
7
|
+
interface OverlayProps {
|
|
8
|
+
children: ReactNode
|
|
9
|
+
overlayContent: ReactNode
|
|
10
|
+
className?: string
|
|
11
|
+
overlayClassName?: string
|
|
12
|
+
position?: 'left' | 'right' | 'top' | 'bottom' | 'center'
|
|
13
|
+
width?: string
|
|
14
|
+
height?: string
|
|
15
|
+
showCloseButton?: boolean
|
|
16
|
+
closeButtonTooltip?: string
|
|
17
|
+
onOpen?: () => void
|
|
18
|
+
onClose?: () => void
|
|
19
|
+
triggerClassName?: string
|
|
20
|
+
backdropClassName?: string
|
|
21
|
+
animationConfig?: {
|
|
22
|
+
type?: "spring" | "tween"
|
|
23
|
+
stiffness?: number
|
|
24
|
+
damping?: number
|
|
25
|
+
duration?: number
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function Overlay({
|
|
29
|
+
children,
|
|
30
|
+
overlayContent,
|
|
31
|
+
className = "",
|
|
32
|
+
overlayClassName = "",
|
|
33
|
+
position = 'right',
|
|
34
|
+
width,
|
|
35
|
+
height,
|
|
36
|
+
showCloseButton = true,
|
|
37
|
+
onOpen,
|
|
38
|
+
onClose,
|
|
39
|
+
triggerClassName = "",
|
|
40
|
+
backdropClassName = "",
|
|
41
|
+
animationConfig = { type: "spring", stiffness: 300, damping: 30 }
|
|
42
|
+
}: Readonly<OverlayProps>) {
|
|
43
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
44
|
+
|
|
45
|
+
const handleOpen = () => {
|
|
46
|
+
setIsOpen(true)
|
|
47
|
+
onOpen?.()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const handleClose = () => {
|
|
51
|
+
setIsOpen(false)
|
|
52
|
+
onClose?.()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const animationProps = getAnimationProps(position)
|
|
56
|
+
const positionClasses = getPositionClasses(position, width, height)
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<div className={`flex items-center justify-center w-full ${className}`}>
|
|
60
|
+
<div onClick={handleOpen} className={`w-full align-left cursor-pointer ${triggerClassName}`}>
|
|
61
|
+
{children}
|
|
62
|
+
</div>
|
|
63
|
+
{
|
|
64
|
+
isOpen && (
|
|
65
|
+
<div className={`z-45 fixed inset-0 bg-black bg-opacity-50 ${backdropClassName}`}>
|
|
66
|
+
<motion.div
|
|
67
|
+
{...animationProps}
|
|
68
|
+
transition={animationConfig}
|
|
69
|
+
className={`${positionClasses} ${overlayClassName}`}
|
|
70
|
+
>
|
|
71
|
+
{
|
|
72
|
+
showCloseButton && (
|
|
73
|
+
<div className="absolute top-2 right-2 z-10">
|
|
74
|
+
<Button onClick={handleClose} variant="primary">
|
|
75
|
+
<X />
|
|
76
|
+
</Button>
|
|
77
|
+
</div>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
<div className={showCloseButton ? "mt-8" : ""}>
|
|
81
|
+
{overlayContent}
|
|
82
|
+
</div>
|
|
83
|
+
</motion.div>
|
|
84
|
+
</div>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
</div>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getAnimationProps(position: string) {
|
|
92
|
+
switch (position) {
|
|
93
|
+
case 'left':
|
|
94
|
+
return { initial: { x: "-100%" }, animate: { x: 0 }, exit: { x: "-100%" } }
|
|
95
|
+
case 'right':
|
|
96
|
+
return { initial: { x: "100%" }, animate: { x: 0 }, exit: { x: "100%" } }
|
|
97
|
+
case 'top':
|
|
98
|
+
return { initial: { y: "-100%" }, animate: { y: 0 }, exit: { y: "-100%" } }
|
|
99
|
+
case 'bottom':
|
|
100
|
+
return { initial: { y: "100%" }, animate: { y: 0 }, exit: { y: "100%" } }
|
|
101
|
+
case 'center':
|
|
102
|
+
return {
|
|
103
|
+
initial: { opacity: 0, scale: 0.8 },
|
|
104
|
+
animate: { opacity: 1, scale: 1 },
|
|
105
|
+
exit: { opacity: 0, scale: 0.8 }
|
|
106
|
+
}
|
|
107
|
+
default:
|
|
108
|
+
return { initial: { x: "100%" }, animate: { x: 0 }, exit: { x: "100%" } }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getPositionClasses(position: string, width?: string, height?: string) {
|
|
113
|
+
const baseClasses = "fixed bg-white shadow-lg p-4 relative"
|
|
114
|
+
|
|
115
|
+
switch (position) {
|
|
116
|
+
case 'left':
|
|
117
|
+
return `${baseClasses} left-0 top-[var(--header-height)] h-full ${width || 'w-80'}`
|
|
118
|
+
case 'right':
|
|
119
|
+
return `${baseClasses} right-0 top-[var(--header-height)] h-full ${width || 'w-80'}`
|
|
120
|
+
case 'top':
|
|
121
|
+
return `${baseClasses} top-[var(--header-height)] left-0 right-0 ${height || 'h-80'}`
|
|
122
|
+
case 'bottom':
|
|
123
|
+
return `${baseClasses} bottom-0 left-0 right-0 ${height || 'h-80'}`
|
|
124
|
+
case 'center':
|
|
125
|
+
return `${baseClasses} top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 ${width || 'w-96'} ${height || 'max-h-96'}`
|
|
126
|
+
default:
|
|
127
|
+
return `${baseClasses} right-0 top-[var(--header-height)] h-full ${width || 'w-80'}`
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { useState, Fragment } from 'react';
|
|
4
|
-
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react';
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
5
3
|
import { X } from 'lucide-react';
|
|
6
4
|
import { Button } from './shadcn/button';
|
|
7
5
|
|
|
@@ -10,16 +8,18 @@ interface SidePanelProps {
|
|
|
10
8
|
onClose: () => void;
|
|
11
9
|
children: React.ReactNode;
|
|
12
10
|
title?: string;
|
|
11
|
+
panelWidth?: number;
|
|
12
|
+
backdrop?: boolean;
|
|
13
13
|
}
|
|
14
|
-
export function SidePanel({ isOpen, title, onClose, children }: SidePanelProps) {
|
|
15
|
-
const [
|
|
14
|
+
export function SidePanel({ isOpen, title, onClose, children, panelWidth = 768, backdrop = false }: SidePanelProps) {
|
|
15
|
+
const [_panelWidth, setPanelWidth] = useState(panelWidth);
|
|
16
16
|
|
|
17
17
|
const handleDragStart = (e: React.MouseEvent) => {
|
|
18
18
|
e.preventDefault();
|
|
19
19
|
|
|
20
20
|
let isDragging = true;
|
|
21
21
|
const startX = e.pageX;
|
|
22
|
-
const startWidth =
|
|
22
|
+
const startWidth = _panelWidth;
|
|
23
23
|
|
|
24
24
|
const handleMouseMove = (e: MouseEvent) => {
|
|
25
25
|
if (isDragging) {
|
|
@@ -40,25 +40,30 @@ export function SidePanel({ isOpen, title, onClose, children }: SidePanelProps)
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
<div className="
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<div
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
43
|
+
<AnimatePresence>
|
|
44
|
+
{isOpen && (
|
|
45
|
+
<div className="relative z-10">
|
|
46
|
+
{/* Backdrop */}
|
|
47
|
+
{backdrop && (
|
|
48
|
+
<motion.div
|
|
49
|
+
className="fixed inset-0 bg-black bg-opacity-50"
|
|
50
|
+
initial={{ opacity: 0 }}
|
|
51
|
+
animate={{ opacity: 1 }}
|
|
52
|
+
exit={{ opacity: 0 }}
|
|
53
|
+
onClick={onClose}
|
|
54
|
+
/>
|
|
55
|
+
)}
|
|
56
|
+
|
|
57
|
+
<div className="fixed inset-y-0 right-0 overflow-hidden">
|
|
58
|
+
<div className="absolute inset-0 overflow-hidden">
|
|
59
|
+
<div className="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10 sm:pl-16">
|
|
60
|
+
<motion.div
|
|
60
61
|
className="pointer-events-auto border-l"
|
|
61
|
-
style={{ width: `${
|
|
62
|
+
style={{ width: `${_panelWidth}px` }}
|
|
63
|
+
initial={{ x: "100%" }}
|
|
64
|
+
animate={{ x: 0 }}
|
|
65
|
+
exit={{ x: "100%" }}
|
|
66
|
+
transition={{ type: "spring", stiffness: 300, damping: 30 }}
|
|
62
67
|
>
|
|
63
68
|
<div className="relative flex h-full">
|
|
64
69
|
{/* Drag Handle */}
|
|
@@ -67,28 +72,28 @@ export function SidePanel({ isOpen, title, onClose, children }: SidePanelProps)
|
|
|
67
72
|
onMouseDown={handleDragStart}
|
|
68
73
|
/>
|
|
69
74
|
<div className="flex-1 flex flex-col overflow-y-scroll gap-4 bg-background py-6 shadow-xl">
|
|
70
|
-
<div className="px-
|
|
75
|
+
<div className="px-2 sm:px-4">
|
|
71
76
|
<div className="flex items-start justify-between">
|
|
72
|
-
<
|
|
77
|
+
<h2 className="w-full text-base font-semibold leading-6">
|
|
73
78
|
<div className="text-2xl">{title ?? ""}</div>
|
|
74
|
-
</
|
|
79
|
+
</h2>
|
|
75
80
|
<div className="ml-3 flex h-7 items-center">
|
|
76
81
|
<CloseButton onClose={onClose} />
|
|
77
82
|
</div>
|
|
78
83
|
</div>
|
|
79
84
|
</div>
|
|
80
|
-
<div className="px-
|
|
85
|
+
<div className="px-2 sm:px-4">
|
|
81
86
|
{children}
|
|
82
87
|
</div>
|
|
83
88
|
</div>
|
|
84
89
|
</div>
|
|
85
|
-
</
|
|
86
|
-
</
|
|
90
|
+
</motion.div>
|
|
91
|
+
</div>
|
|
87
92
|
</div>
|
|
88
93
|
</div>
|
|
89
94
|
</div>
|
|
90
|
-
|
|
91
|
-
</
|
|
95
|
+
)}
|
|
96
|
+
</AnimatePresence>
|
|
92
97
|
);
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -17,6 +17,7 @@ export * from "./MenuList.js";
|
|
|
17
17
|
export * from "./MessageBox.js";
|
|
18
18
|
export * from "./Modal.js";
|
|
19
19
|
export * from "./NumberInput.js";
|
|
20
|
+
export * from "./Overlay.js";
|
|
20
21
|
export * from "./popup/index.js";
|
|
21
22
|
export * from "./Portal.js";
|
|
22
23
|
export * from "./RadioGroup.js";
|
|
@@ -44,15 +44,58 @@ const VTabs = ({
|
|
|
44
44
|
responsive = false,
|
|
45
45
|
variant = "tabs"
|
|
46
46
|
}: TabsProps) => {
|
|
47
|
-
|
|
47
|
+
// Initialize value
|
|
48
|
+
const [value, setValue] = React.useState(() => {
|
|
49
|
+
// First check if current is provided
|
|
50
|
+
const currentValue = typeof current === 'function' ? current() : current;
|
|
51
|
+
if (currentValue) {
|
|
52
|
+
return currentValue;
|
|
53
|
+
}
|
|
48
54
|
|
|
49
|
-
|
|
55
|
+
// Then check hash
|
|
56
|
+
const hash = window.location.hash;
|
|
57
|
+
const currentTab = hash ? hash.substring(1) : undefined;
|
|
58
|
+
|
|
59
|
+
// Check if the tab from hash exists in tabs
|
|
60
|
+
if (currentTab && tabs.some(tab => tab.name === currentTab)) {
|
|
61
|
+
return currentTab;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Fall back to default or first tab
|
|
65
|
+
return defaultValue || tabs[0]?.name;
|
|
66
|
+
});
|
|
50
67
|
|
|
68
|
+
// Update when current prop changes (but don't create a loop)
|
|
51
69
|
React.useEffect(() => {
|
|
52
|
-
|
|
70
|
+
const currentValue = typeof current === 'function' ? current() : current;
|
|
71
|
+
if (currentValue && currentValue !== value) {
|
|
53
72
|
setValue(currentValue);
|
|
54
73
|
}
|
|
55
|
-
}, [
|
|
74
|
+
}, [current]);
|
|
75
|
+
|
|
76
|
+
// Listen to hash changes only when there's no current prop being controlled externally
|
|
77
|
+
React.useEffect(() => {
|
|
78
|
+
if (current) return; // Skip hash handling if controlled by parent
|
|
79
|
+
|
|
80
|
+
const handleHashChange = () => {
|
|
81
|
+
const hash = window.location.hash;
|
|
82
|
+
const currentTab = hash ? hash.substring(1) : undefined;
|
|
83
|
+
|
|
84
|
+
// Only update if the tab exists in tabs
|
|
85
|
+
if (currentTab && tabs.some(tab => tab.name === currentTab)) {
|
|
86
|
+
setValue(currentTab);
|
|
87
|
+
} else if (!hash && defaultValue) {
|
|
88
|
+
// If no hash, fall back to default
|
|
89
|
+
setValue(defaultValue);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Check initial hash
|
|
94
|
+
handleHashChange();
|
|
95
|
+
|
|
96
|
+
window.addEventListener('hashchange', handleHashChange);
|
|
97
|
+
return () => window.removeEventListener('hashchange', handleHashChange);
|
|
98
|
+
}, [current, tabs, defaultValue]);
|
|
56
99
|
|
|
57
100
|
const handleValueChange = (newValue: string) => {
|
|
58
101
|
setValue(newValue);
|
|
@@ -68,7 +111,7 @@ const VTabs = ({
|
|
|
68
111
|
return (
|
|
69
112
|
<TabsContext.Provider value={{ tabs, size: fullWidth ? tabs.length : 0, current: value, setTab, responsive: responsive, variant }}>
|
|
70
113
|
<TabsPrimitive.Root
|
|
71
|
-
defaultValue={tabs[0]?.name}
|
|
114
|
+
defaultValue={value || tabs[0]?.name}
|
|
72
115
|
value={value}
|
|
73
116
|
onValueChange={handleValueChange}
|
|
74
117
|
className={className}
|
package/src/env/index.ts
CHANGED
|
@@ -129,8 +129,14 @@ export class PayloadBuilder implements ConversationWorkflowPayload {
|
|
|
129
129
|
if (environment?.id !== this.payload.config.environment?.id) {
|
|
130
130
|
this.payload.config.environment = environment;
|
|
131
131
|
if (!this._preserveRunValues) {
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
// First try to use the interaction model, then the environment default model
|
|
133
|
+
const interactionModel = this.payload.interaction?.model;
|
|
134
|
+
if (interactionModel && environment && supportsToolUse(interactionModel, environment.provider)) {
|
|
135
|
+
this.payload.config.model = interactionModel;
|
|
136
|
+
} else {
|
|
137
|
+
this.payload.config.model = environment?.default_model && supportsToolUse(environment.default_model, environment.provider)
|
|
138
|
+
? environment.default_model : undefined;
|
|
139
|
+
}
|
|
134
140
|
}
|
|
135
141
|
|
|
136
142
|
this.onStateChanged();
|
|
@@ -42,7 +42,8 @@ export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets'
|
|
|
42
42
|
const statusFilterGroup = VStringFacet({
|
|
43
43
|
search: null as any, // This will be provided by the search context
|
|
44
44
|
buckets: facets.status || [],
|
|
45
|
-
name: '
|
|
45
|
+
name: 'status',
|
|
46
|
+
placeholder: 'Status',
|
|
46
47
|
type: 'select',
|
|
47
48
|
multiple: true
|
|
48
49
|
});
|
|
@@ -51,7 +52,8 @@ export function useDocumentFilterGroups(facets: DocumentsFacetsNavProps['facets'
|
|
|
51
52
|
|
|
52
53
|
if (facets.tags) {
|
|
53
54
|
customFilterGroups.push({
|
|
54
|
-
name: '
|
|
55
|
+
name: 'tags',
|
|
56
|
+
placeholder: 'Tags',
|
|
55
57
|
type: 'stringList',
|
|
56
58
|
options: facets.tags.map((tag: string) => ({
|
|
57
59
|
label: tag,
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { JSONCode, Theme, XMLViewer } from '@vertesia/ui/widgets';
|
|
1
|
+
import { JSONCode, Theme, XMLViewer, MarkdownRenderer } from '@vertesia/ui/widgets';
|
|
2
2
|
import { useEffect, useLayoutEffect, useState } from "react";
|
|
3
|
-
import Markdown from "react-markdown";
|
|
4
|
-
import remarkGfm from "remark-gfm";
|
|
5
3
|
import { usePdfPagesInfo } from "./PdfPageProvider";
|
|
6
4
|
import { ViewType } from "./types";
|
|
7
5
|
|
|
@@ -16,6 +14,7 @@ const darkTheme: Theme = {
|
|
|
16
14
|
cdataColor: "#33CC66",
|
|
17
15
|
}
|
|
18
16
|
|
|
17
|
+
|
|
19
18
|
interface TextPageViewProps {
|
|
20
19
|
pageNumber: number;
|
|
21
20
|
viewType: ViewType;
|
|
@@ -86,7 +85,7 @@ function MarkdownPageView({ pageNumber }: MarkdownPageViewProps) {
|
|
|
86
85
|
}, [pageNumber]);
|
|
87
86
|
return (
|
|
88
87
|
<div className="px-4 py-2 prose prose-sm max-w-none dark:prose-invert">
|
|
89
|
-
{content ? <
|
|
88
|
+
{content ? <MarkdownRenderer>{content}</MarkdownRenderer> : <div>No markdown content available</div>}
|
|
90
89
|
</div>
|
|
91
90
|
)
|
|
92
91
|
}
|
|
@@ -74,7 +74,7 @@ export function CreateCollectionForm({ onClose, redirect = true, onAddToCollecti
|
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
return (
|
|
77
|
-
<form>
|
|
77
|
+
<form onSubmit={(e) => e.preventDefault()}>
|
|
78
78
|
<VModalBody>
|
|
79
79
|
<FormItem label="Name" required>
|
|
80
80
|
<Input type="text" value={payload.name || ""} onChange={(value) => setPayloadProp("name", value)} />
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import { Button, Spinner, useToast } from "@vertesia/ui/core";
|
|
6
6
|
import { useNavigate } from "@vertesia/ui/router";
|
|
7
7
|
import { useUserSession } from "@vertesia/ui/session";
|
|
8
|
-
import { JSONDisplay } from "@vertesia/ui/widgets";
|
|
8
|
+
import { JSONDisplay, MarkdownRenderer } from "@vertesia/ui/widgets";
|
|
9
9
|
import {
|
|
10
10
|
ChevronRight,
|
|
11
11
|
Download,
|
|
@@ -16,8 +16,6 @@ import {
|
|
|
16
16
|
X,
|
|
17
17
|
} from "lucide-react";
|
|
18
18
|
import { useEffect, useState } from "react";
|
|
19
|
-
import Markdown from "react-markdown";
|
|
20
|
-
import remarkGfm from "remark-gfm";
|
|
21
19
|
|
|
22
20
|
interface DocumentPreviewPanelProps {
|
|
23
21
|
objectId: string | null;
|
|
@@ -233,7 +231,7 @@ export function DocumentPreviewPanel({
|
|
|
233
231
|
<div className="shadow rounded-md p-4 border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800">
|
|
234
232
|
{seemsMarkdown ? (
|
|
235
233
|
<div className="prose prose-sm max-w-none prose-p:my-2 prose-pre:bg-gray-800 prose-pre:my-2 prose-headings:text-indigo-700 dark:prose-invert dark:prose-headings:text-indigo-300">
|
|
236
|
-
<
|
|
234
|
+
<MarkdownRenderer>{text}</MarkdownRenderer>
|
|
237
235
|
</div>
|
|
238
236
|
) : (
|
|
239
237
|
<pre className="text-wrap whitespace-pre-wrap dark:text-gray-200">
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
import { ColumnLayout, ContentObject, ContentObjectItem, ComplexSearchQuery } from '@vertesia/common';
|
|
3
|
+
import {
|
|
4
|
+
|
|
5
|
+
Button, Divider, ErrorBox, SidePanel, Spinner, useIntersectionObserver, useToast,
|
|
6
|
+
FilterProvider, FilterBtn, FilterBar, FilterClear, Filter as BaseFilter
|
|
7
|
+
} from '@vertesia/ui/core';
|
|
5
8
|
import { useNavigate } from "@vertesia/ui/router";
|
|
6
9
|
import { TypeRegistry, useUserSession } from '@vertesia/ui/session';
|
|
7
10
|
import { Download, RefreshCw, Eye } from 'lucide-react';
|
|
8
|
-
import { FilterProvider, FilterBtn, FilterBar, FilterClear, Filter as BaseFilter } from '@vertesia/ui/core';
|
|
9
11
|
import { useDocumentFilterGroups, useDocumentFilterHandler } from "../../facets/DocumentsFacetsNav";
|
|
10
12
|
import { VectorSearchWidget } from './components/VectorSearchWidget';
|
|
11
|
-
|
|
12
13
|
import { ContentDispositionButton } from './components/ContentDispositionButton';
|
|
13
14
|
import { DocumentTable } from './DocumentTable';
|
|
14
15
|
import { useDocumentSearch, useWatchDocumentSearchFacets, useWatchDocumentSearchResult } from './search/DocumentSearchContext';
|
|
@@ -90,7 +91,6 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
|
|
|
90
91
|
const [selectedObject, setSelectedObject] = useState<ContentObjectItem | null>(null);
|
|
91
92
|
const { typeRegistry } = useUserSession();
|
|
92
93
|
const { search, isLoading, error, objects } = useWatchDocumentSearchResult();
|
|
93
|
-
const [vQuery, setVQuery] = useState<VectorSearchQuery | undefined>(undefined);
|
|
94
94
|
const [actualLayout, setActualLayout] = useState<ColumnLayout[]>(
|
|
95
95
|
typeRegistry ? layout || getTableLayout(typeRegistry, search.query.type) : defaultLayout,
|
|
96
96
|
);
|
|
@@ -111,37 +111,35 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
|
|
|
111
111
|
}
|
|
112
112
|
}, { deps: [isReady, objects.length] });
|
|
113
113
|
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
search.search().then(() => setIsReady(true));
|
|
116
|
-
}, []);
|
|
117
114
|
|
|
118
|
-
//
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (vQuery) {
|
|
128
|
-
search.query.vector = vQuery;
|
|
129
|
-
if (!actualLayout.find((c) => c.name === "Vector Similarity")) {
|
|
115
|
+
// Handler for vector search widget
|
|
116
|
+
const handleVectorSearch = (query?: ComplexSearchQuery) => {
|
|
117
|
+
if (query && query.vector) {
|
|
118
|
+
search.query.vector = query.vector;
|
|
119
|
+
search.query.full_text = query.full_text;
|
|
120
|
+
search.query.weights = query.weights;
|
|
121
|
+
search.query.score_aggregation = query.score_aggregation;
|
|
122
|
+
search.query.dynamic_scaling = query.dynamic_scaling;
|
|
123
|
+
if (!actualLayout.find((c) => c.name === "Search Score")) {
|
|
130
124
|
const layout = [
|
|
131
125
|
...actualLayout,
|
|
132
126
|
{
|
|
133
|
-
name: "
|
|
127
|
+
name: "Search Score",
|
|
134
128
|
field: "score",
|
|
135
129
|
} satisfies ColumnLayout,
|
|
136
130
|
];
|
|
137
131
|
setActualLayout(layout);
|
|
138
132
|
}
|
|
139
133
|
search.search().then(() => setIsReady(true));
|
|
134
|
+
} else if (query && query.full_text) {
|
|
135
|
+
search.query.full_text = query.full_text;
|
|
136
|
+
search.search().then(() => setIsReady(true));
|
|
140
137
|
} else {
|
|
141
138
|
delete search.query.vector;
|
|
139
|
+
delete search.query.full_text;
|
|
142
140
|
search.search().then(() => setIsReady(true));
|
|
143
141
|
}
|
|
144
|
-
}
|
|
142
|
+
};
|
|
145
143
|
|
|
146
144
|
const facets = useWatchDocumentSearchFacets();
|
|
147
145
|
const facetSearch = useDocumentSearch();
|
|
@@ -202,7 +200,7 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
|
|
|
202
200
|
<div className="flex flex-row gap-4 items-center justify-between w-full">
|
|
203
201
|
<div className="flex gap-2 items-center w-2/3">
|
|
204
202
|
{
|
|
205
|
-
allowSearch && <VectorSearchWidget onChange={
|
|
203
|
+
allowSearch && <VectorSearchWidget onChange={handleVectorSearch} isLoading={isLoading} refresh={refreshTrigger} className="w-full" />
|
|
206
204
|
}
|
|
207
205
|
<FilterBtn />
|
|
208
206
|
</div>
|
|
@@ -223,7 +221,7 @@ export function DocumentSearchResults({ layout, onUpload, allowFilter = true, al
|
|
|
223
221
|
<div className="flex flex-row gap-4 items-center justify-between w-full">
|
|
224
222
|
<div className="flex gap-2 items-center w-2/3">
|
|
225
223
|
{
|
|
226
|
-
allowSearch && <VectorSearchWidget onChange={
|
|
224
|
+
allowSearch && <VectorSearchWidget onChange={handleVectorSearch} isLoading={isLoading} refresh={refreshTrigger} />
|
|
227
225
|
}
|
|
228
226
|
</div>
|
|
229
227
|
<div className="flex gap-1 items-center">
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { useEffect, useState } from "react";
|
|
2
|
-
import Markdown from "react-markdown";
|
|
3
|
-
import remarkGfm from "remark-gfm";
|
|
4
2
|
|
|
5
3
|
import { useUserSession } from "@vertesia/ui/session";
|
|
6
4
|
import { Button, Spinner, useToast } from "@vertesia/ui/core";
|
|
7
|
-
import { JSONDisplay } from "@vertesia/ui/widgets";
|
|
5
|
+
import { JSONDisplay, MarkdownRenderer } from "@vertesia/ui/widgets";
|
|
8
6
|
import { ContentObject, ImageRenditionFormat } from "@vertesia/common";
|
|
9
7
|
import { Copy, Download, SquarePen } from "lucide-react";
|
|
10
8
|
import { PropertiesEditorModal } from "./PropertiesEditorModal";
|
|
@@ -314,8 +312,7 @@ export function ContentOverview({
|
|
|
314
312
|
<div className="border shadow-xs rounded-xs max-w-7xl">
|
|
315
313
|
{seemsMarkdown ? (
|
|
316
314
|
<div className="vprose prose-sm p-1">
|
|
317
|
-
<
|
|
318
|
-
remarkPlugins={[remarkGfm]}
|
|
315
|
+
<MarkdownRenderer
|
|
319
316
|
components={{
|
|
320
317
|
a: ({ node, ...props }: { node?: any; href?: string; children?: React.ReactNode }) => {
|
|
321
318
|
const href = props.href || "";
|
|
@@ -378,7 +375,7 @@ export function ContentOverview({
|
|
|
378
375
|
}}
|
|
379
376
|
>
|
|
380
377
|
{text}
|
|
381
|
-
</
|
|
378
|
+
</MarkdownRenderer>
|
|
382
379
|
</div>
|
|
383
380
|
) : (
|
|
384
381
|
<pre className="text-wrap bg-muted text-muted p-2">
|