@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertesia/ui",
|
|
3
|
-
"version": "0.80.0
|
|
3
|
+
"version": "0.80.0",
|
|
4
4
|
"description": "Vertesia UI components and and hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -44,26 +44,29 @@
|
|
|
44
44
|
"fast-xml-parser": "^5.2.3",
|
|
45
45
|
"firebase": "^10.12.2",
|
|
46
46
|
"framer-motion": "^12.23.12",
|
|
47
|
+
"html-to-image": "^1.11.13",
|
|
47
48
|
"json-schema": "^0.4.0",
|
|
48
49
|
"jwt-decode": "^4.0.0",
|
|
49
50
|
"lodash-es": "^4.17.21",
|
|
50
51
|
"lucide-react": "^0.511.0",
|
|
51
52
|
"monaco-editor": "^0.52.2",
|
|
52
53
|
"motion": "^12.12.1",
|
|
53
|
-
"react": "^19.
|
|
54
|
+
"react": "^19.2.3",
|
|
54
55
|
"react-calendar": "^6.0.0",
|
|
55
56
|
"react-date-picker": "^11.0.0",
|
|
56
|
-
"react-dom": "^19.
|
|
57
|
+
"react-dom": "^19.2.3",
|
|
57
58
|
"react-error-boundary": "^6.0.0",
|
|
58
59
|
"react-markdown": "^10.1.0",
|
|
60
|
+
"react-pdf": "^10.2.0",
|
|
59
61
|
"react-resizable-panels": "^3.0.6",
|
|
62
|
+
"recharts": "^3.5.0",
|
|
60
63
|
"remark-gfm": "^4.0.1",
|
|
61
64
|
"tailwind-merge": "^3.3.0",
|
|
62
65
|
"ts-md5": "^1.3.1",
|
|
63
66
|
"unist-util-visit": "^5.0.0",
|
|
64
|
-
"@vertesia/client": "0.80.0
|
|
65
|
-
"@vertesia/json": "0.80.0
|
|
66
|
-
"@vertesia/common": "0.80.0
|
|
67
|
+
"@vertesia/client": "0.80.0",
|
|
68
|
+
"@vertesia/json": "0.80.0",
|
|
69
|
+
"@vertesia/common": "0.80.0"
|
|
67
70
|
},
|
|
68
71
|
"devDependencies": {
|
|
69
72
|
"@eslint/js": "^9.27.0",
|
|
@@ -73,8 +76,8 @@
|
|
|
73
76
|
"@types/json-schema": "^7.0.15",
|
|
74
77
|
"@types/lodash-es": "^4.17.12",
|
|
75
78
|
"@types/node": "^22.15.21",
|
|
76
|
-
"@types/react": "^19.
|
|
77
|
-
"@types/react-dom": "^19.
|
|
79
|
+
"@types/react": "^19.2.3",
|
|
80
|
+
"@types/react-dom": "^19.2.3",
|
|
78
81
|
"eslint": "^9.27.0",
|
|
79
82
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
80
83
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -7,7 +7,7 @@ interface MenuListProps {
|
|
|
7
7
|
}
|
|
8
8
|
export function MenuList({ className, children }: MenuListProps) {
|
|
9
9
|
return (
|
|
10
|
-
<ul className={`${className} space-y-1 flex flex-col items-start
|
|
10
|
+
<ul className={`${className} space-y-1 flex flex-col items-start`}>
|
|
11
11
|
{children}
|
|
12
12
|
</ul>
|
|
13
13
|
)
|
|
@@ -21,11 +21,8 @@ interface MenuListItemProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
|
21
21
|
const MenuListItem = forwardRef<HTMLAnchorElement, MenuListItemProps>(function _MenuListItem(props, ref) {
|
|
22
22
|
const { current, children, className, href = '#', onClick, ...others } = props;
|
|
23
23
|
return (
|
|
24
|
-
<li className={clsx(className, current ?
|
|
25
|
-
'
|
|
26
|
-
:
|
|
27
|
-
'text-gray-700 dark:dark:text-slate-300 hover:text-indigo-600 hover:bg-gray-50 dark:hover:bg-slate-800 dark:hover:text-slate-50 dark:border dark:border-transparent dark:hover:border-slate-50',
|
|
28
|
-
'w-full rounded-md p-2 pl-3 text-sm leading-6 font-semibold')}>
|
|
24
|
+
<li className={clsx(className, current ? 'bg-muted' : '',
|
|
25
|
+
'w-full p-2 pl-3 text-sm leading-6 font-semibold hover:bg-muted')}>
|
|
29
26
|
<a ref={ref} href={href} onClick={(e) => {
|
|
30
27
|
if (onClick) {
|
|
31
28
|
e.preventDefault();
|
|
@@ -74,7 +74,13 @@ export function MessageBox({ icon, status, title, children, className }: Message
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export function ErrorBox({ title, className, children }: { title: string, className?:string, children: React.ReactNode }) {
|
|
77
|
-
return
|
|
77
|
+
return (
|
|
78
|
+
<MessageBox status="error" title={title} className={className}>
|
|
79
|
+
<pre className="whitespace-pre-wrap break-words">
|
|
80
|
+
{children}
|
|
81
|
+
</pre>
|
|
82
|
+
</MessageBox>
|
|
83
|
+
);
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
export function InfoBox({ title, className, children }: { title: string, className?:string, children: React.ReactNode }) {
|
|
@@ -93,4 +99,3 @@ export function DefaultBox({ title, className, children }: { title: string, clas
|
|
|
93
99
|
return <MessageBox status="default" title={title} className={className}>{children}</MessageBox>
|
|
94
100
|
}
|
|
95
101
|
|
|
96
|
-
|
|
@@ -16,6 +16,7 @@ interface ModalProps {
|
|
|
16
16
|
className?: string;
|
|
17
17
|
allowOverflow?: boolean;
|
|
18
18
|
disableCloseOnClickOutside?: boolean;
|
|
19
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
19
20
|
}
|
|
20
21
|
const ModalContext = createContext<boolean>(false)
|
|
21
22
|
export function useIsInModal() {
|
|
@@ -34,12 +35,27 @@ export function VModal({
|
|
|
34
35
|
noCloseButton = false,
|
|
35
36
|
allowOverflow = false,
|
|
36
37
|
disableCloseOnClickOutside = false,
|
|
38
|
+
size = "md",
|
|
37
39
|
}: ModalProps) {
|
|
38
40
|
const handleOpenChange = (open: boolean) => {
|
|
39
41
|
if (!open) {
|
|
40
42
|
onClose();
|
|
41
43
|
}
|
|
42
44
|
};
|
|
45
|
+
function getSizeClasses() {
|
|
46
|
+
switch (size) {
|
|
47
|
+
case "sm":
|
|
48
|
+
return "max-w-[20vw]";
|
|
49
|
+
case "md":
|
|
50
|
+
return "max-w-[40vw]";
|
|
51
|
+
case "lg":
|
|
52
|
+
return "max-w-[60vw]";
|
|
53
|
+
case "xl":
|
|
54
|
+
return "max-w-[80vw]";
|
|
55
|
+
default:
|
|
56
|
+
return "max-w-[40vw]";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
43
59
|
|
|
44
60
|
return (
|
|
45
61
|
<Dialog
|
|
@@ -49,6 +65,7 @@ export function VModal({
|
|
|
49
65
|
handleOpenChange(open);
|
|
50
66
|
}
|
|
51
67
|
}}
|
|
68
|
+
|
|
52
69
|
>
|
|
53
70
|
{allowOverflow && <DialogOverlay className="z-50 fixed inset-0 bg-black/80" />}
|
|
54
71
|
<VisuallyHidden>
|
|
@@ -57,7 +74,8 @@ export function VModal({
|
|
|
57
74
|
<DialogContent
|
|
58
75
|
className={cn(
|
|
59
76
|
"min-h-20 p-4",
|
|
60
|
-
"fixed left-[50%] top-[50%] z-50 grid w-full
|
|
77
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200 sm:rounded-lg",
|
|
78
|
+
getSizeClasses(),
|
|
61
79
|
className
|
|
62
80
|
)}
|
|
63
81
|
>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import { CommandItem
|
|
2
|
+
import { CommandItem } from "../../command";
|
|
3
3
|
import { Button } from "../../button";
|
|
4
4
|
import { Filter, FilterGroup, FilterGroupOption, FilterOption } from "../types";
|
|
5
5
|
import { DynamicLabel } from "../DynamicLabel";
|
|
@@ -52,12 +52,8 @@ export default function SelectFilter({
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
const options = getFilteredOptions(selectedView);
|
|
55
|
-
const selectedGroup = filterGroups.find(g => g.name === selectedView);
|
|
56
|
-
|
|
57
|
-
if (options.length === 0) {
|
|
58
|
-
return <CommandEmpty>No matching options</CommandEmpty>;
|
|
59
|
-
}
|
|
60
55
|
|
|
56
|
+
const selectedGroup = filterGroups.find(g => g.name === selectedView);
|
|
61
57
|
const groupTitle = selectedGroup?.placeholder || selectedGroup?.name;
|
|
62
58
|
|
|
63
59
|
const handleApply = () => {
|
|
@@ -117,35 +113,39 @@ export default function SelectFilter({
|
|
|
117
113
|
};
|
|
118
114
|
|
|
119
115
|
return (
|
|
120
|
-
|
|
121
|
-
<div className="flex items-center p-1.5 text-xs text-muted">
|
|
116
|
+
<div className="flex flex-col h-full">
|
|
117
|
+
<div className="flex items-center p-1.5 text-xs text-muted shrink-0">
|
|
122
118
|
<span>{groupTitle}</span>
|
|
123
119
|
</div>
|
|
124
|
-
<div className="
|
|
125
|
-
|
|
126
|
-
|
|
120
|
+
<div className="flex-1 overflow-hidden min-h-0">
|
|
121
|
+
<div className="max-h-[200px] overflow-y-auto">
|
|
122
|
+
{options.length > 0 && (
|
|
123
|
+
options.map((option: FilterGroupOption) => {
|
|
124
|
+
const isSelected = selectedOptions.some(opt => opt.value === option.value);
|
|
127
125
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
126
|
+
return (
|
|
127
|
+
<CommandItem
|
|
128
|
+
key={option.value || `option-${Math.random()}`}
|
|
129
|
+
className={`group flex gap-2 items-center w-full hover:bg-muted ${selectedGroup?.multiple && isSelected ? 'bg-muted' : ''
|
|
130
|
+
}`}
|
|
131
|
+
onSelect={() => handleOptionToggle(option)}
|
|
132
|
+
>
|
|
133
|
+
<DynamicLabel
|
|
134
|
+
value={option.value || ''}
|
|
135
|
+
labelRenderer={option.labelRenderer || selectedGroup?.labelRenderer}
|
|
136
|
+
fallbackLabel={option.label}
|
|
137
|
+
/>
|
|
138
|
+
{selectedGroup?.multiple && isSelected && (
|
|
139
|
+
<span className="ml-auto text-xs text-success">✓</span>
|
|
140
|
+
)}
|
|
141
|
+
</CommandItem>
|
|
142
|
+
);
|
|
143
|
+
})
|
|
144
|
+
)}
|
|
145
|
+
</div>
|
|
146
146
|
</div>
|
|
147
147
|
{selectedGroup?.multiple && (
|
|
148
|
-
<div className="p-2 border-t">
|
|
148
|
+
<div className="p-2 border-t shrink-0">
|
|
149
149
|
<div className="flex gap-2 justify-end">
|
|
150
150
|
<Button variant="ghost" size="sm" onClick={handleClose}>
|
|
151
151
|
Cancel
|
|
@@ -156,6 +156,6 @@ export default function SelectFilter({
|
|
|
156
156
|
</div>
|
|
157
157
|
</div>
|
|
158
158
|
)}
|
|
159
|
-
|
|
159
|
+
</div>
|
|
160
160
|
);
|
|
161
161
|
}
|
|
@@ -330,6 +330,7 @@ const FilterBtn = ({ className }: { className?: string }) => {
|
|
|
330
330
|
)
|
|
331
331
|
}
|
|
332
332
|
<CommandList>
|
|
333
|
+
<CommandEmpty>No matching filters</CommandEmpty>
|
|
333
334
|
<CommandGroup>
|
|
334
335
|
{!selectedView ? getAvailableFilterGroups() : renderFilterOptions()}
|
|
335
336
|
</CommandGroup>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { isEqual } from 'lodash-es';
|
|
3
|
-
import { Check, ChevronsUpDown, SearchIcon, SquarePlus, X } from 'lucide-react';
|
|
4
|
-
import { useState, useEffect, useRef } from 'react';
|
|
3
|
+
import { AlertTriangle, Check, ChevronsUpDown, SearchIcon, SquarePlus, X } from 'lucide-react';
|
|
4
|
+
import { useState, useEffect, useRef, useMemo } from 'react';
|
|
5
5
|
|
|
6
6
|
import { Popover, PopoverContent, PopoverTrigger, PopoverClose } from './popover';
|
|
7
7
|
import { Command, CommandEmpty, CommandGroup, CommandItem, CommandList } from './command';
|
|
8
8
|
import { Input } from './input';
|
|
9
9
|
import { Button } from '@vertesia/ui/core';
|
|
10
|
+
import { VTooltip } from './tooltip';
|
|
10
11
|
|
|
11
12
|
export interface VSelectBoxBaseProps<T> {
|
|
12
13
|
options: T[] | undefined;
|
|
@@ -25,6 +26,10 @@ export interface VSelectBoxBaseProps<T> {
|
|
|
25
26
|
isClearable?: boolean;
|
|
26
27
|
border?: boolean;
|
|
27
28
|
inline?: boolean;
|
|
29
|
+
/** Show warning when value is not in options list (default: true) */
|
|
30
|
+
warnOnMissingValue?: boolean;
|
|
31
|
+
/** Custom warning message when value is not in options */
|
|
32
|
+
missingValueWarning?: string;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
interface VSelectBoxSingleProps<T> extends VSelectBoxBaseProps<T> {
|
|
@@ -41,12 +46,27 @@ interface VSelectBoxMultipleProps<T> extends VSelectBoxBaseProps<T> {
|
|
|
41
46
|
|
|
42
47
|
type VSelectBoxProps<T> = VSelectBoxSingleProps<T> | VSelectBoxMultipleProps<T>;
|
|
43
48
|
|
|
44
|
-
export function VSelectBox<T = any>({ options, optionLabel, value, onChange, addNew, addNewLabel, disabled, filterBy, label, placeholder, className, popupClass, isClearable, border = true, multiple = false, by, inline = false }: Readonly<VSelectBoxProps<T>>) {
|
|
49
|
+
export function VSelectBox<T = any>({ options, optionLabel, value, onChange, addNew, addNewLabel, disabled, filterBy, label, placeholder, className, popupClass, isClearable, border = true, multiple = false, by, inline = false, warnOnMissingValue = true, missingValueWarning = "Value not in options list, may not be valid" }: Readonly<VSelectBoxProps<T>>) {
|
|
45
50
|
const triggerRef = useRef<HTMLDivElement>(null);
|
|
46
51
|
const [open, setOpen] = useState(false);
|
|
47
52
|
const [width, setWidth] = useState<number>(0);
|
|
48
53
|
const [filterValue, setFilterValue] = useState('');
|
|
49
54
|
|
|
55
|
+
// Check if value is in options list (for single select only)
|
|
56
|
+
const isMissingValue = useMemo(() => {
|
|
57
|
+
if (!warnOnMissingValue || multiple || value == null || !options) return false;
|
|
58
|
+
// Use the isOptionsEqual helper which respects the 'by' comparator
|
|
59
|
+
return !options.some(opt => {
|
|
60
|
+
if (typeof by === 'string') {
|
|
61
|
+
return (opt as any)[by] === (value as any)[by];
|
|
62
|
+
} else if (typeof by === 'function') {
|
|
63
|
+
return by(opt, value as T);
|
|
64
|
+
} else {
|
|
65
|
+
return isEqual(opt, value);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}, [warnOnMissingValue, multiple, value, options, by]);
|
|
69
|
+
|
|
50
70
|
useEffect(() => {
|
|
51
71
|
const element = triggerRef.current;
|
|
52
72
|
if (!element) {
|
|
@@ -185,7 +205,7 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
|
|
|
185
205
|
<Command className="overflow-hidden">
|
|
186
206
|
<CommandList className={inline ? "max-h-full overflow-y-auto" : "max-h-[200px] overflow-y-auto"}>
|
|
187
207
|
<CommandEmpty>No result found.</CommandEmpty>
|
|
188
|
-
<CommandGroup
|
|
208
|
+
<CommandGroup>
|
|
189
209
|
{filteredOptions?.map((opt, index) => {
|
|
190
210
|
const isSelected = multiple
|
|
191
211
|
? isOptionSelected(opt, Array.isArray(value) ? value : [])
|
|
@@ -255,7 +275,7 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
|
|
|
255
275
|
onClick={handleTriggerClick}
|
|
256
276
|
className={clsx(
|
|
257
277
|
className,
|
|
258
|
-
border && 'border border-border',
|
|
278
|
+
border && (isMissingValue ? 'border border-destructive' : 'border border-border'),
|
|
259
279
|
'flex flex-row gap-2 items-center justify-between p-2 rounded-md group relative [&:hover_.clear-button]:opacity-100',
|
|
260
280
|
!disabled ? "cursor-pointer hover:bg-muted" : "cursor-not-allowed text-muted",
|
|
261
281
|
)}
|
|
@@ -268,13 +288,19 @@ export function VSelectBox<T = any>({ options, optionLabel, value, onChange, add
|
|
|
268
288
|
)}
|
|
269
289
|
>
|
|
270
290
|
{label && <div className='w-full text-left text-xs font-semibold'>{label}</div>}
|
|
271
|
-
<div className={clsx('w-full text-left', !disabled && '')}>
|
|
291
|
+
<div className={clsx('w-full text-left min-h-6', !disabled && '', isMissingValue && 'text-destructive')}>
|
|
292
|
+
{isMissingValue && (
|
|
293
|
+
<VTooltip description={missingValueWarning} placement="top" asChild>
|
|
294
|
+
<AlertTriangle className="inline-block size-4 mr-1 -mt-0.5 cursor-help" />
|
|
295
|
+
</VTooltip>
|
|
296
|
+
)}
|
|
272
297
|
{multiple ? renderMultipleValue() : renderSingleValue()}
|
|
273
298
|
</div>
|
|
274
299
|
</div>
|
|
275
300
|
<div className="flex items-center gap-1 group">
|
|
276
301
|
{isClearable && value && (Array.isArray(value) ? value.length > 0 : true) && (
|
|
277
302
|
<Button variant={"link"} size={"icon"}
|
|
303
|
+
disabled={disabled}
|
|
278
304
|
alt="Clear selection"
|
|
279
305
|
onClick={(e) => {
|
|
280
306
|
e.stopPropagation();
|
|
@@ -194,7 +194,7 @@ const VTabsBar = ({ className }: { className?: string }) => {
|
|
|
194
194
|
);
|
|
195
195
|
};
|
|
196
196
|
|
|
197
|
-
const VTabsPanel = () => {
|
|
197
|
+
const VTabsPanel = ({ className }: { className?: string }) => {
|
|
198
198
|
const { tabs } = React.useContext(TabsContext);
|
|
199
199
|
|
|
200
200
|
if (!tabs) return null;
|
|
@@ -202,7 +202,7 @@ const VTabsPanel = () => {
|
|
|
202
202
|
return (
|
|
203
203
|
<>
|
|
204
204
|
{tabs.map((tab) => (
|
|
205
|
-
<TabsContent key={tab.name} value={tab.name}>
|
|
205
|
+
<TabsContent key={tab.name} value={tab.name} className={className}>
|
|
206
206
|
{tab.content}
|
|
207
207
|
</TabsContent>
|
|
208
208
|
))}
|
|
@@ -285,6 +285,7 @@ const TabsContent = React.forwardRef<
|
|
|
285
285
|
ref={ref}
|
|
286
286
|
className={cn(
|
|
287
287
|
"focus-visible:outline-none",
|
|
288
|
+
"flex-1 overflow-y-auto min-h-0 pt-2",
|
|
288
289
|
className
|
|
289
290
|
)}
|
|
290
291
|
{...props}
|
package/src/env/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { AuthTokenPayload } from "@vertesia/common";
|
|
|
6
6
|
export interface EnvProps {
|
|
7
7
|
name: string; // the app name
|
|
8
8
|
version: string,
|
|
9
|
+
sdkVersion?: string, // the @vertesia/ui package version
|
|
9
10
|
isLocalDev: boolean,
|
|
10
11
|
isDocker: boolean,
|
|
11
12
|
type: "production" | "staging" | "preview" | "development" | string,
|
|
@@ -53,6 +54,10 @@ export class VertesiaEnvironment implements Readonly<EnvProps> {
|
|
|
53
54
|
return this.prop("version");
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
get sdkVersion() {
|
|
58
|
+
return this._props?.sdkVersion;
|
|
59
|
+
}
|
|
60
|
+
|
|
56
61
|
get name() {
|
|
57
62
|
return this.prop("name");
|
|
58
63
|
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Chart Creation Instructions for AI Agents
|
|
2
|
+
|
|
3
|
+
This document provides instructions for AI agents on how to create interactive charts that will be rendered in the UI.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
You can create charts by including a special markdown code block with the language `chart`. The UI will automatically detect and render these as interactive Recharts visualizations.
|
|
8
|
+
|
|
9
|
+
## Basic Format
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
\`\`\`chart
|
|
13
|
+
{
|
|
14
|
+
"version": "1.0",
|
|
15
|
+
"library": "recharts",
|
|
16
|
+
"chart": "bar" | "line" | "composed",
|
|
17
|
+
"title": "Chart Title",
|
|
18
|
+
"description": "Optional description",
|
|
19
|
+
"data": [ /* array of data objects */ ],
|
|
20
|
+
"xKey": "fieldName",
|
|
21
|
+
"series": [ /* array of series configurations */ ],
|
|
22
|
+
"yAxis": { /* optional axis labels */ },
|
|
23
|
+
"options": { /* optional chart options */ }
|
|
24
|
+
}
|
|
25
|
+
\`\`\`
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Chart Types
|
|
29
|
+
|
|
30
|
+
### 1. Bar Chart
|
|
31
|
+
Used for comparing values across categories.
|
|
32
|
+
|
|
33
|
+
```chart
|
|
34
|
+
{
|
|
35
|
+
"version": "1.0",
|
|
36
|
+
"chart": "bar",
|
|
37
|
+
"title": "Revenue by Quarter",
|
|
38
|
+
"data": [
|
|
39
|
+
{ "quarter": "Q1", "revenue": 100000 },
|
|
40
|
+
{ "quarter": "Q2", "revenue": 150000 },
|
|
41
|
+
{ "quarter": "Q3", "revenue": 120000 }
|
|
42
|
+
],
|
|
43
|
+
"xKey": "quarter",
|
|
44
|
+
"series": [
|
|
45
|
+
{ "key": "revenue", "label": "Revenue", "type": "bar" }
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Line Chart
|
|
51
|
+
Used for showing trends over time.
|
|
52
|
+
|
|
53
|
+
```chart
|
|
54
|
+
{
|
|
55
|
+
"version": "1.0",
|
|
56
|
+
"chart": "line",
|
|
57
|
+
"title": "Performance Over Time",
|
|
58
|
+
"data": [
|
|
59
|
+
{ "period": "2024-Q1", "tvpi": 1.2, "dpi": 0.3 },
|
|
60
|
+
{ "period": "2024-Q2", "tvpi": 1.5, "dpi": 0.5 },
|
|
61
|
+
{ "period": "2024-Q3", "tvpi": 1.8, "dpi": 0.7 }
|
|
62
|
+
],
|
|
63
|
+
"xKey": "period",
|
|
64
|
+
"series": [
|
|
65
|
+
{ "key": "tvpi", "label": "TVPI", "color": "#4f46e5", "dot": false },
|
|
66
|
+
{ "key": "dpi", "label": "DPI", "color": "#16a34a", "dot": false }
|
|
67
|
+
],
|
|
68
|
+
"yAxis": {
|
|
69
|
+
"left": { "label": "Multiple (x)" }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 3. Composed Chart
|
|
75
|
+
Used for mixing bar and line charts (e.g., bars for cashflows, line for net).
|
|
76
|
+
|
|
77
|
+
```chart
|
|
78
|
+
{
|
|
79
|
+
"version": "1.0",
|
|
80
|
+
"chart": "composed",
|
|
81
|
+
"title": "Cashflow Timeline",
|
|
82
|
+
"data": [
|
|
83
|
+
{ "period": "2024-Q1", "calls": 1000000, "distributions": 500000, "netCashflow": -500000 },
|
|
84
|
+
{ "period": "2024-Q2", "calls": 800000, "distributions": 1200000, "netCashflow": 400000 }
|
|
85
|
+
],
|
|
86
|
+
"xKey": "period",
|
|
87
|
+
"series": [
|
|
88
|
+
{ "key": "calls", "label": "Calls", "type": "bar", "color": "#ef4444" },
|
|
89
|
+
{ "key": "distributions", "label": "Distributions", "type": "bar", "color": "#22c55e" },
|
|
90
|
+
{ "key": "netCashflow", "label": "Net CF", "type": "line", "color": "#0ea5e9", "yAxisId": "right", "dot": false }
|
|
91
|
+
],
|
|
92
|
+
"yAxis": {
|
|
93
|
+
"left": { "label": "Amount" },
|
|
94
|
+
"right": { "label": "Net" }
|
|
95
|
+
},
|
|
96
|
+
"options": {
|
|
97
|
+
"referenceZero": true
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Series Configuration
|
|
103
|
+
|
|
104
|
+
Each series can have:
|
|
105
|
+
|
|
106
|
+
- `key`: (required) The field name in the data
|
|
107
|
+
- `label`: Display name for the legend
|
|
108
|
+
- `type`: "bar" or "line" (for composed charts)
|
|
109
|
+
- `color`: Hex color code (e.g., "#4f46e5")
|
|
110
|
+
- `yAxisId`: "left" (default) or "right" for dual Y-axis
|
|
111
|
+
- `stackId`: Group bars for stacking
|
|
112
|
+
- `dot`: true/false - show dots on line charts
|
|
113
|
+
|
|
114
|
+
## Options
|
|
115
|
+
|
|
116
|
+
- `stacked`: true/false - Stack bars in bar charts
|
|
117
|
+
- `referenceZero`: true/false - Show a reference line at y=0
|
|
118
|
+
- `collapsible`: true/false - Allow users to collapse the chart (default: true)
|
|
119
|
+
- `collapseInitially`: true/false - Start in collapsed state
|
|
120
|
+
|
|
121
|
+
## Number Formatting
|
|
122
|
+
|
|
123
|
+
Numbers are automatically formatted:
|
|
124
|
+
- 1,000 → 1K
|
|
125
|
+
- 1,000,000 → 1M
|
|
126
|
+
- 1,000,000,000 → 1B
|
|
127
|
+
|
|
128
|
+
## Pre-built Chart Builders (TypeScript)
|
|
129
|
+
|
|
130
|
+
If you're writing TypeScript code, you can use these helper functions:
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import {
|
|
134
|
+
buildCashflowComposedChart,
|
|
135
|
+
buildPerformanceLineChart,
|
|
136
|
+
buildScenarioComparisonBarChart,
|
|
137
|
+
toChartMarkdown
|
|
138
|
+
} from '@vertesia/ui/features';
|
|
139
|
+
|
|
140
|
+
// Example: Create a cashflow chart
|
|
141
|
+
const chart = buildCashflowComposedChart({
|
|
142
|
+
title: 'Fund Cashflow',
|
|
143
|
+
rows: [
|
|
144
|
+
{ period: '2024-Q1', calls: 1000000, distributions: 500000 },
|
|
145
|
+
{ period: '2024-Q2', calls: 800000, distributions: 1200000 }
|
|
146
|
+
]
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Convert to markdown
|
|
150
|
+
const markdown = toChartMarkdown(chart);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Available Builders
|
|
154
|
+
|
|
155
|
+
1. `buildCashflowComposedChart` - Calls/Distributions + Net CF
|
|
156
|
+
2. `buildPerformanceLineChart` - TVPI/DPI/RVPI J-curve
|
|
157
|
+
3. `buildScenarioComparisonBarChart` - Side-by-side comparison
|
|
158
|
+
4. `buildScenarioDeltaPercentChart` - % change visualization
|
|
159
|
+
5. `buildTvpiOverlayChart` - TVPI comparison between scenarios
|
|
160
|
+
6. `buildNavLineChart` - NAV over time
|
|
161
|
+
|
|
162
|
+
## Best Practices
|
|
163
|
+
|
|
164
|
+
1. **Use appropriate chart types**:
|
|
165
|
+
- Bar charts for comparisons
|
|
166
|
+
- Line charts for trends
|
|
167
|
+
- Composed charts for mixed metrics
|
|
168
|
+
|
|
169
|
+
2. **Keep data concise**:
|
|
170
|
+
- Limit to 20-30 data points for readability
|
|
171
|
+
- Use aggregation for large datasets
|
|
172
|
+
|
|
173
|
+
3. **Color consistency**:
|
|
174
|
+
- Use the default color palette for consistency
|
|
175
|
+
- Red (#ef4444) for negative/costs
|
|
176
|
+
- Green (#22c55e) for positive/gains
|
|
177
|
+
- Blue (#0ea5e9) for neutral metrics
|
|
178
|
+
|
|
179
|
+
4. **Add context**:
|
|
180
|
+
- Always include a descriptive title
|
|
181
|
+
- Add a description when the chart needs explanation
|
|
182
|
+
- Use axis labels for clarity
|
|
183
|
+
|
|
184
|
+
5. **Dual Y-axis**:
|
|
185
|
+
- Use when comparing metrics with different scales
|
|
186
|
+
- Example: Amount (left) vs Count (right)
|
|
187
|
+
|
|
188
|
+
## Example: Complete Workflow
|
|
189
|
+
|
|
190
|
+
When a user asks "Show me the fund performance":
|
|
191
|
+
|
|
192
|
+
1. Fetch or calculate the data
|
|
193
|
+
2. Format it as a chart spec
|
|
194
|
+
3. Include it in your response:
|
|
195
|
+
|
|
196
|
+
```markdown
|
|
197
|
+
Here's the fund performance over time:
|
|
198
|
+
|
|
199
|
+
\`\`\`chart
|
|
200
|
+
{
|
|
201
|
+
"version": "1.0",
|
|
202
|
+
"chart": "line",
|
|
203
|
+
"title": "Fund Performance",
|
|
204
|
+
"data": [
|
|
205
|
+
{ "period": "2024-Q1", "tvpi": 1.2 },
|
|
206
|
+
{ "period": "2024-Q2", "tvpi": 1.5 }
|
|
207
|
+
],
|
|
208
|
+
"xKey": "period",
|
|
209
|
+
"series": [
|
|
210
|
+
{ "key": "tvpi", "label": "TVPI", "color": "#4f46e5" }
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
\`\`\`
|
|
214
|
+
|
|
215
|
+
The fund shows strong performance with TVPI increasing from 1.2x to 1.5x.
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Common Pitfalls
|
|
219
|
+
|
|
220
|
+
❌ **Don't** include line breaks in the JSON
|
|
221
|
+
❌ **Don't** use single quotes in JSON (use double quotes)
|
|
222
|
+
❌ **Don't** forget to specify the chart type
|
|
223
|
+
❌ **Don't** mix up xKey with data field names
|
|
224
|
+
|
|
225
|
+
✅ **Do** validate your JSON before including it
|
|
226
|
+
✅ **Do** include descriptive labels
|
|
227
|
+
✅ **Do** test with sample data first
|
|
228
|
+
✅ **Do** provide context around the chart
|