@vertesia/ui 0.80.0-dev.20251121 → 0.80.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/README.md +105 -0
- package/lib/esm/core/components/MenuList.js +2 -5
- package/lib/esm/core/components/MenuList.js.map +1 -1
- package/lib/esm/core/components/MessageBox.js +1 -1
- package/lib/esm/core/components/MessageBox.js.map +1 -1
- package/lib/esm/core/components/shadcn/dialog.js +16 -2
- package/lib/esm/core/components/shadcn/dialog.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/filter/SelectFilter.js +6 -9
- package/lib/esm/core/components/shadcn/filters/filter/SelectFilter.js.map +1 -1
- package/lib/esm/core/components/shadcn/filters/filterBar.js +1 -1
- package/lib/esm/core/components/shadcn/filters/filterBar.js.map +1 -1
- package/lib/esm/core/components/shadcn/selectBox.js +23 -5
- package/lib/esm/core/components/shadcn/selectBox.js.map +1 -1
- package/lib/esm/core/components/shadcn/tabs.js +3 -3
- package/lib/esm/core/components/shadcn/tabs.js.map +1 -1
- package/lib/esm/env/index.js +3 -0
- package/lib/esm/env/index.js.map +1 -1
- package/lib/esm/features/agent/chat/AgentChart.js +184 -0
- package/lib/esm/features/agent/chat/AgentChart.js.map +1 -0
- package/lib/esm/features/agent/chat/ModernAgentConversation.js +87 -10
- package/lib/esm/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +6 -2
- package/lib/esm/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js +4 -4
- package/lib/esm/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js +4 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageInput.js +12 -4
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js +60 -56
- package/lib/esm/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/esm/features/agent/chat/index.js +1 -0
- package/lib/esm/features/agent/chat/index.js.map +1 -1
- package/lib/esm/features/agent/createChartTool.js +354 -0
- package/lib/esm/features/agent/createChartTool.js.map +1 -0
- package/lib/esm/features/agent/examples.js +295 -0
- package/lib/esm/features/agent/examples.js.map +1 -0
- package/lib/esm/features/agent/index.js +2 -0
- package/lib/esm/features/agent/index.js.map +1 -1
- package/lib/esm/features/agent/visualization.js +165 -0
- package/lib/esm/features/agent/visualization.js.map +1 -0
- package/lib/esm/features/facets/CollectionsFacetsNav.js +5 -1
- package/lib/esm/features/facets/CollectionsFacetsNav.js.map +1 -1
- package/lib/esm/features/index.js +1 -0
- package/lib/esm/features/index.js.map +1 -1
- package/lib/esm/features/layout/GenericPageNavHeader.js +14 -4
- package/lib/esm/features/layout/GenericPageNavHeader.js.map +1 -1
- package/lib/esm/features/magic-pdf/AnnotatedImageSlider.js +268 -0
- package/lib/esm/features/magic-pdf/AnnotatedImageSlider.js.map +1 -0
- package/lib/esm/features/magic-pdf/DownloadPopover.js +11 -11
- package/lib/esm/features/magic-pdf/DownloadPopover.js.map +1 -1
- package/lib/esm/features/magic-pdf/ExtractedContentView.js +77 -0
- package/lib/esm/features/magic-pdf/ExtractedContentView.js.map +1 -0
- package/lib/esm/features/magic-pdf/MagicPdfProvider.js +242 -0
- package/lib/esm/features/magic-pdf/MagicPdfProvider.js.map +1 -0
- package/lib/esm/features/magic-pdf/MagicPdfView.js +41 -47
- package/lib/esm/features/magic-pdf/MagicPdfView.js.map +1 -1
- package/lib/esm/features/pdf-viewer/PdfPageRenderer.js +261 -0
- package/lib/esm/features/pdf-viewer/PdfPageRenderer.js.map +1 -0
- package/lib/esm/features/pdf-viewer/PdfPageSlider.js +276 -0
- package/lib/esm/features/pdf-viewer/PdfPageSlider.js.map +1 -0
- package/lib/esm/features/pdf-viewer/SimplePdfViewer.js +71 -0
- package/lib/esm/features/pdf-viewer/SimplePdfViewer.js.map +1 -0
- package/lib/esm/features/pdf-viewer/index.js +4 -0
- package/lib/esm/features/pdf-viewer/index.js.map +1 -0
- package/lib/esm/features/store/collections/EditCollectionView.js +3 -5
- package/lib/esm/features/store/collections/EditCollectionView.js.map +1 -1
- package/lib/esm/features/store/collections/SharedPropsEditor.js +1 -2
- package/lib/esm/features/store/collections/SharedPropsEditor.js.map +1 -1
- package/lib/esm/features/store/objects/DocumentSearchResults.js +0 -7
- package/lib/esm/features/store/objects/DocumentSearchResults.js.map +1 -1
- package/lib/esm/features/store/objects/components/ContentOverview.js +273 -83
- package/lib/esm/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/esm/features/store/objects/components/useContentPanelHooks.js +153 -0
- package/lib/esm/features/store/objects/components/useContentPanelHooks.js.map +1 -0
- package/lib/esm/features/store/objects/layout/DocumentTableColumn.js +3 -3
- package/lib/esm/features/store/objects/layout/DocumentTableColumn.js.map +1 -1
- package/lib/esm/features/store/objects/layout/renderers.js +13 -0
- package/lib/esm/features/store/objects/layout/renderers.js.map +1 -1
- package/lib/esm/features/utils/index.js +2 -0
- package/lib/esm/features/utils/index.js.map +1 -1
- package/lib/esm/features/utils/mimeType.js +8 -0
- package/lib/esm/features/utils/mimeType.js.map +1 -1
- package/lib/esm/features/utils/print.js +181 -0
- package/lib/esm/features/utils/print.js.map +1 -0
- package/lib/esm/features/utils/workflowStatus.js +43 -0
- package/lib/esm/features/utils/workflowStatus.js.map +1 -0
- package/lib/esm/router/HistoryNavigator.js +22 -2
- package/lib/esm/router/HistoryNavigator.js.map +1 -1
- package/lib/esm/shell/login/UserInfo.js +2 -1
- package/lib/esm/shell/login/UserInfo.js.map +1 -1
- package/lib/esm/shell/login/UserSessionMenu.js +7 -1
- package/lib/esm/shell/login/UserSessionMenu.js.map +1 -1
- package/lib/esm/widgets/form/Form.js +6 -2
- package/lib/esm/widgets/form/Form.js.map +1 -1
- package/lib/esm/widgets/markdown/MarkdownRenderer.js +226 -4
- package/lib/esm/widgets/markdown/MarkdownRenderer.js.map +1 -1
- package/lib/esm/widgets/schema-editor/ManagedSchema.js +0 -3
- package/lib/esm/widgets/schema-editor/ManagedSchema.js.map +1 -1
- package/lib/esm/widgets/schema-editor/json-schema4-utils.js +1 -1
- package/lib/esm/widgets/schema-editor/json-schema4-utils.js.map +1 -1
- package/lib/esm/widgets/xml-viewer/components/XMLViewer.js +18 -9
- package/lib/esm/widgets/xml-viewer/components/XMLViewer.js.map +1 -1
- package/lib/esm/widgets/xml-viewer/constants/index.js +10 -0
- package/lib/esm/widgets/xml-viewer/constants/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/core/components/MessageBox.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/dialog.d.ts +2 -1
- package/lib/types/core/components/shadcn/dialog.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/selectBox.d.ts +5 -1
- package/lib/types/core/components/shadcn/selectBox.d.ts.map +1 -1
- package/lib/types/core/components/shadcn/tabs.d.ts +3 -1
- package/lib/types/core/components/shadcn/tabs.d.ts.map +1 -1
- package/lib/types/env/index.d.ts +2 -0
- package/lib/types/env/index.d.ts.map +1 -1
- package/lib/types/features/agent/chat/AgentChart.d.ts +48 -0
- package/lib/types/features/agent/chat/AgentChart.d.ts.map +1 -0
- package/lib/types/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +3 -2
- package/lib/types/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts +2 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/Header.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts +4 -2
- package/lib/types/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +2 -4
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
- package/lib/types/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/types/features/agent/chat/index.d.ts +1 -0
- package/lib/types/features/agent/chat/index.d.ts.map +1 -1
- package/lib/types/features/agent/createChartTool.d.ts +178 -0
- package/lib/types/features/agent/createChartTool.d.ts.map +1 -0
- package/lib/types/features/agent/examples.d.ts +59 -0
- package/lib/types/features/agent/examples.d.ts.map +1 -0
- package/lib/types/features/agent/index.d.ts +2 -0
- package/lib/types/features/agent/index.d.ts.map +1 -1
- package/lib/types/features/agent/visualization.d.ts +95 -0
- package/lib/types/features/agent/visualization.d.ts.map +1 -0
- package/lib/types/features/facets/CollectionsFacetsNav.d.ts.map +1 -1
- package/lib/types/features/index.d.ts +1 -0
- package/lib/types/features/index.d.ts.map +1 -1
- package/lib/types/features/layout/GenericPageNavHeader.d.ts.map +1 -1
- package/lib/types/features/magic-pdf/AnnotatedImageSlider.d.ts +13 -0
- package/lib/types/features/magic-pdf/AnnotatedImageSlider.d.ts.map +1 -0
- package/lib/types/features/magic-pdf/DownloadPopover.d.ts.map +1 -1
- package/lib/types/features/magic-pdf/ExtractedContentView.d.ts +8 -0
- package/lib/types/features/magic-pdf/ExtractedContentView.d.ts.map +1 -0
- package/lib/types/features/magic-pdf/MagicPdfProvider.d.ts +58 -0
- package/lib/types/features/magic-pdf/MagicPdfProvider.d.ts.map +1 -0
- package/lib/types/features/magic-pdf/MagicPdfView.d.ts +1 -1
- package/lib/types/features/magic-pdf/MagicPdfView.d.ts.map +1 -1
- package/lib/types/features/pdf-viewer/PdfPageRenderer.d.ts +83 -0
- package/lib/types/features/pdf-viewer/PdfPageRenderer.d.ts.map +1 -0
- package/lib/types/features/pdf-viewer/PdfPageSlider.d.ts +29 -0
- package/lib/types/features/pdf-viewer/PdfPageSlider.d.ts.map +1 -0
- package/lib/types/features/pdf-viewer/SimplePdfViewer.d.ts +19 -0
- package/lib/types/features/pdf-viewer/SimplePdfViewer.d.ts.map +1 -0
- package/lib/types/features/pdf-viewer/index.d.ts +4 -0
- package/lib/types/features/pdf-viewer/index.d.ts.map +1 -0
- package/lib/types/features/store/collections/EditCollectionView.d.ts.map +1 -1
- package/lib/types/features/store/collections/SharedPropsEditor.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/useContentPanelHooks.d.ts +30 -0
- package/lib/types/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -0
- package/lib/types/features/store/objects/layout/renderers.d.ts.map +1 -1
- package/lib/types/features/utils/index.d.ts +2 -0
- package/lib/types/features/utils/index.d.ts.map +1 -1
- package/lib/types/features/utils/mimeType.d.ts +1 -0
- package/lib/types/features/utils/mimeType.d.ts.map +1 -1
- package/lib/types/features/utils/print.d.ts +10 -0
- package/lib/types/features/utils/print.d.ts.map +1 -0
- package/lib/types/features/utils/workflowStatus.d.ts +10 -0
- package/lib/types/features/utils/workflowStatus.d.ts.map +1 -0
- package/lib/types/router/HistoryNavigator.d.ts +3 -0
- package/lib/types/router/HistoryNavigator.d.ts.map +1 -1
- package/lib/types/shell/login/UserInfo.d.ts.map +1 -1
- package/lib/types/shell/login/UserSessionMenu.d.ts.map +1 -1
- package/lib/types/widgets/form/Form.d.ts.map +1 -1
- package/lib/types/widgets/markdown/MarkdownRenderer.d.ts +5 -1
- package/lib/types/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
- package/lib/types/widgets/schema-editor/ManagedSchema.d.ts.map +1 -1
- package/lib/types/widgets/xml-viewer/components/XMLViewer.d.ts.map +1 -1
- package/lib/types/widgets/xml-viewer/constants/index.d.ts +10 -0
- package/lib/types/widgets/xml-viewer/constants/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-env.js +1 -1
- package/lib/vertesia-ui-env.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-layout.js +1 -1
- package/lib/vertesia-ui-layout.js.map +1 -1
- package/lib/vertesia-ui-router.js +1 -1
- package/lib/vertesia-ui-router.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 +11 -8
- package/src/core/components/MenuList.tsx +3 -6
- package/src/core/components/MessageBox.tsx +7 -2
- package/src/core/components/SelectBox.tsx +1 -1
- package/src/core/components/shadcn/dialog.tsx +19 -1
- package/src/core/components/shadcn/filters/filter/SelectFilter.tsx +31 -31
- package/src/core/components/shadcn/filters/filterBar.tsx +1 -0
- package/src/core/components/shadcn/selectBox.tsx +32 -6
- package/src/core/components/shadcn/tabs.tsx +3 -2
- package/src/env/index.ts +5 -0
- package/src/features/agent/CHART_INSTRUCTIONS.md +228 -0
- package/src/features/agent/chat/AgentChart.tsx +601 -0
- package/src/features/agent/chat/ModernAgentConversation.tsx +123 -11
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +8 -2
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +12 -2
- package/src/features/agent/chat/ModernAgentOutput/InlineSlidingPlanPanel.tsx +6 -1
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +15 -10
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +122 -87
- package/src/features/agent/chat/index.ts +1 -0
- package/src/features/agent/createChartTool.ts +364 -0
- package/src/features/agent/examples.ts +321 -0
- package/src/features/agent/index.ts +2 -0
- package/src/features/agent/visualization.ts +227 -0
- package/src/features/facets/CollectionsFacetsNav.tsx +5 -1
- package/src/features/index.ts +1 -0
- package/src/features/layout/GenericPageNavHeader.tsx +15 -4
- package/src/features/magic-pdf/AnnotatedImageSlider.tsx +482 -0
- package/src/features/magic-pdf/DownloadPopover.tsx +45 -40
- package/src/features/magic-pdf/ExtractedContentView.tsx +132 -0
- package/src/features/magic-pdf/MagicPdfProvider.tsx +297 -0
- package/src/features/magic-pdf/MagicPdfView.tsx +184 -91
- package/src/features/pdf-viewer/PdfPageRenderer.tsx +612 -0
- package/src/features/pdf-viewer/PdfPageSlider.tsx +473 -0
- package/src/features/pdf-viewer/SimplePdfViewer.tsx +142 -0
- package/src/features/pdf-viewer/index.ts +3 -0
- package/src/features/store/collections/EditCollectionView.tsx +3 -5
- package/src/features/store/collections/SharedPropsEditor.tsx +1 -2
- package/src/features/store/objects/DocumentSearchResults.tsx +0 -7
- package/src/features/store/objects/components/ContentOverview.tsx +677 -210
- package/src/features/store/objects/components/useContentPanelHooks.ts +169 -0
- package/src/features/store/objects/layout/DocumentTableColumn.tsx +3 -3
- package/src/features/store/objects/layout/knowledge.md +1 -0
- package/src/features/store/objects/layout/renderers.tsx +25 -0
- package/src/features/utils/index.ts +3 -1
- package/src/features/utils/mimeType.ts +10 -1
- package/src/features/utils/print.ts +189 -0
- package/src/features/utils/workflowStatus.ts +44 -0
- package/src/router/HistoryNavigator.ts +30 -2
- package/src/shell/login/UserInfo.tsx +2 -0
- package/src/shell/login/UserSessionMenu.tsx +12 -1
- package/src/widgets/form/Form.tsx +8 -3
- package/src/widgets/markdown/MarkdownRenderer.tsx +350 -6
- package/src/widgets/schema-editor/ManagedSchema.ts +0 -3
- package/src/widgets/schema-editor/json-schema4-utils.ts +1 -1
- package/src/widgets/xml-viewer/components/XMLViewer.tsx +22 -10
- package/src/widgets/xml-viewer/constants/index.ts +11 -0
- package/lib/esm/features/magic-pdf/PageSlider.js +0 -70
- package/lib/esm/features/magic-pdf/PageSlider.js.map +0 -1
- package/lib/esm/features/magic-pdf/PdfPageProvider.js +0 -188
- package/lib/esm/features/magic-pdf/PdfPageProvider.js.map +0 -1
- package/lib/esm/features/magic-pdf/TextPageView.js +0 -62
- package/lib/esm/features/magic-pdf/TextPageView.js.map +0 -1
- package/lib/esm/features/magic-pdf/useResizeOnDrag.js +0 -34
- package/lib/esm/features/magic-pdf/useResizeOnDrag.js.map +0 -1
- package/lib/types/features/magic-pdf/PageSlider.d.ts +0 -9
- package/lib/types/features/magic-pdf/PageSlider.d.ts.map +0 -1
- package/lib/types/features/magic-pdf/PdfPageProvider.d.ts +0 -39
- package/lib/types/features/magic-pdf/PdfPageProvider.d.ts.map +0 -1
- package/lib/types/features/magic-pdf/TextPageView.d.ts +0 -8
- package/lib/types/features/magic-pdf/TextPageView.d.ts.map +0 -1
- package/lib/types/features/magic-pdf/useResizeOnDrag.d.ts +0 -9
- package/lib/types/features/magic-pdf/useResizeOnDrag.d.ts.map +0 -1
- package/src/features/magic-pdf/PageSlider.tsx +0 -142
- package/src/features/magic-pdf/PdfPageProvider.tsx +0 -310
- package/src/features/magic-pdf/TextPageView.tsx +0 -91
- package/src/features/magic-pdf/useResizeOnDrag.ts +0 -42
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { useUserSession } from "@vertesia/ui/session";
|
|
3
|
+
import { DocAnalyzerProgress, DocProcessorOutputFormat, MarkdownRenditionFormat, WorkflowExecutionStatus } from "@vertesia/common";
|
|
4
|
+
|
|
5
|
+
// Maximum text size before cropping (128K characters)
|
|
6
|
+
const MAX_TEXT_DISPLAY_SIZE = 128 * 1024;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hook for managing object text loading and cropping.
|
|
10
|
+
*/
|
|
11
|
+
export function useObjectText(objectId: string, initialText?: string, loadOnMount = false) {
|
|
12
|
+
const { store } = useUserSession();
|
|
13
|
+
|
|
14
|
+
const [fullText, setFullText] = useState<string | undefined>(initialText);
|
|
15
|
+
const [displayText, setDisplayText] = useState<string | undefined>(() => {
|
|
16
|
+
if (initialText && initialText.length > MAX_TEXT_DISPLAY_SIZE) {
|
|
17
|
+
return initialText.substring(0, MAX_TEXT_DISPLAY_SIZE);
|
|
18
|
+
}
|
|
19
|
+
return initialText;
|
|
20
|
+
});
|
|
21
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
22
|
+
const [isCropped, setIsCropped] = useState(
|
|
23
|
+
() => !!initialText && initialText.length > MAX_TEXT_DISPLAY_SIZE
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const loadText = useCallback(() => {
|
|
27
|
+
setIsLoading(true);
|
|
28
|
+
store.objects
|
|
29
|
+
.getObjectText(objectId)
|
|
30
|
+
.then((res) => {
|
|
31
|
+
setFullText(res.text);
|
|
32
|
+
if (res.text.length > MAX_TEXT_DISPLAY_SIZE) {
|
|
33
|
+
setDisplayText(res.text.substring(0, MAX_TEXT_DISPLAY_SIZE));
|
|
34
|
+
setIsCropped(true);
|
|
35
|
+
} else {
|
|
36
|
+
setDisplayText(res.text);
|
|
37
|
+
setIsCropped(false);
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.catch((err) => {
|
|
41
|
+
console.error("Failed to load text", err);
|
|
42
|
+
})
|
|
43
|
+
.finally(() => {
|
|
44
|
+
setIsLoading(false);
|
|
45
|
+
});
|
|
46
|
+
}, [objectId, store]);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (loadOnMount && !displayText) {
|
|
50
|
+
loadText();
|
|
51
|
+
}
|
|
52
|
+
}, [loadOnMount, displayText, loadText]);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
fullText,
|
|
56
|
+
displayText,
|
|
57
|
+
isLoading,
|
|
58
|
+
isCropped,
|
|
59
|
+
loadText,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Hook for polling PDF/document processing status.
|
|
65
|
+
*/
|
|
66
|
+
export function usePdfProcessingStatus(objectId: string, shouldPoll: boolean) {
|
|
67
|
+
const { client } = useUserSession();
|
|
68
|
+
|
|
69
|
+
const [progress, setProgress] = useState<DocAnalyzerProgress | undefined>();
|
|
70
|
+
const [status, setStatus] = useState<WorkflowExecutionStatus | undefined>();
|
|
71
|
+
const [outputFormat, setOutputFormat] = useState<DocProcessorOutputFormat | undefined>();
|
|
72
|
+
const [isComplete, setIsComplete] = useState(false);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!shouldPoll) return;
|
|
76
|
+
|
|
77
|
+
let interrupted = false;
|
|
78
|
+
|
|
79
|
+
function poll() {
|
|
80
|
+
if (interrupted) return;
|
|
81
|
+
|
|
82
|
+
client.objects.analyze(objectId).getStatus()
|
|
83
|
+
.then((r) => {
|
|
84
|
+
setProgress(r.progress);
|
|
85
|
+
setStatus(r.status);
|
|
86
|
+
setOutputFormat(r.output_format ?? r.progress?.output_format);
|
|
87
|
+
|
|
88
|
+
if (r.status === WorkflowExecutionStatus.RUNNING) {
|
|
89
|
+
// Workflow is running, poll every 2 seconds for progress
|
|
90
|
+
if (!interrupted) {
|
|
91
|
+
setTimeout(poll, 2000);
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
// Workflow completed or terminal state
|
|
95
|
+
setIsComplete(true);
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
.catch(() => {
|
|
99
|
+
// No workflow found yet, poll every 10 seconds to check if one starts
|
|
100
|
+
if (!interrupted) {
|
|
101
|
+
setTimeout(poll, 10000);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
poll();
|
|
107
|
+
return () => { interrupted = true; };
|
|
108
|
+
}, [shouldPoll, objectId, client]);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
progress,
|
|
112
|
+
status,
|
|
113
|
+
outputFormat,
|
|
114
|
+
isComplete,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Hook for managing Office document to PDF conversion.
|
|
120
|
+
*/
|
|
121
|
+
export function useOfficePdfConversion(objectId: string, enabled: boolean) {
|
|
122
|
+
const { client } = useUserSession();
|
|
123
|
+
|
|
124
|
+
const [pdfUrl, setPdfUrl] = useState<string | undefined>();
|
|
125
|
+
const [isConverting, setIsConverting] = useState(false);
|
|
126
|
+
const [error, setError] = useState<string | undefined>();
|
|
127
|
+
|
|
128
|
+
const triggerConversion = useCallback(async () => {
|
|
129
|
+
if (!enabled || isConverting) return;
|
|
130
|
+
|
|
131
|
+
setIsConverting(true);
|
|
132
|
+
setError(undefined);
|
|
133
|
+
|
|
134
|
+
const pollForPdf = async (isFirstCall: boolean) => {
|
|
135
|
+
try {
|
|
136
|
+
const response = await client.objects.getRendition(objectId, {
|
|
137
|
+
format: MarkdownRenditionFormat.pdf,
|
|
138
|
+
generate_if_missing: isFirstCall,
|
|
139
|
+
sign_url: true,
|
|
140
|
+
block_on_generation: false,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
if (response.status === "generating") {
|
|
144
|
+
// Poll every 5 seconds
|
|
145
|
+
setTimeout(() => pollForPdf(false), 5000);
|
|
146
|
+
} else if (response.status === "found" && response.renditions?.length) {
|
|
147
|
+
setPdfUrl(response.renditions[0]);
|
|
148
|
+
setIsConverting(false);
|
|
149
|
+
} else if (response.status === "failed") {
|
|
150
|
+
setError("PDF conversion failed");
|
|
151
|
+
setIsConverting(false);
|
|
152
|
+
}
|
|
153
|
+
} catch (err) {
|
|
154
|
+
console.error("Failed to convert Office document to PDF:", err);
|
|
155
|
+
setError("Failed to convert to PDF");
|
|
156
|
+
setIsConverting(false);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
await pollForPdf(true);
|
|
161
|
+
}, [objectId, enabled, isConverting, client]);
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
pdfUrl,
|
|
165
|
+
isConverting,
|
|
166
|
+
error,
|
|
167
|
+
triggerConversion,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
@@ -84,13 +84,13 @@ export class DocumentTableColumn {
|
|
|
84
84
|
const type = this.layout.type || 'string';
|
|
85
85
|
const baseType = type.indexOf('?') > 0 ? type.substring(0, type.indexOf('?')) : type;
|
|
86
86
|
|
|
87
|
-
if (baseType === 'objectId' && this.previewObject) {
|
|
87
|
+
if ((baseType === 'objectId' || baseType === 'objectLink') && this.previewObject) {
|
|
88
88
|
const i = type.indexOf('?');
|
|
89
89
|
const params = i > 0 ? new URLSearchParams(type.substring(i + 1)) : undefined;
|
|
90
|
-
const
|
|
90
|
+
const renderer = renderers[baseType](params, (_id: string) => {
|
|
91
91
|
this.previewObject!(object.id);
|
|
92
92
|
});
|
|
93
|
-
return
|
|
93
|
+
return renderer(object, index);
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
// Otherwise use the type-based renderer with the resolved value
|
|
@@ -32,6 +32,7 @@ Complete list of supported types:
|
|
|
32
32
|
3. **date** - Date/time display
|
|
33
33
|
4. **objectId** - object id with preview button
|
|
34
34
|
5. **objectName** - object name display
|
|
35
|
+
6. **objectLink** - *(deprecated)* alias for objectId, kept for backward compatibility
|
|
35
36
|
|
|
36
37
|
### Column Types and Renderers
|
|
37
38
|
Built-in renderers with parameters:
|
|
@@ -131,6 +131,31 @@ const renderers: Record<string, (params?: URLSearchParams, onClick?: (id: string
|
|
|
131
131
|
);
|
|
132
132
|
};
|
|
133
133
|
},
|
|
134
|
+
// objectLink - same implementation as objectId but defaults to slice=-7
|
|
135
|
+
objectLink(_params?: URLSearchParams, onClick?: (id: string) => void) {
|
|
136
|
+
const transforms: ((value: string) => string)[] = [];
|
|
137
|
+
const hasSlice = true;
|
|
138
|
+
transforms.push((value) => value.slice(-7));
|
|
139
|
+
|
|
140
|
+
return (value: any, index: number) => {
|
|
141
|
+
const displayValue = transforms.reduce((v, t) => t(v), value.id);
|
|
142
|
+
return (
|
|
143
|
+
<td key={index} className="flex justify-between items-center gap-2 max-w-48">
|
|
144
|
+
{hasSlice ? "~" : ""}{displayValue}
|
|
145
|
+
<Button
|
|
146
|
+
variant="ghost"
|
|
147
|
+
alt="Preview Object"
|
|
148
|
+
onClick={(e) => {
|
|
149
|
+
e.stopPropagation();
|
|
150
|
+
onClick?.(value.id);
|
|
151
|
+
}}
|
|
152
|
+
>
|
|
153
|
+
<Eye className="size-4" />
|
|
154
|
+
</Button>
|
|
155
|
+
</td>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
},
|
|
134
159
|
typeLink(_params?: URLSearchParams, _onClick?: (id: string) => void) {
|
|
135
160
|
return (value: any, index: number) => {
|
|
136
161
|
return <td key={index}>{value?.name || "n/a"}</td>;
|
|
@@ -3,7 +3,16 @@ const IMAGE_PREFIX = 'image/'
|
|
|
3
3
|
const PDF_PREFIX = 'application/pdf'
|
|
4
4
|
const VIDEO_PREFIX = 'video/'
|
|
5
5
|
|
|
6
|
+
// Office document MIME types that can be converted to PDF for preview
|
|
7
|
+
const PREVIEWABLE_AS_PDF_TYPES = [
|
|
8
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
|
|
9
|
+
'application/msword', // .doc
|
|
10
|
+
'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
|
|
11
|
+
'application/vnd.ms-powerpoint', // .ppt
|
|
12
|
+
]
|
|
13
|
+
|
|
6
14
|
export const isCsv = (type: string) => type === CSV_PREFIX || CSV_PREFIX.includes(type)
|
|
7
15
|
export const isImage = (type: string) => type.startsWith(IMAGE_PREFIX) || IMAGE_PREFIX.includes(type)
|
|
8
16
|
export const isPdf = (type: string) => type === PDF_PREFIX || PDF_PREFIX.includes(type)
|
|
9
|
-
export const isVideo = (type: string) => type.startsWith(VIDEO_PREFIX) || VIDEO_PREFIX.includes(type)
|
|
17
|
+
export const isVideo = (type: string) => type.startsWith(VIDEO_PREFIX) || VIDEO_PREFIX.includes(type)
|
|
18
|
+
export const isPreviewableAsPdf = (type: string) => PREVIEWABLE_AS_PDF_TYPES.includes(type)
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Print styles for markdown content export to PDF.
|
|
3
|
+
* These styles ensure tables and other elements render properly in print mode,
|
|
4
|
+
* independent from the application theme.
|
|
5
|
+
*/
|
|
6
|
+
const PRINT_STYLES = `
|
|
7
|
+
@media print {
|
|
8
|
+
body {
|
|
9
|
+
margin: 24px;
|
|
10
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
11
|
+
font-size: 14px;
|
|
12
|
+
line-height: 1.5;
|
|
13
|
+
color: #111827;
|
|
14
|
+
background-color: #ffffff;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.vprose {
|
|
18
|
+
max-width: 800px;
|
|
19
|
+
margin: 0 auto;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.vprose h1 {
|
|
23
|
+
font-size: 24px;
|
|
24
|
+
font-weight: 700;
|
|
25
|
+
margin: 1.5rem 0 0.75rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.vprose h2 {
|
|
29
|
+
font-size: 20px;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
margin: 1.25rem 0 0.75rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.vprose h3 {
|
|
35
|
+
font-size: 18px;
|
|
36
|
+
font-weight: 600;
|
|
37
|
+
margin: 1rem 0 0.5rem;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.vprose p {
|
|
41
|
+
margin: 0 0 0.5rem;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.vprose ul,
|
|
45
|
+
.vprose ol {
|
|
46
|
+
margin: 0.5rem 0 0.5rem 1.5rem;
|
|
47
|
+
padding: 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.vprose li {
|
|
51
|
+
margin: 0.25rem 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.vprose table {
|
|
55
|
+
width: 100%;
|
|
56
|
+
border-collapse: collapse;
|
|
57
|
+
margin: 1rem 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.vprose th,
|
|
61
|
+
.vprose td {
|
|
62
|
+
border: 1px solid #d1d5db;
|
|
63
|
+
padding: 0.5rem 0.75rem;
|
|
64
|
+
vertical-align: top;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.vprose thead th {
|
|
68
|
+
background-color: #f3f4f6;
|
|
69
|
+
font-weight: 600;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.vprose pre,
|
|
73
|
+
.vprose code {
|
|
74
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.vprose pre {
|
|
79
|
+
padding: 0.75rem;
|
|
80
|
+
border-radius: 4px;
|
|
81
|
+
border: 1px solid #e5e7eb;
|
|
82
|
+
background-color: #f9fafb;
|
|
83
|
+
white-space: pre-wrap;
|
|
84
|
+
word-break: break-word;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Hide chart action buttons when printing */
|
|
88
|
+
.chart-actions {
|
|
89
|
+
display: none !important;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Hide interactive elements in agent conversation when printing */
|
|
93
|
+
.print-hidden,
|
|
94
|
+
[class*="print:hidden"],
|
|
95
|
+
button[title="Copy message"],
|
|
96
|
+
button[title="Copy to clipboard"],
|
|
97
|
+
button[title="Export as PNG"],
|
|
98
|
+
.message-actions {
|
|
99
|
+
display: none !important;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* Prevent page breaks inside elements */
|
|
103
|
+
.vprose table,
|
|
104
|
+
.vprose pre,
|
|
105
|
+
.vprose blockquote,
|
|
106
|
+
.vprose figure,
|
|
107
|
+
.vprose img,
|
|
108
|
+
.recharts-wrapper,
|
|
109
|
+
[class*="chart"],
|
|
110
|
+
[class*="Chart"] {
|
|
111
|
+
break-inside: avoid;
|
|
112
|
+
page-break-inside: avoid;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Keep headings with following content */
|
|
116
|
+
.vprose h1,
|
|
117
|
+
.vprose h2,
|
|
118
|
+
.vprose h3,
|
|
119
|
+
.vprose h4,
|
|
120
|
+
.vprose h5,
|
|
121
|
+
.vprose h6 {
|
|
122
|
+
break-after: avoid;
|
|
123
|
+
page-break-after: avoid;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/* Keep list items together when possible */
|
|
127
|
+
.vprose li {
|
|
128
|
+
break-inside: avoid;
|
|
129
|
+
page-break-inside: avoid;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Opens the browser print dialog with the content of a given HTML element.
|
|
136
|
+
* Uses a hidden iframe to avoid opening a new window.
|
|
137
|
+
*
|
|
138
|
+
* @param sourceElement - The HTML element whose content to print
|
|
139
|
+
* @param title - The document title for the printed page
|
|
140
|
+
* @returns true if print dialog was opened successfully, false otherwise
|
|
141
|
+
*/
|
|
142
|
+
export function printElementToPdf(sourceElement: HTMLElement, title: string): boolean {
|
|
143
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Use a hidden iframe to avoid opening a new window
|
|
148
|
+
const iframe = document.createElement("iframe");
|
|
149
|
+
iframe.style.position = "fixed";
|
|
150
|
+
iframe.style.right = "0";
|
|
151
|
+
iframe.style.bottom = "0";
|
|
152
|
+
iframe.style.width = "0";
|
|
153
|
+
iframe.style.height = "0";
|
|
154
|
+
iframe.style.border = "0";
|
|
155
|
+
iframe.style.visibility = "hidden";
|
|
156
|
+
document.body.appendChild(iframe);
|
|
157
|
+
|
|
158
|
+
const iframeWindow = iframe.contentWindow;
|
|
159
|
+
if (!iframeWindow) {
|
|
160
|
+
iframe.parentNode?.removeChild(iframe);
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const doc = iframeWindow.document;
|
|
165
|
+
doc.open();
|
|
166
|
+
doc.write(`<!doctype html><html><head><title>${title}</title></head><body></body></html>`);
|
|
167
|
+
doc.close();
|
|
168
|
+
doc.title = title;
|
|
169
|
+
|
|
170
|
+
const styles = document.querySelectorAll<HTMLLinkElement | HTMLStyleElement>("link[rel=\"stylesheet\"], style");
|
|
171
|
+
styles.forEach((node) => {
|
|
172
|
+
doc.head.appendChild(node.cloneNode(true));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Add dedicated print styles
|
|
176
|
+
const printStyle = doc.createElement("style");
|
|
177
|
+
printStyle.textContent = PRINT_STYLES;
|
|
178
|
+
doc.head.appendChild(printStyle);
|
|
179
|
+
|
|
180
|
+
doc.body.innerHTML = sourceElement.innerHTML;
|
|
181
|
+
iframeWindow.focus();
|
|
182
|
+
iframeWindow.print();
|
|
183
|
+
|
|
184
|
+
setTimeout(() => {
|
|
185
|
+
iframe.parentNode?.removeChild(iframe);
|
|
186
|
+
}, 1000);
|
|
187
|
+
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { WorkflowExecutionStatus } from "@vertesia/common";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the semantic color class for a workflow execution status.
|
|
5
|
+
*/
|
|
6
|
+
export function getWorkflowStatusColor(status?: WorkflowExecutionStatus): string {
|
|
7
|
+
switch (status) {
|
|
8
|
+
case WorkflowExecutionStatus.RUNNING:
|
|
9
|
+
return "text-info";
|
|
10
|
+
case WorkflowExecutionStatus.COMPLETED:
|
|
11
|
+
return "text-success";
|
|
12
|
+
case WorkflowExecutionStatus.FAILED:
|
|
13
|
+
return "text-destructive";
|
|
14
|
+
case WorkflowExecutionStatus.TERMINATED:
|
|
15
|
+
case WorkflowExecutionStatus.CANCELED:
|
|
16
|
+
return "text-attention";
|
|
17
|
+
default:
|
|
18
|
+
return "text-muted";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get a human-readable name for a workflow execution status.
|
|
24
|
+
*/
|
|
25
|
+
export function getWorkflowStatusName(status?: WorkflowExecutionStatus): string {
|
|
26
|
+
switch (status) {
|
|
27
|
+
case WorkflowExecutionStatus.RUNNING:
|
|
28
|
+
return "Running";
|
|
29
|
+
case WorkflowExecutionStatus.COMPLETED:
|
|
30
|
+
return "Completed";
|
|
31
|
+
case WorkflowExecutionStatus.FAILED:
|
|
32
|
+
return "Failed";
|
|
33
|
+
case WorkflowExecutionStatus.CONTINUED_AS_NEW:
|
|
34
|
+
return "Continued As New";
|
|
35
|
+
case WorkflowExecutionStatus.TERMINATED:
|
|
36
|
+
return "Terminated";
|
|
37
|
+
case WorkflowExecutionStatus.TIMED_OUT:
|
|
38
|
+
return "Timed Out";
|
|
39
|
+
case WorkflowExecutionStatus.CANCELED:
|
|
40
|
+
return "Canceled";
|
|
41
|
+
default:
|
|
42
|
+
return "Unknown";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -66,6 +66,10 @@ export interface NavigateOptions {
|
|
|
66
66
|
* if defined, indicate whether the basePath will be used as a top-level base path or a nested base path.
|
|
67
67
|
*/
|
|
68
68
|
isBasePathNested?: boolean;
|
|
69
|
+
// Number of steps to go back in history, which will pop the history stack instead of pushing a new entry
|
|
70
|
+
stepsBack?: number;
|
|
71
|
+
// the title to set for the new history entry
|
|
72
|
+
title?: string;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
function getElementHrefAsUrl(elem: HTMLElement) {
|
|
@@ -113,6 +117,11 @@ export class HistoryNavigator {
|
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
navigate(to: string, options: NavigateOptions = {}) {
|
|
120
|
+
if (options.stepsBack && options.stepsBack > 0) {
|
|
121
|
+
this.stepBack(options.stepsBack, options);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
116
125
|
if (options.basePath) {
|
|
117
126
|
let basePath = options.basePath;
|
|
118
127
|
if (!basePath.startsWith('/')) {
|
|
@@ -124,6 +133,24 @@ export class HistoryNavigator {
|
|
|
124
133
|
this._navigate(new URL(to, window.location.href), 'navigate', options);
|
|
125
134
|
}
|
|
126
135
|
|
|
136
|
+
stepBack(steps: number, options: NavigateOptions = {}) {
|
|
137
|
+
const historyChain = window.history.state.historyChain || [];
|
|
138
|
+
const to = historyChain.length >= steps
|
|
139
|
+
? new URL(historyChain[historyChain.length - steps].href, window.location.href)
|
|
140
|
+
: new URL(window.location.origin, window.location.href);
|
|
141
|
+
this._navigate(to, 'popState', options);
|
|
142
|
+
|
|
143
|
+
const stateToStore = {
|
|
144
|
+
from: window.location.href,
|
|
145
|
+
historyChain: historyChain.slice(0, -steps),
|
|
146
|
+
data: options.state || undefined,
|
|
147
|
+
title: options.title || document.title
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
window.history['replaceState'](stateToStore, '', to.href);
|
|
151
|
+
this.fireLocationChange(new AfterLocationChangeEvent('popState', to, options.state));
|
|
152
|
+
}
|
|
153
|
+
|
|
127
154
|
_navigate(to: URL, type: LocationChangeType, options: NavigateOptions) {
|
|
128
155
|
const beforeEvent = new BeforeLocationChangeEvent(type, to, options.state);
|
|
129
156
|
this.fireLocationChange(beforeEvent);
|
|
@@ -133,7 +160,7 @@ export class HistoryNavigator {
|
|
|
133
160
|
|
|
134
161
|
// Build navigation chain by preserving previous history
|
|
135
162
|
const currentState = window.history.state;
|
|
136
|
-
const currentTitle = document.title;
|
|
163
|
+
const currentTitle = options.title || document.title;
|
|
137
164
|
|
|
138
165
|
// Create new history chain entry
|
|
139
166
|
const newChainEntry = {
|
|
@@ -160,7 +187,8 @@ export class HistoryNavigator {
|
|
|
160
187
|
const stateToStore = {
|
|
161
188
|
from: window.location.href,
|
|
162
189
|
historyChain: historyChain,
|
|
163
|
-
data: options.state || undefined
|
|
190
|
+
data: options.state || undefined,
|
|
191
|
+
title: options.title || document.title
|
|
164
192
|
};
|
|
165
193
|
|
|
166
194
|
window.history[options.replace ? 'replaceState' : 'pushState'](stateToStore, '', to.href);
|
|
@@ -2,6 +2,7 @@ import { getTenantIdFromProject } from "@vertesia/common";
|
|
|
2
2
|
import { VTabs, VTabsBar, VTabsPanel, VTooltip } from "@vertesia/ui/core";
|
|
3
3
|
import { Env } from "@vertesia/ui/env";
|
|
4
4
|
import { useUserSession } from "@vertesia/ui/session";
|
|
5
|
+
// Package version is now passed as prop from the consuming application
|
|
5
6
|
import { Check, CopyIcon } from "lucide-react";
|
|
6
7
|
import { useState } from "react";
|
|
7
8
|
|
|
@@ -61,6 +62,7 @@ export default function InfoList() {
|
|
|
61
62
|
<InfoItems title="Server" value={server} />
|
|
62
63
|
<InfoItems title="Store" value={store} />
|
|
63
64
|
<InfoItems title="App Version" value={Env.version} />
|
|
65
|
+
<InfoItems title="SDK Version" value={Env.sdkVersion || 'unknown'} />
|
|
64
66
|
</div>
|
|
65
67
|
}
|
|
66
68
|
];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthTokenPayload } from "@vertesia/common";
|
|
1
|
+
import { AuthTokenPayload, Permission } from "@vertesia/common";
|
|
2
2
|
import { Avatar, Button, MenuList, ModeToggle, Spinner } from "@vertesia/ui/core";
|
|
3
3
|
import { useUserSession } from "@vertesia/ui/session";
|
|
4
4
|
import { Popover } from "@vertesia/ui/widgets";
|
|
@@ -6,6 +6,8 @@ import clsx from "clsx";
|
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
import SignInModal from "./SignInModal";
|
|
8
8
|
import InfoList from "./UserInfo";
|
|
9
|
+
import { useNavigate } from "@vertesia/ui/router";
|
|
10
|
+
import { useUserPermissions } from "@vertesia/ui/features";
|
|
9
11
|
interface UserSessionMenuProps {
|
|
10
12
|
name?: string
|
|
11
13
|
picture?: string;
|
|
@@ -38,9 +40,13 @@ interface UserSessionPopupProps {
|
|
|
38
40
|
}
|
|
39
41
|
function UserSessionPopup({ className, asMenuTrigger = false }: UserSessionPopupProps) {
|
|
40
42
|
const session = useUserSession();
|
|
43
|
+
const navigate = useNavigate();
|
|
44
|
+
const perms = useUserPermissions();
|
|
41
45
|
const { user } = session;
|
|
42
46
|
if (!session || !user) return null;
|
|
43
47
|
|
|
48
|
+
const isProjectManager = perms.hasPermission(Permission.project_admin);
|
|
49
|
+
|
|
44
50
|
return (
|
|
45
51
|
<Popover strategy='fixed' placement='bottom-start' zIndex={100}>
|
|
46
52
|
<Popover.Trigger click>
|
|
@@ -68,6 +74,11 @@ function UserSessionPopup({ className, asMenuTrigger = false }: UserSessionPopup
|
|
|
68
74
|
</div>
|
|
69
75
|
<div className='py-2'>
|
|
70
76
|
<MenuList>
|
|
77
|
+
{isProjectManager && (
|
|
78
|
+
<MenuList.Item className='px-2' onClick={() => navigate('/settings', { replace: true })}>
|
|
79
|
+
Settings
|
|
80
|
+
</MenuList.Item>
|
|
81
|
+
)}
|
|
71
82
|
<MenuList.Item className='px-2' onClick={() => session.logout()}>
|
|
72
83
|
Sign out
|
|
73
84
|
</MenuList.Item>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import type { JSONSchemaObject } from "@vertesia/common";
|
|
3
3
|
import { Button, FormItem } from "@vertesia/ui/core";
|
|
4
4
|
import clsx from "clsx";
|
|
5
|
-
import
|
|
5
|
+
import { Plus, Trash2 } from "lucide-react";
|
|
6
6
|
import { ComponentType, ReactNode, SyntheticEvent, useState } from "react";
|
|
7
7
|
import { FormContext, FormContextProvider, InputComponentProps, useForm } from "./FormContext.js";
|
|
8
8
|
import { ManagedListProperty, ManagedObject, ManagedObjectBase, ManagedProperty, Node } from "./ManagedObject.js";
|
|
@@ -94,10 +94,15 @@ export function ScalarField({ object, editor, inline = false }: ScalarFieldProps
|
|
|
94
94
|
object.value = object.schema.isNumber ? parseFloat(value) : value
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
if (object.isListItem) {
|
|
98
|
+
// List items don't need the FormItem wrapper (no label, description, etc.)
|
|
99
|
+
return <Component object={object} type={inputType} onChange={handleOnChange} disabled={disabled} />;
|
|
100
|
+
}
|
|
101
|
+
|
|
97
102
|
return (
|
|
98
103
|
<FormItem label={object.title} required={object.schema.isRequired} description={object.schema.description}
|
|
99
104
|
className={clsx('flex', inline ? 'flex-row items-center' : 'flex-col')}>
|
|
100
|
-
|
|
105
|
+
<Component object={object} type={inputType} onChange={handleOnChange} disabled={disabled} />
|
|
101
106
|
</FormItem>
|
|
102
107
|
)
|
|
103
108
|
}
|