@flanksource/clicky-ui 0.3.54 → 0.3.56
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/NOTICE.md +6 -0
- package/dist/ai.cjs +6 -0
- package/dist/ai.js +3 -1
- package/dist/chat.cjs +2 -0
- package/dist/chat.d.ts +1 -0
- package/dist/chat.d.ts.map +1 -1
- package/dist/chat.js +2 -1
- package/dist/comments/CommentCard.cjs +37 -7
- package/dist/comments/CommentCard.cjs.map +1 -1
- package/dist/comments/CommentCard.d.ts +11 -1
- package/dist/comments/CommentCard.d.ts.map +1 -1
- package/dist/comments/CommentCard.js +37 -7
- package/dist/comments/CommentCard.js.map +1 -1
- package/dist/comments/CommentCardParts.cjs +9 -4
- package/dist/comments/CommentCardParts.cjs.map +1 -1
- package/dist/comments/CommentCardParts.d.ts.map +1 -1
- package/dist/comments/CommentCardParts.js +9 -4
- package/dist/comments/CommentCardParts.js.map +1 -1
- package/dist/comments/CommentComposer.cjs +8 -8
- package/dist/comments/CommentComposer.cjs.map +1 -1
- package/dist/comments/CommentComposer.d.ts.map +1 -1
- package/dist/comments/CommentComposer.js +8 -8
- package/dist/comments/CommentComposer.js.map +1 -1
- package/dist/comments/CommentProvider.cjs +5 -1
- package/dist/comments/CommentProvider.cjs.map +1 -1
- package/dist/comments/CommentProvider.d.ts +1 -1
- package/dist/comments/CommentProvider.d.ts.map +1 -1
- package/dist/comments/CommentProvider.js +5 -1
- package/dist/comments/CommentProvider.js.map +1 -1
- package/dist/comments/CommentSidePanel.cjs +17 -11
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.d.ts +6 -0
- package/dist/comments/CommentSidePanel.d.ts.map +1 -1
- package/dist/comments/CommentSidePanel.js +17 -11
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/CommentThread.cjs +4 -1
- package/dist/comments/CommentThread.cjs.map +1 -1
- package/dist/comments/CommentThread.d.ts +4 -1
- package/dist/comments/CommentThread.d.ts.map +1 -1
- package/dist/comments/CommentThread.js +4 -1
- package/dist/comments/CommentThread.js.map +1 -1
- package/dist/comments/CommentThreadList.cjs +6 -3
- package/dist/comments/CommentThreadList.cjs.map +1 -1
- package/dist/comments/CommentThreadList.d.ts +7 -2
- package/dist/comments/CommentThreadList.d.ts.map +1 -1
- package/dist/comments/CommentThreadList.js +6 -3
- package/dist/comments/CommentThreadList.js.map +1 -1
- package/dist/comments/MentionTextarea.cjs +1 -1
- package/dist/comments/MentionTextarea.cjs.map +1 -1
- package/dist/comments/MentionTextarea.d.ts.map +1 -1
- package/dist/comments/MentionTextarea.js +1 -1
- package/dist/comments/MentionTextarea.js.map +1 -1
- package/dist/comments/comment-assign.cjs +68 -0
- package/dist/comments/comment-assign.cjs.map +1 -0
- package/dist/comments/comment-assign.d.ts +31 -0
- package/dist/comments/comment-assign.d.ts.map +1 -0
- package/dist/comments/comment-assign.js +67 -0
- package/dist/comments/comment-assign.js.map +1 -0
- package/dist/comments/comment-types.cjs.map +1 -1
- package/dist/comments/comment-types.d.ts +39 -0
- package/dist/comments/comment-types.d.ts.map +1 -1
- package/dist/comments/comment-types.js.map +1 -1
- package/dist/comments/comment-utils.cjs +2 -0
- package/dist/comments/comment-utils.cjs.map +1 -1
- package/dist/comments/comment-utils.d.ts +2 -0
- package/dist/comments/comment-utils.d.ts.map +1 -1
- package/dist/comments/comment-utils.js +2 -0
- package/dist/comments/comment-utils.js.map +1 -1
- package/dist/comments.cjs +3 -0
- package/dist/comments.d.ts +1 -0
- package/dist/comments.d.ts.map +1 -1
- package/dist/comments.js +2 -1
- package/dist/components/ComboboxMenu.cjs +23 -13
- package/dist/components/ComboboxMenu.cjs.map +1 -1
- package/dist/components/ComboboxMenu.d.ts.map +1 -1
- package/dist/components/ComboboxMenu.js +23 -13
- package/dist/components/ComboboxMenu.js.map +1 -1
- package/dist/components/FilterBar.cjs +29 -6
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +3 -1
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +29 -6
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/ItemActions.cjs +1 -1
- package/dist/components/ItemActions.cjs.map +1 -1
- package/dist/components/ItemActions.js +1 -1
- package/dist/components/ItemActions.js.map +1 -1
- package/dist/components/ListMenu.cjs +33 -3
- package/dist/components/ListMenu.cjs.map +1 -1
- package/dist/components/ListMenu.d.ts +4 -1
- package/dist/components/ListMenu.d.ts.map +1 -1
- package/dist/components/ListMenu.js +33 -3
- package/dist/components/ListMenu.js.map +1 -1
- package/dist/components/ListMenuItems.cjs +80 -0
- package/dist/components/ListMenuItems.cjs.map +1 -0
- package/dist/components/ListMenuItems.d.ts +8 -0
- package/dist/components/ListMenuItems.d.ts.map +1 -0
- package/dist/components/ListMenuItems.js +80 -0
- package/dist/components/ListMenuItems.js.map +1 -0
- package/dist/components/LocalPathPicker.cjs +182 -0
- package/dist/components/LocalPathPicker.cjs.map +1 -0
- package/dist/components/LocalPathPicker.d.ts +11 -0
- package/dist/components/LocalPathPicker.d.ts.map +1 -0
- package/dist/components/LocalPathPicker.js +182 -0
- package/dist/components/LocalPathPicker.js.map +1 -0
- package/dist/components/LocalPathTree.cjs +89 -0
- package/dist/components/LocalPathTree.cjs.map +1 -0
- package/dist/components/LocalPathTree.d.ts +9 -0
- package/dist/components/LocalPathTree.d.ts.map +1 -0
- package/dist/components/LocalPathTree.js +89 -0
- package/dist/components/LocalPathTree.js.map +1 -0
- package/dist/components/RangeSlider.cjs +10 -30
- package/dist/components/RangeSlider.cjs.map +1 -1
- package/dist/components/RangeSlider.d.ts.map +1 -1
- package/dist/components/RangeSlider.js +4 -24
- package/dist/components/RangeSlider.js.map +1 -1
- package/dist/components/Slider.cjs +79 -0
- package/dist/components/Slider.cjs.map +1 -0
- package/dist/components/Slider.d.ts +23 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Slider.js +79 -0
- package/dist/components/Slider.js.map +1 -0
- package/dist/components/combobox-types.d.ts +4 -1
- package/dist/components/combobox-types.d.ts.map +1 -1
- package/dist/components/filter-bar-field-utils.cjs +3 -5
- package/dist/components/filter-bar-field-utils.cjs.map +1 -1
- package/dist/components/filter-bar-field-utils.d.ts.map +1 -1
- package/dist/components/filter-bar-field-utils.js +3 -5
- package/dist/components/filter-bar-field-utils.js.map +1 -1
- package/dist/components/filter-bar-tree-model.cjs +22 -0
- package/dist/components/filter-bar-tree-model.cjs.map +1 -0
- package/dist/components/filter-bar-tree-model.d.ts +33 -0
- package/dist/components/filter-bar-tree-model.d.ts.map +1 -0
- package/dist/components/filter-bar-tree-model.js +21 -0
- package/dist/components/filter-bar-tree-model.js.map +1 -0
- package/dist/components/filter-bar-tree.cjs +84 -0
- package/dist/components/filter-bar-tree.cjs.map +1 -0
- package/dist/components/filter-bar-tree.d.ts +7 -0
- package/dist/components/filter-bar-tree.d.ts.map +1 -0
- package/dist/components/filter-bar-tree.js +84 -0
- package/dist/components/filter-bar-tree.js.map +1 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs +2 -0
- package/dist/components/json-schema-form-debug-glyph-map.cjs.map +1 -1
- package/dist/components/json-schema-form-debug-glyph-map.d.ts.map +1 -1
- package/dist/components/json-schema-form-debug-glyph-map.js +2 -0
- package/dist/components/json-schema-form-debug-glyph-map.js.map +1 -1
- package/dist/components/json-schema-form-help-links.cjs +18 -0
- package/dist/components/json-schema-form-help-links.cjs.map +1 -0
- package/dist/components/json-schema-form-help-links.d.ts +5 -0
- package/dist/components/json-schema-form-help-links.d.ts.map +1 -0
- package/dist/components/json-schema-form-help-links.js +18 -0
- package/dist/components/json-schema-form-help-links.js.map +1 -0
- package/dist/components/json-schema-form-help-model.cjs +7 -0
- package/dist/components/json-schema-form-help-model.cjs.map +1 -0
- package/dist/components/json-schema-form-help-model.d.ts +3 -0
- package/dist/components/json-schema-form-help-model.d.ts.map +1 -0
- package/dist/components/json-schema-form-help-model.js +7 -0
- package/dist/components/json-schema-form-help-model.js.map +1 -0
- package/dist/components/json-schema-form-json.cjs +48 -0
- package/dist/components/json-schema-form-json.cjs.map +1 -0
- package/dist/components/json-schema-form-json.d.ts +7 -0
- package/dist/components/json-schema-form-json.d.ts.map +1 -0
- package/dist/components/json-schema-form-json.js +48 -0
- package/dist/components/json-schema-form-json.js.map +1 -0
- package/dist/components/json-schema-form-layout.cjs +7 -5
- package/dist/components/json-schema-form-layout.cjs.map +1 -1
- package/dist/components/json-schema-form-layout.d.ts +2 -2
- package/dist/components/json-schema-form-layout.d.ts.map +1 -1
- package/dist/components/json-schema-form-layout.js +7 -5
- package/dist/components/json-schema-form-layout.js.map +1 -1
- package/dist/components/json-schema-form-object.cjs +2 -13
- package/dist/components/json-schema-form-object.cjs.map +1 -1
- package/dist/components/json-schema-form-object.d.ts.map +1 -1
- package/dist/components/json-schema-form-object.js +2 -13
- package/dist/components/json-schema-form-object.js.map +1 -1
- package/dist/components/json-schema-form-refs.cjs +1 -1
- package/dist/components/json-schema-form-refs.cjs.map +1 -1
- package/dist/components/json-schema-form-refs.d.ts.map +1 -1
- package/dist/components/json-schema-form-refs.js +1 -1
- package/dist/components/json-schema-form-refs.js.map +1 -1
- package/dist/components/json-schema-form-render.cjs +20 -6
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +20 -6
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +22 -2
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +22 -2
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +5 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-union-model.cjs +46 -0
- package/dist/components/json-schema-form-union-model.cjs.map +1 -0
- package/dist/components/json-schema-form-union-model.d.ts +6 -0
- package/dist/components/json-schema-form-union-model.d.ts.map +1 -0
- package/dist/components/json-schema-form-union-model.js +43 -0
- package/dist/components/json-schema-form-union-model.js.map +1 -0
- package/dist/components/json-schema-form-union.cjs +52 -0
- package/dist/components/json-schema-form-union.cjs.map +1 -0
- package/dist/components/json-schema-form-union.d.ts +7 -0
- package/dist/components/json-schema-form-union.d.ts.map +1 -0
- package/dist/components/json-schema-form-union.js +52 -0
- package/dist/components/json-schema-form-union.js.map +1 -0
- package/dist/components/list-menu-virtual.cjs +5 -0
- package/dist/components/list-menu-virtual.cjs.map +1 -0
- package/dist/components/list-menu-virtual.d.ts +12 -0
- package/dist/components/list-menu-virtual.d.ts.map +1 -0
- package/dist/components/list-menu-virtual.js +6 -0
- package/dist/components/list-menu-virtual.js.map +1 -0
- package/dist/components/local-path.cjs +12 -0
- package/dist/components/local-path.cjs.map +1 -0
- package/dist/components/local-path.d.ts +14 -0
- package/dist/components/local-path.d.ts.map +1 -0
- package/dist/components/local-path.js +12 -0
- package/dist/components/local-path.js.map +1 -0
- package/dist/components/slider-shared.cjs +32 -0
- package/dist/components/slider-shared.cjs.map +1 -0
- package/dist/components/slider-shared.d.ts +18 -0
- package/dist/components/slider-shared.d.ts.map +1 -0
- package/dist/components/slider-shared.js +27 -0
- package/dist/components/slider-shared.js.map +1 -0
- package/dist/components.cjs +8 -0
- package/dist/components.d.ts +6 -1
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +5 -1
- package/dist/connections/ConnectionsPage.cjs +51 -19
- package/dist/connections/ConnectionsPage.cjs.map +1 -1
- package/dist/connections/ConnectionsPage.d.ts +9 -1
- package/dist/connections/ConnectionsPage.d.ts.map +1 -1
- package/dist/connections/ConnectionsPage.js +52 -20
- package/dist/connections/ConnectionsPage.js.map +1 -1
- package/dist/connections/connectionDashboard.cjs +13 -8
- package/dist/connections/connectionDashboard.cjs.map +1 -1
- package/dist/connections/connectionDashboard.d.ts +8 -3
- package/dist/connections/connectionDashboard.d.ts.map +1 -1
- package/dist/connections/connectionDashboard.js +14 -9
- package/dist/connections/connectionDashboard.js.map +1 -1
- package/dist/connections/connectionDashboardModel.cjs.map +1 -1
- package/dist/connections/connectionDashboardModel.d.ts +4 -0
- package/dist/connections/connectionDashboardModel.d.ts.map +1 -1
- package/dist/connections/connectionDashboardModel.js.map +1 -1
- package/dist/connections/connectionDashboardRow.cjs +75 -55
- package/dist/connections/connectionDashboardRow.cjs.map +1 -1
- package/dist/connections/connectionDashboardRow.d.ts +3 -2
- package/dist/connections/connectionDashboardRow.d.ts.map +1 -1
- package/dist/connections/connectionDashboardRow.js +75 -55
- package/dist/connections/connectionDashboardRow.js.map +1 -1
- package/dist/connections/connectionNamespaceField.cjs +17 -0
- package/dist/connections/connectionNamespaceField.cjs.map +1 -0
- package/dist/connections/connectionNamespaceField.d.ts +10 -0
- package/dist/connections/connectionNamespaceField.d.ts.map +1 -0
- package/dist/connections/connectionNamespaceField.js +17 -0
- package/dist/connections/connectionNamespaceField.js.map +1 -0
- package/dist/connections/connectionSchemaFormExtensions.cjs +98 -0
- package/dist/connections/connectionSchemaFormExtensions.cjs.map +1 -0
- package/dist/connections/connectionSchemaFormExtensions.d.ts +41 -0
- package/dist/connections/connectionSchemaFormExtensions.d.ts.map +1 -0
- package/dist/connections/connectionSchemaFormExtensions.js +96 -0
- package/dist/connections/connectionSchemaFormExtensions.js.map +1 -0
- package/dist/connections/connectionsPageModel.cjs +11 -0
- package/dist/connections/connectionsPageModel.cjs.map +1 -1
- package/dist/connections/connectionsPageModel.d.ts +5 -0
- package/dist/connections/connectionsPageModel.d.ts.map +1 -1
- package/dist/connections/connectionsPageModel.js +11 -1
- package/dist/connections/connectionsPageModel.js.map +1 -1
- package/dist/connections.cjs +5 -0
- package/dist/connections.d.ts +2 -1
- package/dist/connections.d.ts.map +1 -1
- package/dist/connections.js +3 -2
- package/dist/data/AvatarBadge.cjs +3 -3
- package/dist/data/AvatarBadge.cjs.map +1 -1
- package/dist/data/AvatarBadge.js +3 -3
- package/dist/data/AvatarBadge.js.map +1 -1
- package/dist/data/CodeDiff.cjs +2 -0
- package/dist/data/CodeDiff.cjs.map +1 -1
- package/dist/data/CodeDiff.js +2 -0
- package/dist/data/CodeDiff.js.map +1 -1
- package/dist/data/DataTable.cjs +3 -2
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +3 -2
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Gauge.cjs +1 -1
- package/dist/data/Gauge.cjs.map +1 -1
- package/dist/data/Gauge.js +1 -1
- package/dist/data/Gauge.js.map +1 -1
- package/dist/data/HighlightedTokens.cjs +2 -10
- package/dist/data/HighlightedTokens.cjs.map +1 -1
- package/dist/data/HighlightedTokens.d.ts.map +1 -1
- package/dist/data/HighlightedTokens.js +1 -9
- package/dist/data/HighlightedTokens.js.map +1 -1
- package/dist/data/Markdown.cjs +38 -11
- package/dist/data/Markdown.cjs.map +1 -1
- package/dist/data/Markdown.d.ts +9 -1
- package/dist/data/Markdown.d.ts.map +1 -1
- package/dist/data/Markdown.js +39 -12
- package/dist/data/Markdown.js.map +1 -1
- package/dist/data/MultiGaugeBar.cjs +157 -0
- package/dist/data/MultiGaugeBar.cjs.map +1 -0
- package/dist/data/MultiGaugeBar.d.ts +29 -0
- package/dist/data/MultiGaugeBar.d.ts.map +1 -0
- package/dist/data/MultiGaugeBar.js +157 -0
- package/dist/data/MultiGaugeBar.js.map +1 -0
- package/dist/data/OpenInFilesLink.cjs +27 -0
- package/dist/data/OpenInFilesLink.cjs.map +1 -0
- package/dist/data/OpenInFilesLink.d.ts +15 -0
- package/dist/data/OpenInFilesLink.d.ts.map +1 -0
- package/dist/data/OpenInFilesLink.js +27 -0
- package/dist/data/OpenInFilesLink.js.map +1 -0
- package/dist/data/ProgressBar.cjs +5 -3
- package/dist/data/ProgressBar.cjs.map +1 -1
- package/dist/data/ProgressBar.d.ts +5 -1
- package/dist/data/ProgressBar.d.ts.map +1 -1
- package/dist/data/ProgressBar.js +5 -3
- package/dist/data/ProgressBar.js.map +1 -1
- package/dist/data/ProgressBars.cjs +13 -5
- package/dist/data/ProgressBars.cjs.map +1 -1
- package/dist/data/ProgressBars.d.ts +6 -1
- package/dist/data/ProgressBars.d.ts.map +1 -1
- package/dist/data/ProgressBars.js +13 -5
- package/dist/data/ProgressBars.js.map +1 -1
- package/dist/data/Properties.cjs +3 -3
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.js +3 -3
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/TaskProgress.cjs +14 -6
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.d.ts +3 -1
- package/dist/data/TaskProgress.d.ts.map +1 -1
- package/dist/data/TaskProgress.js +14 -6
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/TaskPrompts.cjs +96 -0
- package/dist/data/TaskPrompts.cjs.map +1 -0
- package/dist/data/TaskPrompts.d.ts +6 -0
- package/dist/data/TaskPrompts.d.ts.map +1 -0
- package/dist/data/TaskPrompts.js +96 -0
- package/dist/data/TaskPrompts.js.map +1 -0
- package/dist/data/TaskSnapshot.cjs.map +1 -1
- package/dist/data/TaskSnapshot.d.ts +3 -0
- package/dist/data/TaskSnapshot.d.ts.map +1 -1
- package/dist/data/TaskSnapshot.js.map +1 -1
- package/dist/data/TimeseriesCoreBars.cjs +7 -3
- package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.js +8 -4
- package/dist/data/TimeseriesCoreBars.js.map +1 -1
- package/dist/data/TimeseriesGauge.cjs +12 -5
- package/dist/data/TimeseriesGauge.cjs.map +1 -1
- package/dist/data/TimeseriesGauge.d.ts.map +1 -1
- package/dist/data/TimeseriesGauge.js +13 -6
- package/dist/data/TimeseriesGauge.js.map +1 -1
- package/dist/data/TimeseriesPanel.cjs +10 -9
- package/dist/data/TimeseriesPanel.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.d.ts +1 -1
- package/dist/data/TimeseriesPanel.d.ts.map +1 -1
- package/dist/data/TimeseriesPanel.js +11 -10
- package/dist/data/TimeseriesPanel.js.map +1 -1
- package/dist/data/TimeseriesPanel.model.cjs +62 -10
- package/dist/data/TimeseriesPanel.model.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.model.d.ts +40 -1
- package/dist/data/TimeseriesPanel.model.d.ts.map +1 -1
- package/dist/data/TimeseriesPanel.model.js +62 -11
- package/dist/data/TimeseriesPanel.model.js.map +1 -1
- package/dist/data/WorkloadCard.cjs +7 -3
- package/dist/data/WorkloadCard.cjs.map +1 -1
- package/dist/data/WorkloadCard.d.ts +3 -1
- package/dist/data/WorkloadCard.d.ts.map +1 -1
- package/dist/data/WorkloadCard.js +7 -3
- package/dist/data/WorkloadCard.js.map +1 -1
- package/dist/data/WorkloadCard.model.cjs.map +1 -1
- package/dist/data/WorkloadCard.model.d.ts +2 -0
- package/dist/data/WorkloadCard.model.d.ts.map +1 -1
- package/dist/data/WorkloadCard.model.js.map +1 -1
- package/dist/data/ai/ChatWindow.placement.cjs +2 -1
- package/dist/data/ai/ChatWindow.placement.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.placement.d.ts +1 -1
- package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.placement.js +2 -1
- package/dist/data/ai/ChatWindow.placement.js.map +1 -1
- package/dist/data/ai/SpecRuntimeBar.cjs +2 -2
- package/dist/data/ai/SpecRuntimeBar.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeBar.d.ts +4 -1
- package/dist/data/ai/SpecRuntimeBar.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeBar.js +2 -2
- package/dist/data/ai/SpecRuntimeBar.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js +1 -1
- package/dist/data/ai/SpecRuntimeEditor/PromptSection.js.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.cjs +2 -2
- package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts +2 -2
- package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
- package/dist/data/ai/SpecRuntimeEditor.model.js +2 -2
- package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
- package/dist/data/ai/ThreadPicker.cjs +2 -2
- package/dist/data/ai/ThreadPicker.cjs.map +1 -1
- package/dist/data/ai/ThreadPicker.js +2 -2
- package/dist/data/ai/ThreadPicker.js.map +1 -1
- package/dist/data/ai/index.d.ts +2 -0
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/use-prompt-run-stream.cjs +126 -0
- package/dist/data/ai/use-prompt-run-stream.cjs.map +1 -0
- package/dist/data/ai/use-prompt-run-stream.d.ts +52 -0
- package/dist/data/ai/use-prompt-run-stream.d.ts.map +1 -0
- package/dist/data/ai/use-prompt-run-stream.js +126 -0
- package/dist/data/ai/use-prompt-run-stream.js.map +1 -0
- package/dist/data/cache-browser/CacheBrowser.cjs +1 -0
- package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -1
- package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -1
- package/dist/data/cache-browser/CacheBrowser.js +1 -0
- package/dist/data/cache-browser/CacheBrowser.js.map +1 -1
- package/dist/data/charts/BarChart.cjs +194 -0
- package/dist/data/charts/BarChart.cjs.map +1 -0
- package/dist/data/charts/BarChart.d.ts +19 -0
- package/dist/data/charts/BarChart.d.ts.map +1 -0
- package/dist/data/charts/BarChart.js +194 -0
- package/dist/data/charts/BarChart.js.map +1 -0
- package/dist/data/charts/ChartLegend.cjs +54 -0
- package/dist/data/charts/ChartLegend.cjs.map +1 -0
- package/dist/data/charts/ChartLegend.d.ts +17 -0
- package/dist/data/charts/ChartLegend.d.ts.map +1 -0
- package/dist/data/charts/ChartLegend.js +54 -0
- package/dist/data/charts/ChartLegend.js.map +1 -0
- package/dist/data/charts/Sparkline.cjs +56 -0
- package/dist/data/charts/Sparkline.cjs.map +1 -0
- package/dist/data/charts/Sparkline.d.ts +15 -0
- package/dist/data/charts/Sparkline.d.ts.map +1 -0
- package/dist/data/charts/Sparkline.js +56 -0
- package/dist/data/charts/Sparkline.js.map +1 -0
- package/dist/data/charts/StackedBarChart.cjs +241 -0
- package/dist/data/charts/StackedBarChart.cjs.map +1 -0
- package/dist/data/charts/StackedBarChart.d.ts +20 -0
- package/dist/data/charts/StackedBarChart.d.ts.map +1 -0
- package/dist/data/charts/StackedBarChart.js +241 -0
- package/dist/data/charts/StackedBarChart.js.map +1 -0
- package/dist/data/charts/TrendChart.cjs +157 -0
- package/dist/data/charts/TrendChart.cjs.map +1 -0
- package/dist/data/charts/TrendChart.d.ts +20 -0
- package/dist/data/charts/TrendChart.d.ts.map +1 -0
- package/dist/data/charts/TrendChart.js +157 -0
- package/dist/data/charts/TrendChart.js.map +1 -0
- package/dist/data/charts/chart-marks.cjs +115 -0
- package/dist/data/charts/chart-marks.cjs.map +1 -0
- package/dist/data/charts/chart-marks.d.ts +39 -0
- package/dist/data/charts/chart-marks.d.ts.map +1 -0
- package/dist/data/charts/chart-marks.js +112 -0
- package/dist/data/charts/chart-marks.js.map +1 -0
- package/dist/data/charts/chart-palette.cjs +74 -0
- package/dist/data/charts/chart-palette.cjs.map +1 -0
- package/dist/data/charts/chart-palette.d.ts +58 -0
- package/dist/data/charts/chart-palette.d.ts.map +1 -0
- package/dist/data/charts/chart-palette.js +72 -0
- package/dist/data/charts/chart-palette.js.map +1 -0
- package/dist/data/charts/chart-scale.cjs +115 -0
- package/dist/data/charts/chart-scale.cjs.map +1 -0
- package/dist/data/charts/chart-scale.d.ts +41 -0
- package/dist/data/charts/chart-scale.d.ts.map +1 -0
- package/dist/data/charts/chart-scale.js +104 -0
- package/dist/data/charts/chart-scale.js.map +1 -0
- package/dist/data/charts/chart.test-utils.d.ts +7 -0
- package/dist/data/charts/chart.test-utils.d.ts.map +1 -0
- package/dist/data/charts/index.d.ts +7 -0
- package/dist/data/charts/index.d.ts.map +1 -0
- package/dist/data/chat/MessageActions.cjs +1 -1
- package/dist/data/chat/MessageActions.cjs.map +1 -1
- package/dist/data/chat/MessageActions.js +1 -1
- package/dist/data/chat/MessageActions.js.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.cjs +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.js +1 -1
- package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +9 -2
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +9 -2
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/ProblemActions.cjs +37 -0
- package/dist/data/diagnostics/ProblemActions.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemActions.d.ts +6 -0
- package/dist/data/diagnostics/ProblemActions.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemActions.js +37 -0
- package/dist/data/diagnostics/ProblemActions.js.map +1 -0
- package/dist/data/diagnostics/ProblemFacet.cjs +33 -0
- package/dist/data/diagnostics/ProblemFacet.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemFacet.d.ts +9 -0
- package/dist/data/diagnostics/ProblemFacet.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemFacet.js +33 -0
- package/dist/data/diagnostics/ProblemFacet.js.map +1 -0
- package/dist/data/diagnostics/ProblemRow.cjs +62 -0
- package/dist/data/diagnostics/ProblemRow.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemRow.d.ts +14 -0
- package/dist/data/diagnostics/ProblemRow.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemRow.js +62 -0
- package/dist/data/diagnostics/ProblemRow.js.map +1 -0
- package/dist/data/diagnostics/ProblemViewOptions.cjs +18 -0
- package/dist/data/diagnostics/ProblemViewOptions.cjs.map +1 -0
- package/dist/data/diagnostics/ProblemViewOptions.d.ts +6 -0
- package/dist/data/diagnostics/ProblemViewOptions.d.ts.map +1 -0
- package/dist/data/diagnostics/ProblemViewOptions.js +18 -0
- package/dist/data/diagnostics/ProblemViewOptions.js.map +1 -0
- package/dist/data/diagnostics/StackFrameRow.cjs +1 -1
- package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -1
- package/dist/data/diagnostics/StackFrameRow.js +1 -1
- package/dist/data/diagnostics/StackFrameRow.js.map +1 -1
- package/dist/data/diagnostics/diagnostic-identity.cjs +14 -0
- package/dist/data/diagnostics/diagnostic-identity.cjs.map +1 -0
- package/dist/data/diagnostics/diagnostic-identity.d.ts +3 -0
- package/dist/data/diagnostics/diagnostic-identity.d.ts.map +1 -0
- package/dist/data/diagnostics/diagnostic-identity.js +14 -0
- package/dist/data/diagnostics/diagnostic-identity.js.map +1 -0
- package/dist/data/diagnostics/use-problem-expansion.cjs +16 -0
- package/dist/data/diagnostics/use-problem-expansion.cjs.map +1 -0
- package/dist/data/diagnostics/use-problem-expansion.d.ts +3 -0
- package/dist/data/diagnostics/use-problem-expansion.d.ts.map +1 -0
- package/dist/data/diagnostics/use-problem-expansion.js +16 -0
- package/dist/data/diagnostics/use-problem-expansion.js.map +1 -0
- package/dist/data/git/GitChangeList.cjs +9 -6
- package/dist/data/git/GitChangeList.cjs.map +1 -1
- package/dist/data/git/GitChangeList.d.ts +6 -0
- package/dist/data/git/GitChangeList.d.ts.map +1 -1
- package/dist/data/git/GitChangeList.js +9 -6
- package/dist/data/git/GitChangeList.js.map +1 -1
- package/dist/data/git/pickers/GitPickersDemo.d.ts.map +1 -1
- package/dist/data/git/pickers/ReferencePicker.cjs +1 -0
- package/dist/data/git/pickers/ReferencePicker.cjs.map +1 -1
- package/dist/data/git/pickers/ReferencePicker.js +1 -0
- package/dist/data/git/pickers/ReferencePicker.js.map +1 -1
- package/dist/data/lint/LintDetail.cjs +230 -189
- package/dist/data/lint/LintDetail.cjs.map +1 -1
- package/dist/data/lint/LintDetail.d.ts +25 -3
- package/dist/data/lint/LintDetail.d.ts.map +1 -1
- package/dist/data/lint/LintDetail.js +231 -192
- package/dist/data/lint/LintDetail.js.map +1 -1
- package/dist/data/lint/LintFilterBar.cjs +78 -83
- package/dist/data/lint/LintFilterBar.cjs.map +1 -1
- package/dist/data/lint/LintFilterBar.d.ts +23 -6
- package/dist/data/lint/LintFilterBar.d.ts.map +1 -1
- package/dist/data/lint/LintFilterBar.js +78 -85
- package/dist/data/lint/LintFilterBar.js.map +1 -1
- package/dist/data/lint/LintIgnoreMenu.cjs +59 -0
- package/dist/data/lint/LintIgnoreMenu.cjs.map +1 -0
- package/dist/data/lint/LintIgnoreMenu.d.ts +20 -0
- package/dist/data/lint/LintIgnoreMenu.d.ts.map +1 -0
- package/dist/data/lint/LintIgnoreMenu.js +58 -0
- package/dist/data/lint/LintIgnoreMenu.js.map +1 -0
- package/dist/data/lint/LintResults.cjs +59 -14
- package/dist/data/lint/LintResults.cjs.map +1 -1
- package/dist/data/lint/LintResults.d.ts +25 -1
- package/dist/data/lint/LintResults.d.ts.map +1 -1
- package/dist/data/lint/LintResults.fixtures.d.ts +19 -0
- package/dist/data/lint/LintResults.fixtures.d.ts.map +1 -1
- package/dist/data/lint/LintResults.js +60 -15
- package/dist/data/lint/LintResults.js.map +1 -1
- package/dist/data/lint/LintTable.cjs +156 -0
- package/dist/data/lint/LintTable.cjs.map +1 -0
- package/dist/data/lint/LintTable.d.ts +13 -0
- package/dist/data/lint/LintTable.d.ts.map +1 -0
- package/dist/data/lint/LintTable.js +156 -0
- package/dist/data/lint/LintTable.js.map +1 -0
- package/dist/data/lint/LintTreeNode.cjs +42 -19
- package/dist/data/lint/LintTreeNode.cjs.map +1 -1
- package/dist/data/lint/LintTreeNode.d.ts +7 -2
- package/dist/data/lint/LintTreeNode.d.ts.map +1 -1
- package/dist/data/lint/LintTreeNode.js +44 -21
- package/dist/data/lint/LintTreeNode.js.map +1 -1
- package/dist/data/lint/ViolationSnippet.cjs +113 -0
- package/dist/data/lint/ViolationSnippet.cjs.map +1 -0
- package/dist/data/lint/ViolationSnippet.d.ts +20 -0
- package/dist/data/lint/ViolationSnippet.d.ts.map +1 -0
- package/dist/data/lint/ViolationSnippet.js +112 -0
- package/dist/data/lint/ViolationSnippet.js.map +1 -0
- package/dist/data/lint/actions.cjs +44 -16
- package/dist/data/lint/actions.cjs.map +1 -1
- package/dist/data/lint/actions.d.ts +7 -3
- package/dist/data/lint/actions.d.ts.map +1 -1
- package/dist/data/lint/actions.js +44 -16
- package/dist/data/lint/actions.js.map +1 -1
- package/dist/data/lint/grouping.cjs +105 -8
- package/dist/data/lint/grouping.cjs.map +1 -1
- package/dist/data/lint/grouping.d.ts +21 -1
- package/dist/data/lint/grouping.d.ts.map +1 -1
- package/dist/data/lint/grouping.js +105 -10
- package/dist/data/lint/grouping.js.map +1 -1
- package/dist/data/lint/ignore-menu-items.cjs +18 -0
- package/dist/data/lint/ignore-menu-items.cjs.map +1 -0
- package/dist/data/lint/ignore-menu-items.d.ts +6 -0
- package/dist/data/lint/ignore-menu-items.d.ts.map +1 -0
- package/dist/data/lint/ignore-menu-items.js +17 -0
- package/dist/data/lint/ignore-menu-items.js.map +1 -0
- package/dist/data/lint/index.d.ts +7 -5
- package/dist/data/lint/index.d.ts.map +1 -1
- package/dist/data/lint/stats.cjs +19 -4
- package/dist/data/lint/stats.cjs.map +1 -1
- package/dist/data/lint/stats.d.ts +13 -3
- package/dist/data/lint/stats.d.ts.map +1 -1
- package/dist/data/lint/stats.js +17 -5
- package/dist/data/lint/stats.js.map +1 -1
- package/dist/data/lint/types.cjs +8 -0
- package/dist/data/lint/types.cjs.map +1 -1
- package/dist/data/lint/types.d.ts +47 -0
- package/dist/data/lint/types.d.ts.map +1 -1
- package/dist/data/lint/types.js +8 -1
- package/dist/data/lint/types.js.map +1 -1
- package/dist/data/lint/violation-menu-items.cjs +31 -0
- package/dist/data/lint/violation-menu-items.cjs.map +1 -0
- package/dist/data/lint/violation-menu-items.d.ts +12 -0
- package/dist/data/lint/violation-menu-items.d.ts.map +1 -0
- package/dist/data/lint/violation-menu-items.js +31 -0
- package/dist/data/lint/violation-menu-items.js.map +1 -0
- package/dist/data/markdown-source-blocks.cjs +38 -0
- package/dist/data/markdown-source-blocks.cjs.map +1 -0
- package/dist/data/markdown-source-blocks.d.ts +32 -0
- package/dist/data/markdown-source-blocks.d.ts.map +1 -0
- package/dist/data/markdown-source-blocks.js +35 -0
- package/dist/data/markdown-source-blocks.js.map +1 -0
- package/dist/data/test-runner/FilterFacet.cjs +52 -0
- package/dist/data/test-runner/FilterFacet.cjs.map +1 -0
- package/dist/data/test-runner/FilterFacet.d.ts +13 -0
- package/dist/data/test-runner/FilterFacet.d.ts.map +1 -0
- package/dist/data/test-runner/FilterFacet.js +52 -0
- package/dist/data/test-runner/FilterFacet.js.map +1 -0
- package/dist/data/test-runner/MatrixMarks.cjs +42 -40
- package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
- package/dist/data/test-runner/MatrixMarks.d.ts +20 -4
- package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
- package/dist/data/test-runner/MatrixMarks.js +43 -42
- package/dist/data/test-runner/MatrixMarks.js.map +1 -1
- package/dist/data/test-runner/TestAttemptDetail.cjs +1 -1
- package/dist/data/test-runner/TestAttemptDetail.js +1 -1
- package/dist/data/test-runner/TestDetailPanel.cjs +11 -0
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +11 -0
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFilterBar.cjs +3 -44
- package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
- package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
- package/dist/data/test-runner/TestFilterBar.js +3 -44
- package/dist/data/test-runner/TestFilterBar.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +3 -1
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +7 -1
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +3 -1
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +3 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/index.d.ts +2 -2
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/matrix-marks.cjs +2 -11
- package/dist/data/test-runner/matrix-marks.cjs.map +1 -1
- package/dist/data/test-runner/matrix-marks.d.ts +2 -4
- package/dist/data/test-runner/matrix-marks.d.ts.map +1 -1
- package/dist/data/test-runner/matrix-marks.js +3 -11
- package/dist/data/test-runner/matrix-marks.js.map +1 -1
- package/dist/data/test-runner/types.d.ts +2 -0
- package/dist/data/test-runner/types.d.ts.map +1 -1
- package/dist/data/timeseries-query.cjs +98 -2
- package/dist/data/timeseries-query.cjs.map +1 -1
- package/dist/data/timeseries-query.d.ts +31 -5
- package/dist/data/timeseries-query.d.ts.map +1 -1
- package/dist/data/timeseries-query.js +98 -3
- package/dist/data/timeseries-query.js.map +1 -1
- package/dist/data/timeseries-stream-provider.cjs +38 -0
- package/dist/data/timeseries-stream-provider.cjs.map +1 -0
- package/dist/data/timeseries-stream-provider.d.ts +26 -0
- package/dist/data/timeseries-stream-provider.d.ts.map +1 -0
- package/dist/data/timeseries-stream-provider.js +38 -0
- package/dist/data/timeseries-stream-provider.js.map +1 -0
- package/dist/data/timeseries-stream.cjs +304 -0
- package/dist/data/timeseries-stream.cjs.map +1 -0
- package/dist/data/timeseries-stream.d.ts +81 -0
- package/dist/data/timeseries-stream.d.ts.map +1 -0
- package/dist/data/timeseries-stream.fixtures.d.ts +36 -0
- package/dist/data/timeseries-stream.fixtures.d.ts.map +1 -0
- package/dist/data/timeseries-stream.js +296 -0
- package/dist/data/timeseries-stream.js.map +1 -0
- package/dist/data/token-style.cjs +13 -0
- package/dist/data/token-style.cjs.map +1 -0
- package/dist/data/token-style.d.ts +4 -0
- package/dist/data/token-style.d.ts.map +1 -0
- package/dist/data/token-style.js +13 -0
- package/dist/data/token-style.js.map +1 -0
- package/dist/data/traces/ProcessTraceDetail.cjs +1 -1
- package/dist/data/traces/ProcessTraceDetail.js +1 -1
- package/dist/data/traces/index.d.ts +1 -1
- package/dist/data/traces/index.d.ts.map +1 -1
- package/dist/data/use-data-table-virtual.d.ts +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data/workload-panel/MemoryStack.cjs +49 -0
- package/dist/data/workload-panel/MemoryStack.cjs.map +1 -0
- package/dist/data/workload-panel/MemoryStack.d.ts +11 -0
- package/dist/data/workload-panel/MemoryStack.d.ts.map +1 -0
- package/dist/data/workload-panel/MemoryStack.js +48 -0
- package/dist/data/workload-panel/MemoryStack.js.map +1 -0
- package/dist/data/workload-panel/Metrics.cjs +197 -0
- package/dist/data/workload-panel/Metrics.cjs.map +1 -0
- package/dist/data/workload-panel/Metrics.d.ts +11 -0
- package/dist/data/workload-panel/Metrics.d.ts.map +1 -0
- package/dist/data/workload-panel/Metrics.js +196 -0
- package/dist/data/workload-panel/Metrics.js.map +1 -0
- package/dist/data/workload-panel/WorkloadPanel.cjs +66 -0
- package/dist/data/workload-panel/WorkloadPanel.cjs.map +1 -0
- package/dist/data/workload-panel/WorkloadPanel.d.ts +3 -0
- package/dist/data/workload-panel/WorkloadPanel.d.ts.map +1 -0
- package/dist/data/workload-panel/WorkloadPanel.js +66 -0
- package/dist/data/workload-panel/WorkloadPanel.js.map +1 -0
- package/dist/data/workload-panel/fixtures.d.ts +60 -0
- package/dist/data/workload-panel/fixtures.d.ts.map +1 -0
- package/dist/data/workload-panel/model.cjs +137 -0
- package/dist/data/workload-panel/model.cjs.map +1 -0
- package/dist/data/workload-panel/model.d.ts +53 -0
- package/dist/data/workload-panel/model.d.ts.map +1 -0
- package/dist/data/workload-panel/model.js +133 -0
- package/dist/data/workload-panel/model.js.map +1 -0
- package/dist/data/workload-panel/types.d.ts +56 -0
- package/dist/data/workload-panel/types.d.ts.map +1 -0
- package/dist/data.cjs +58 -7
- package/dist/data.d.ts +9 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +29 -12
- package/dist/file-findings/AnnotatedCode.cjs +243 -0
- package/dist/file-findings/AnnotatedCode.cjs.map +1 -0
- package/dist/file-findings/AnnotatedCode.d.ts +30 -0
- package/dist/file-findings/AnnotatedCode.d.ts.map +1 -0
- package/dist/file-findings/AnnotatedCode.js +243 -0
- package/dist/file-findings/AnnotatedCode.js.map +1 -0
- package/dist/file-findings/FileFindingsView.cjs +213 -0
- package/dist/file-findings/FileFindingsView.cjs.map +1 -0
- package/dist/file-findings/FileFindingsView.d.ts +35 -0
- package/dist/file-findings/FileFindingsView.d.ts.map +1 -0
- package/dist/file-findings/FileFindingsView.js +213 -0
- package/dist/file-findings/FileFindingsView.js.map +1 -0
- package/dist/file-findings/LazyAnnotatedCode.cjs +22 -0
- package/dist/file-findings/LazyAnnotatedCode.cjs.map +1 -0
- package/dist/file-findings/LazyAnnotatedCode.d.ts +5 -0
- package/dist/file-findings/LazyAnnotatedCode.d.ts.map +1 -0
- package/dist/file-findings/LazyAnnotatedCode.js +22 -0
- package/dist/file-findings/LazyAnnotatedCode.js.map +1 -0
- package/dist/file-findings/adapters.cjs +155 -0
- package/dist/file-findings/adapters.cjs.map +1 -0
- package/dist/file-findings/adapters.d.ts +24 -0
- package/dist/file-findings/adapters.d.ts.map +1 -0
- package/dist/file-findings/adapters.js +153 -0
- package/dist/file-findings/adapters.js.map +1 -0
- package/dist/file-findings/file-review/CommentDraft.cjs +97 -0
- package/dist/file-findings/file-review/CommentDraft.cjs.map +1 -0
- package/dist/file-findings/file-review/CommentDraft.d.ts +25 -0
- package/dist/file-findings/file-review/CommentDraft.d.ts.map +1 -0
- package/dist/file-findings/file-review/CommentDraft.js +97 -0
- package/dist/file-findings/file-review/CommentDraft.js.map +1 -0
- package/dist/file-findings/file-review/FileReview.cjs +863 -0
- package/dist/file-findings/file-review/FileReview.cjs.map +1 -0
- package/dist/file-findings/file-review/FileReview.d.ts +79 -0
- package/dist/file-findings/file-review/FileReview.d.ts.map +1 -0
- package/dist/file-findings/file-review/FileReview.fixtures.d.ts +25 -0
- package/dist/file-findings/file-review/FileReview.fixtures.d.ts.map +1 -0
- package/dist/file-findings/file-review/FileReview.js +863 -0
- package/dist/file-findings/file-review/FileReview.js.map +1 -0
- package/dist/file-findings/file-review/InlineAuthors.cjs +77 -0
- package/dist/file-findings/file-review/InlineAuthors.cjs.map +1 -0
- package/dist/file-findings/file-review/InlineAuthors.d.ts +9 -0
- package/dist/file-findings/file-review/InlineAuthors.d.ts.map +1 -0
- package/dist/file-findings/file-review/InlineAuthors.js +77 -0
- package/dist/file-findings/file-review/InlineAuthors.js.map +1 -0
- package/dist/file-findings/file-review/InlineThread.cjs +77 -0
- package/dist/file-findings/file-review/InlineThread.cjs.map +1 -0
- package/dist/file-findings/file-review/InlineThread.d.ts +27 -0
- package/dist/file-findings/file-review/InlineThread.d.ts.map +1 -0
- package/dist/file-findings/file-review/InlineThread.js +77 -0
- package/dist/file-findings/file-review/InlineThread.js.map +1 -0
- package/dist/file-findings/file-review/ProblemsList.cjs +164 -0
- package/dist/file-findings/file-review/ProblemsList.cjs.map +1 -0
- package/dist/file-findings/file-review/ProblemsList.d.ts +15 -0
- package/dist/file-findings/file-review/ProblemsList.d.ts.map +1 -0
- package/dist/file-findings/file-review/ProblemsList.js +164 -0
- package/dist/file-findings/file-review/ProblemsList.js.map +1 -0
- package/dist/file-findings/file-review/SourceView.cjs +179 -0
- package/dist/file-findings/file-review/SourceView.cjs.map +1 -0
- package/dist/file-findings/file-review/SourceView.d.ts +29 -0
- package/dist/file-findings/file-review/SourceView.d.ts.map +1 -0
- package/dist/file-findings/file-review/SourceView.js +179 -0
- package/dist/file-findings/file-review/SourceView.js.map +1 -0
- package/dist/file-findings/file-review/blame.cjs +35 -0
- package/dist/file-findings/file-review/blame.cjs.map +1 -0
- package/dist/file-findings/file-review/blame.d.ts +28 -0
- package/dist/file-findings/file-review/blame.d.ts.map +1 -0
- package/dist/file-findings/file-review/blame.js +33 -0
- package/dist/file-findings/file-review/blame.js.map +1 -0
- package/dist/file-findings/file-review/geometry.cjs +101 -0
- package/dist/file-findings/file-review/geometry.cjs.map +1 -0
- package/dist/file-findings/file-review/geometry.d.ts +45 -0
- package/dist/file-findings/file-review/geometry.d.ts.map +1 -0
- package/dist/file-findings/file-review/geometry.js +98 -0
- package/dist/file-findings/file-review/geometry.js.map +1 -0
- package/dist/file-findings/file-review/hooks.cjs +101 -0
- package/dist/file-findings/file-review/hooks.cjs.map +1 -0
- package/dist/file-findings/file-review/hooks.d.ts +22 -0
- package/dist/file-findings/file-review/hooks.d.ts.map +1 -0
- package/dist/file-findings/file-review/hooks.js +99 -0
- package/dist/file-findings/file-review/hooks.js.map +1 -0
- package/dist/file-findings/file-review/marks.cjs +52 -0
- package/dist/file-findings/file-review/marks.cjs.map +1 -0
- package/dist/file-findings/file-review/marks.d.ts +23 -0
- package/dist/file-findings/file-review/marks.d.ts.map +1 -0
- package/dist/file-findings/file-review/marks.js +47 -0
- package/dist/file-findings/file-review/marks.js.map +1 -0
- package/dist/file-findings/file-review/problem-filters.cjs +14 -0
- package/dist/file-findings/file-review/problem-filters.cjs.map +1 -0
- package/dist/file-findings/file-review/problem-filters.d.ts +10 -0
- package/dist/file-findings/file-review/problem-filters.d.ts.map +1 -0
- package/dist/file-findings/file-review/problem-filters.js +13 -0
- package/dist/file-findings/file-review/problem-filters.js.map +1 -0
- package/dist/file-findings/file-review/quote-anchor.cjs +234 -0
- package/dist/file-findings/file-review/quote-anchor.cjs.map +1 -0
- package/dist/file-findings/file-review/quote-anchor.d.ts +54 -0
- package/dist/file-findings/file-review/quote-anchor.d.ts.map +1 -0
- package/dist/file-findings/file-review/quote-anchor.js +226 -0
- package/dist/file-findings/file-review/quote-anchor.js.map +1 -0
- package/dist/file-findings/file-review/source-anchor.cjs +104 -0
- package/dist/file-findings/file-review/source-anchor.cjs.map +1 -0
- package/dist/file-findings/file-review/source-anchor.d.ts +27 -0
- package/dist/file-findings/file-review/source-anchor.d.ts.map +1 -0
- package/dist/file-findings/file-review/source-anchor.js +99 -0
- package/dist/file-findings/file-review/source-anchor.js.map +1 -0
- package/dist/file-findings/file-review/source-marks.cjs +71 -0
- package/dist/file-findings/file-review/source-marks.cjs.map +1 -0
- package/dist/file-findings/file-review/source-marks.d.ts +27 -0
- package/dist/file-findings/file-review/source-marks.d.ts.map +1 -0
- package/dist/file-findings/file-review/source-marks.js +68 -0
- package/dist/file-findings/file-review/source-marks.js.map +1 -0
- package/dist/file-findings/findings-comments.cjs +136 -0
- package/dist/file-findings/findings-comments.cjs.map +1 -0
- package/dist/file-findings/findings-comments.d.ts +28 -0
- package/dist/file-findings/findings-comments.d.ts.map +1 -0
- package/dist/file-findings/findings-comments.js +131 -0
- package/dist/file-findings/findings-comments.js.map +1 -0
- package/dist/file-findings/findings-languages.cjs +53 -0
- package/dist/file-findings/findings-languages.cjs.map +1 -0
- package/dist/file-findings/findings-languages.d.ts +11 -0
- package/dist/file-findings/findings-languages.d.ts.map +1 -0
- package/dist/file-findings/findings-languages.js +53 -0
- package/dist/file-findings/findings-languages.js.map +1 -0
- package/dist/file-findings/mdx-source.cjs +48 -0
- package/dist/file-findings/mdx-source.cjs.map +1 -0
- package/dist/file-findings/mdx-source.d.ts +7 -0
- package/dist/file-findings/mdx-source.d.ts.map +1 -0
- package/dist/file-findings/mdx-source.js +48 -0
- package/dist/file-findings/mdx-source.js.map +1 -0
- package/dist/file-findings/monaco-language.cjs +73 -0
- package/dist/file-findings/monaco-language.cjs.map +1 -0
- package/dist/file-findings/monaco-language.d.ts +11 -0
- package/dist/file-findings/monaco-language.d.ts.map +1 -0
- package/dist/file-findings/monaco-language.js +72 -0
- package/dist/file-findings/monaco-language.js.map +1 -0
- package/dist/file-findings/severity-counts.cjs +20 -0
- package/dist/file-findings/severity-counts.cjs.map +1 -0
- package/dist/file-findings/severity-counts.d.ts +5 -0
- package/dist/file-findings/severity-counts.d.ts.map +1 -0
- package/dist/file-findings/severity-counts.js +19 -0
- package/dist/file-findings/severity-counts.js.map +1 -0
- package/dist/file-findings/types.cjs +12 -0
- package/dist/file-findings/types.cjs.map +1 -0
- package/dist/file-findings/types.d.ts +43 -0
- package/dist/file-findings/types.d.ts.map +1 -0
- package/dist/file-findings/types.js +11 -0
- package/dist/file-findings/types.js.map +1 -0
- package/dist/file-findings.cjs +47 -0
- package/dist/file-findings.d.ts +15 -0
- package/dist/file-findings.d.ts.map +1 -0
- package/dist/file-findings.js +15 -0
- package/dist/hooks/event-hub.cjs +22 -8
- package/dist/hooks/event-hub.cjs.map +1 -1
- package/dist/hooks/event-hub.d.ts.map +1 -1
- package/dist/hooks/event-hub.js +22 -8
- package/dist/hooks/event-hub.js.map +1 -1
- package/dist/icons/components/UiBrowser.cjs +51 -0
- package/dist/icons/components/UiBrowser.cjs.map +1 -0
- package/dist/icons/components/UiBrowser.d.ts +15 -0
- package/dist/icons/components/UiBrowser.d.ts.map +1 -0
- package/dist/icons/components/UiBrowser.js +48 -0
- package/dist/icons/components/UiBrowser.js.map +1 -0
- package/dist/icons/components/UiCreditCard.cjs +51 -0
- package/dist/icons/components/UiCreditCard.cjs.map +1 -0
- package/dist/icons/components/UiCreditCard.d.ts +15 -0
- package/dist/icons/components/UiCreditCard.d.ts.map +1 -0
- package/dist/icons/components/UiCreditCard.js +48 -0
- package/dist/icons/components/UiCreditCard.js.map +1 -0
- package/dist/icons/components/UiShoppingCart.cjs +51 -0
- package/dist/icons/components/UiShoppingCart.cjs.map +1 -0
- package/dist/icons/components/UiShoppingCart.d.ts +15 -0
- package/dist/icons/components/UiShoppingCart.d.ts.map +1 -0
- package/dist/icons/components/UiShoppingCart.js +48 -0
- package/dist/icons/components/UiShoppingCart.js.map +1 -0
- package/dist/icons/index.d.ts +6 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +6 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +6 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +9 -0
- package/dist/icons.js +4 -1
- package/dist/index.cjs +76 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -14
- package/dist/layout/AppShell.cjs +37 -21
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts +13 -2
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.js +37 -21
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/layout/AppShell.nav.cjs +7 -6
- package/dist/layout/AppShell.nav.cjs.map +1 -1
- package/dist/layout/AppShell.nav.d.ts.map +1 -1
- package/dist/layout/AppShell.nav.js +7 -6
- package/dist/layout/AppShell.nav.js.map +1 -1
- package/dist/layout/SplitPane.cjs +16 -6
- package/dist/layout/SplitPane.cjs.map +1 -1
- package/dist/layout/SplitPane.d.ts +12 -2
- package/dist/layout/SplitPane.d.ts.map +1 -1
- package/dist/layout/SplitPane.js +16 -6
- package/dist/layout/SplitPane.js.map +1 -1
- package/dist/layout/Workspace.cjs +37 -33
- package/dist/layout/Workspace.cjs.map +1 -1
- package/dist/layout/Workspace.d.ts.map +1 -1
- package/dist/layout/Workspace.js +37 -33
- package/dist/layout/Workspace.js.map +1 -1
- package/dist/layout/Workspace.regions.cjs +3 -3
- package/dist/layout/Workspace.regions.cjs.map +1 -1
- package/dist/layout/Workspace.regions.js +3 -3
- package/dist/layout/Workspace.regions.js.map +1 -1
- package/dist/lib/breakpoints.cjs +102 -0
- package/dist/lib/breakpoints.cjs.map +1 -0
- package/dist/lib/breakpoints.d.ts +36 -0
- package/dist/lib/breakpoints.d.ts.map +1 -0
- package/dist/lib/breakpoints.js +99 -0
- package/dist/lib/breakpoints.js.map +1 -0
- package/dist/lib/combobox.cjs +2 -1
- package/dist/lib/combobox.cjs.map +1 -1
- package/dist/lib/combobox.d.ts +1 -1
- package/dist/lib/combobox.d.ts.map +1 -1
- package/dist/lib/combobox.js +2 -1
- package/dist/lib/combobox.js.map +1 -1
- package/dist/lib/path-tree.cjs +21 -0
- package/dist/lib/path-tree.cjs.map +1 -1
- package/dist/lib/path-tree.d.ts +15 -0
- package/dist/lib/path-tree.d.ts.map +1 -1
- package/dist/lib/path-tree.js +21 -1
- package/dist/lib/path-tree.js.map +1 -1
- package/dist/overlay/Modal.cjs +2 -1
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +2 -1
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/overlay/dropdownMenuContext.d.ts +1 -1
- package/dist/profiles/editor/profileEditor.cjs +1 -1
- package/dist/profiles/editor/profileEditor.cjs.map +1 -1
- package/dist/profiles/editor/profileEditor.js +1 -1
- package/dist/profiles/editor/profileEditor.js.map +1 -1
- package/dist/profiles/editor/profileEditorSections.cjs +2 -2
- package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
- package/dist/profiles/editor/profileEditorSections.js +2 -2
- package/dist/profiles/editor/profileEditorSections.js.map +1 -1
- package/dist/profiles/query/prometheusResults.cjs +24 -36
- package/dist/profiles/query/prometheusResults.cjs.map +1 -1
- package/dist/profiles/query/prometheusResults.d.ts.map +1 -1
- package/dist/profiles/query/prometheusResults.js +24 -36
- package/dist/profiles/query/prometheusResults.js.map +1 -1
- package/dist/rpc/CommandForm.cjs +1 -1
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.js +1 -1
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/rpc/classify.cjs +1 -1
- package/dist/rpc/classify.cjs.map +1 -1
- package/dist/rpc/classify.d.ts.map +1 -1
- package/dist/rpc/classify.js +1 -1
- package/dist/rpc/classify.js.map +1 -1
- package/dist/rpc/useOperations.d.ts +24 -24
- package/dist/rpc.cjs +0 -2
- package/dist/rpc.d.ts +0 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +1 -2
- package/dist/styles.css +1 -1
- package/dist/utils.cjs +6 -0
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -2
- package/package.json +9 -3
- package/schemas/json-schema-form.schema.json +9 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesGauge.cjs","names":["cn","Icon","defaultTimeseriesFetcher","useState","useTimeseriesQueries","latestValue","formatUnit","useMemo","seriesStats","GaugeHoverCard","UiFullscreen","_Fragment","Modal","TimeseriesPanel"],"sources":["../../src/data/TimeseriesGauge.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { formatUnit } from \"../lib/format\";\nimport { Modal } from \"../overlay/Modal\";\nimport { UiFullscreen } from \"../icons\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport {\n TimeseriesPanel,\n type SeriesLoader,\n type TimeseriesResponse,\n type TimeseriesSeries,\n} from \"./TimeseriesPanel\";\nimport { defaultTimeseriesFetcher, latestValue, useTimeseriesQueries } from \"./timeseries-query\";\nimport { GaugeHoverCard, type GaugeHoverRow } from \"./GaugeHoverCard\";\nimport { seriesStats } from \"./gauge-stats\";\n\n/**\n * A metric series whose latest value drives the gauge fill or its maximum. It\n * is requested as `baseUrl + id` through the widget's `fetcher`, or, when\n * `load` is set, loaded by calling `load` directly.\n */\nexport interface GaugeSeries {\n /**\n * Metric id appended to the gauge's baseUrl, e.g. \"k8s.statefulset.cycle.cpu.usage\".\n * With `load`, the id is the cache identity: loaded series are cached under\n * `[\"timeseries\", \"load\", id, range]`, so keep it unique per data source.\n */\n id: string;\n /** Maps the latest value before display (e.g. unit scaling). Identity when omitted. */\n transform?: (value: number) => number;\n /** Loads the series' points; when set, `baseUrl` and `fetcher` are not used. */\n load?: SeriesLoader;\n}\n\nexport type TimeseriesGaugeVariant = \"default\" | \"cell\";\n/** Gauge fill geometry: a half-circle arc (default) or a horizontal progress bar. */\nexport type TimeseriesGaugeShape = \"radial\" | \"linear\";\n\nexport interface TimeseriesGaugeProps {\n /** Common prefix; the value/max requests are `baseUrl + id` (unless a series has `load`). */\n baseUrl?: string;\n /** The metric whose latest value fills the gauge. */\n value: GaugeSeries;\n /**\n * The gauge maximum. Either a metric series (its latest value, e.g. a `.limit`\n * metric) or a fixed number. When omitted, or when the resolved max is 0, the\n * gauge shows the raw value with no fill (an unbounded reading).\n */\n max?: GaugeSeries | number;\n title: string;\n /** Iconify name or static icon component shown beside the label. */\n icon?: string | StaticIconComponent;\n /** Grafana-style unit key for the readout (e.g. \"bytes\", \"percent\", \"short\", \"ms\"). */\n unit?: string;\n /** Look-back window for the expand chart, passed as ?since=; defaults to \"1h\". */\n range?: string;\n /** Poll interval in ms; defaults to 5000. Pass 0 to disable polling. */\n refreshMs?: number;\n /** Show an expand button that opens the value/max time-series chart in a modal. Default true. */\n expandable?: boolean;\n /**\n * Utilisation thresholds (percent of max) at which the arc turns amber then\n * red. Defaults to [75, 90].\n */\n thresholds?: [warning: number, danger: number];\n /**\n * What to print in the centre: the formatted value (default) or the\n * utilisation percentage of max (e.g. CPU usage out of its millicore limit).\n */\n centerDisplay?: \"value\" | \"percent\";\n /** Visual density/layout. `cell` is a compact inline form for table/grid cells. */\n variant?: TimeseriesGaugeVariant;\n /** Fill geometry: a radial half-gauge (default) or a horizontal progress bar. */\n shape?: TimeseriesGaugeShape;\n /** Show the title text. Icons and values remain visible when false. */\n showLabel?: boolean;\n /**\n * Wrap the gauge in a hover card summarising the metric (label + current / min /\n * max / avg / capacity over the window). Defaults to true.\n */\n hoverCard?: boolean;\n /** Override the default fetch (e.g. to route through an app's API client). */\n fetcher?: (url: string) => Promise<TimeseriesResponse>;\n className?: string;\n}\n\n// Half-gauge SVG geometry: a 100×50 viewBox semicircle (radius 40, centre 50,50)\n// swept 180°. The arc length is π·r; stroke-dashoffset reveals value/max of it.\nconst GAUGE_RADIUS = 40;\nconst GAUGE_ARC = Math.PI * GAUGE_RADIUS;\nconst GAUGE_PATH = `M 10 50 A ${GAUGE_RADIUS} ${GAUGE_RADIUS} 0 0 1 90 50`;\n\nfunction toneClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"text-red-500\";\n if (pct >= warn) return \"text-amber-500\";\n return \"text-emerald-500\";\n}\n\n// toneBgClass mirrors toneClass for the linear bar's fill, which needs a\n// background colour rather than the arc's stroke (currentColor) tone.\nfunction toneBgClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"bg-red-500\";\n if (pct >= warn) return \"bg-amber-500\";\n return \"bg-emerald-500\";\n}\n\n// GaugeArc is the half-circle SVG shared by the cell and default radial gauges;\n// only the stroke width differs between the two densities.\nfunction GaugeArc({ pct, tone, strokeWidth }: { pct: number; tone: string; strokeWidth: number }) {\n return (\n <svg viewBox=\"0 0 100 50\" className=\"h-full w-full overflow-visible\">\n <path d={GAUGE_PATH} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" className=\"text-muted\" />\n <path\n d={GAUGE_PATH}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={tone}\n strokeDasharray={GAUGE_ARC}\n strokeDashoffset={GAUGE_ARC * (1 - pct / 100)}\n />\n </svg>\n );\n}\n\n// GaugeBar is the horizontal progress track shared by the cell and default linear\n// gauges; the caller sizes it via className (e.g. \"h-1.5 w-12\" or \"h-2 w-full\").\nfunction GaugeBar({ pct, toneBg, className }: { pct: number; toneBg: string; className?: string }) {\n return (\n <span className={cn(\"relative block overflow-hidden rounded-full bg-muted\", className)} aria-hidden=\"true\">\n <span\n className={cn(\"absolute inset-y-0 left-0 rounded-full transition-all duration-300\", toneBg)}\n style={{ width: `${pct}%` }}\n />\n </span>\n );\n}\n\nfunction GaugeIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n }\n return <Icon icon={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n}\n\n/**\n * TimeseriesGauge renders a half (180°) radial gauge whose fill is the latest\n * value of a metric over its maximum (a `.limit`-style metric or a fixed number),\n * both read live from the timeseries store. The centre shows the utilisation\n * percentage, with the value/max caption below; the arc colour crosses warning\n * and danger thresholds. An expand button opens the full value/max time-series\n * chart in a modal (a `TimeseriesPanel`), so the gauge gives the at-a-glance\n * reading and the chart the trend.\n */\nexport function TimeseriesGauge({\n baseUrl = \"\",\n value,\n max,\n title,\n icon,\n unit,\n range = \"1h\",\n refreshMs = 5000,\n expandable = true,\n thresholds = [75, 90],\n centerDisplay = \"value\",\n variant = \"default\",\n shape = \"radial\",\n showLabel = true,\n hoverCard = true,\n fetcher = defaultTimeseriesFetcher,\n className,\n}: TimeseriesGaugeProps) {\n const [expanded, setExpanded] = useState(false);\n\n const maxIsSeries = typeof max === \"object\";\n const maxSeries = maxIsSeries ? max : undefined;\n const results = useTimeseriesQueries(maxSeries ? [value, maxSeries] : [value], {\n baseUrl,\n range,\n refreshMs,\n fetcher,\n });\n\n const rawValue = latestValue(results[0]?.data);\n const hasValue = rawValue !== undefined;\n const usage = value.transform ? value.transform(rawValue ?? 0) : (rawValue ?? 0);\n\n let limit: number | undefined;\n if (typeof max === \"number\") {\n limit = max;\n } else if (maxSeries) {\n const rawMax = latestValue(results[1]?.data);\n limit = rawMax === undefined ? undefined : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;\n }\n\n const bounded = hasValue && limit !== undefined && limit > 0;\n const pct = bounded ? Math.min(100, Math.round((usage / (limit as number)) * 100)) : 0;\n const tone = toneClass(pct, thresholds);\n const toneBg = toneBgClass(pct, thresholds);\n const readout =\n centerDisplay === \"percent\"\n ? bounded\n ? `${pct}%`\n : hasValue\n ? \"n/a\"\n : \"—\"\n : hasValue\n ? formatUnit(usage, unit)\n : \"—\";\n const titleText = `${title}: ${readout}`;\n const canExpand = expandable && variant === \"default\";\n const readoutTone = bounded ? tone : \"text-foreground\";\n\n const chartSeries: TimeseriesSeries[] = useMemo(() => {\n const s: TimeseriesSeries[] = [{ ...value, label: \"value\" }];\n if (maxSeries) s.push({ ...maxSeries, label: \"max\" });\n return s;\n }, [value, maxSeries]);\n\n // Hover card: reduce the value's points to current/min/max/avg (transformed to\n // the display unit), plus the resolved capacity. The current row is tinted by\n // its threshold tone when the reading is bounded.\n const stats = seriesStats(results[0]?.data?.points, value.transform);\n const fmt = (n: number) => formatUnit(n, unit);\n const hoverRows: GaugeHoverRow[] = hasValue\n ? [\n { label: \"Current\", value: fmt(usage), ...(bounded ? { tone } : {}) },\n ...(stats\n ? [\n { label: \"Min\", value: fmt(stats.min) },\n { label: \"Max\", value: fmt(stats.max) },\n { label: \"Avg\", value: fmt(stats.avg) },\n ]\n : []),\n ...(limit !== undefined\n ? [{ label: \"Capacity\", value: fmt(limit) }]\n : []),\n ]\n : [];\n const useHover = hoverCard && hoverRows.length > 0;\n const footer = `over last ${range}`;\n\n if (variant === \"cell\") {\n const cell = (\n <span\n className={cn(\n \"inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap align-middle text-xs\",\n className,\n )}\n {...(useHover ? {} : { title: titleText })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span className=\"min-w-0 truncate text-muted-foreground\">{title}</span> : null}\n {shape === \"linear\" ? (\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-1.5 w-12 shrink-0\" />\n ) : (\n <span className=\"relative h-4 w-8 shrink-0\" aria-hidden=\"true\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={10} />\n </span>\n )}\n <span className={cn(\"shrink-0 font-semibold tabular-nums\", readoutTone)}>\n {readout}\n </span>\n </span>\n );\n return useHover ? (\n <GaugeHoverCard title={title} rows={hoverRows} footer={footer} trigger={cell} />\n ) : (\n cell\n );\n }\n\n const body = (\n <div\n className={cn(\"flex flex-col items-center gap-1\", className)}\n {...(useHover ? {} : { title: !showLabel ? titleText : undefined })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {shape === \"linear\" ? (\n <div className=\"flex w-full items-center gap-2\">\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-2 w-full\" />\n <span className=\"shrink-0 text-sm font-semibold text-foreground\">{readout}</span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"shrink-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n ) : (\n <div className=\"relative h-10 w-20\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={9} />\n <span className=\"absolute inset-x-0 bottom-0 text-center text-sm font-semibold text-foreground\">\n {readout}\n </span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"absolute right-0 top-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n )}\n {icon || showLabel ? (\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span>{title}</span> : null}\n </div>\n ) : null}\n </div>\n );\n\n return (\n <>\n {useHover ? (\n <GaugeHoverCard\n title={title}\n rows={hoverRows}\n footer={footer}\n trigger={body}\n className=\"w-full justify-center\"\n />\n ) : (\n body\n )}\n {canExpand && (\n <Modal open={expanded} onClose={() => setExpanded(false)} title={title} size=\"xl\">\n <TimeseriesPanel\n title={title}\n {...(icon ? { icon } : {})}\n {...(unit ? { unit } : {})}\n baseUrl={baseUrl}\n series={chartSeries}\n range={range}\n refreshMs={refreshMs}\n expandable={false}\n fetcher={fetcher}\n />\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAwFA,IAAM,eAAe;AACrB,IAAM,YAAY,KAAK,KAAK;AAC5B,IAAM,aAAa,aAAa,aAAa,GAAG,aAAa;AAE7D,SAAS,UAAU,KAAa,CAAC,MAAM,SAAmC;CACxE,IAAI,OAAO,QAAQ,OAAO;CAC1B,IAAI,OAAO,MAAM,OAAO;CACxB,OAAO;AACT;AAIA,SAAS,YAAY,KAAa,CAAC,MAAM,SAAmC;CAC1E,IAAI,OAAO,QAAQ,OAAO;CAC1B,IAAI,OAAO,MAAM,OAAO;CACxB,OAAO;AACT;AAIA,SAAS,SAAS,EAAE,KAAK,MAAM,eAAmE;CAChG,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,SAAQ;EAAa,WAAU;EAApC,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GAAM,GAAG;GAAY,MAAK;GAAO,QAAO;GAA4B;GAAa,eAAc;GAAQ,WAAU;EAAc,CAAA,GAC/H,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GACE,GAAG;GACH,MAAK;GACL,QAAO;GACM;GACb,eAAc;GACd,WAAW;GACX,iBAAiB;GACjB,kBAAkB,aAAa,IAAI,MAAM;EAC1C,CAAA,CACE;;AAET;AAIA,SAAS,SAAS,EAAE,KAAK,QAAQ,aAAkE;CACjG,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EAAM,WAAWA,cAAAA,GAAG,wDAAwD,SAAS;EAAG,eAAY;EAClG,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;GACE,WAAWA,cAAAA,GAAG,sEAAsE,MAAM;GAC1F,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG;EAC3B,CAAA;CACG,CAAA;AAEV;AAEA,SAAS,UAAU,EAAE,QAAgD;CACnE,IAAI,OAAO,SAAS,UAClB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,MAAD;EAAM,MAAM;EAAM,OAAO;EAAI,QAAQ;EAAI,WAAU;CAAyB,CAAA;CAErF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACA,aAAAA,MAAD;EAAY;EAAM,OAAO;EAAI,QAAQ;EAAI,WAAU;CAAyB,CAAA;AACrF;;;;;;;;;;AAWA,SAAgB,gBAAgB,EAC9B,UAAU,IACV,OACA,KACA,OACA,MACA,MACA,QAAQ,MACR,YAAY,KACZ,aAAa,MACb,aAAa,CAAC,IAAI,EAAE,GACpB,gBAAgB,SAChB,UAAU,WACV,QAAQ,UACR,YAAY,MACZ,YAAY,MACZ,UAAUC,yBAAAA,0BACV,aACuB;CACvB,MAAM,CAAC,UAAU,gBAAA,GAAeC,MAAAA,SAAAA,CAAS,KAAK;CAG9C,MAAM,YADc,OAAO,QAAQ,WACH,MAAM,KAAA;CACtC,MAAM,UAAUC,yBAAAA,qBAAqB,YAAY,CAAC,OAAO,SAAS,IAAI,CAAC,KAAK,GAAG;EAC7E;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,WAAWC,yBAAAA,YAAY,QAAQ,EAAE,EAAE,IAAI;CAC7C,MAAM,WAAW,aAAa,KAAA;CAC9B,MAAM,QAAQ,MAAM,YAAY,MAAM,UAAU,YAAY,CAAC,IAAK,YAAY;CAE9E,IAAI;CACJ,IAAI,OAAO,QAAQ,UACjB,QAAQ;MACH,IAAI,WAAW;EACpB,MAAM,SAASA,yBAAAA,YAAY,QAAQ,EAAE,EAAE,IAAI;EAC3C,QAAQ,WAAW,KAAA,IAAY,KAAA,IAAY,UAAU,YAAY,UAAU,UAAU,MAAM,IAAI;CACjG;CAEA,MAAM,UAAU,YAAY,UAAU,KAAA,KAAa,QAAQ;CAC3D,MAAM,MAAM,UAAU,KAAK,IAAI,KAAK,KAAK,MAAO,QAAS,QAAoB,GAAG,CAAC,IAAI;CACrF,MAAM,OAAO,UAAU,KAAK,UAAU;CACtC,MAAM,SAAS,YAAY,KAAK,UAAU;CAC1C,MAAM,UACJ,kBAAkB,YACd,UACE,GAAG,IAAI,KACP,WACE,QACA,MACJ,WACEC,eAAAA,WAAW,OAAO,IAAI,IACtB;CACR,MAAM,YAAY,GAAG,MAAM,IAAI;CAC/B,MAAM,YAAY,cAAc,YAAY;CAC5C,MAAM,cAAc,UAAU,OAAO;CAErC,MAAM,eAAA,GAAkCC,MAAAA,QAAAA,OAAc;EACpD,MAAM,IAAwB,CAAC;GAAE,GAAG;GAAO,OAAO;EAAQ,CAAC;EAC3D,IAAI,WAAW,EAAE,KAAK;GAAE,GAAG;GAAW,OAAO;EAAM,CAAC;EACpD,OAAO;CACT,GAAG,CAAC,OAAO,SAAS,CAAC;CAKrB,MAAM,QAAQC,oBAAAA,YAAY,QAAQ,EAAE,EAAE,MAAM,QAAQ,MAAM,SAAS;CACnE,MAAM,OAAO,MAAcF,eAAAA,WAAW,GAAG,IAAI;CAC7C,MAAM,YAA6B,WAC/B;EACE;GAAE,OAAO;GAAW,OAAO,IAAI,KAAK;GAAG,GAAI,UAAU,EAAE,KAAK,IAAI,CAAC;EAAG;EACpE,GAAI,QACA;GACE;IAAE,OAAO;IAAO,OAAO,IAAI,MAAM,GAAG;GAAE;GACtC;IAAE,OAAO;IAAO,OAAO,IAAI,MAAM,GAAG;GAAE;GACtC;IAAE,OAAO;IAAO,OAAO,IAAI,MAAM,GAAG;GAAE;EACxC,IACA,CAAC;EACL,GAAI,UAAU,KAAA,IACV,CAAC;GAAE,OAAO;GAAY,OAAO,IAAI,KAAK;EAAE,CAAC,IACzC,CAAC;CACP,IACA,CAAC;CACL,MAAM,WAAW,aAAa,UAAU,SAAS;CACjD,MAAM,SAAS,aAAa;CAE5B,IAAI,YAAY,QAAQ;EACtB,MAAM,OACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;GACE,WAAWN,cAAAA,GACT,mFACA,SACF;GACA,GAAK,WAAW,CAAC,IAAI,EAAE,OAAO,UAAU;GACxC,cAAY,YAAY,CAAC,YAAY,YAAY,KAAA;GACjD,cAAY;GAPd,UAAA;IASG,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,EAAiB,KAAO,CAAA,IAAI;IACnC,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KAA0C,UAAA;IAAY,CAAA,IAAI;IACtF,UAAU,WACT,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAe;KAAa;KAAQ,WAAU;IAAuB,CAAA,IAErE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KAA4B,eAAY;KACtD,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAe;MAAW;MAAM,aAAa;KAAK,CAAA;IAC9C,CAAA;IAER,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,cAAAA,GAAG,uCAAuC,WAAW;KACnE,UAAA;IACG,CAAA;GACF;;EAER,OAAO,WACL,iBAAA,GAAA,kBAAA,IAAA,CAACS,uBAAAA,gBAAD;GAAuB;GAAO,MAAM;GAAmB;GAAQ,SAAS;EAAO,CAAA,IAE/E;CAEJ;CAEA,MAAM,OACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EACE,WAAWT,cAAAA,GAAG,oCAAoC,SAAS;EAC3D,GAAK,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,YAAY,KAAA,EAAU;EACjE,cAAY,YAAY,CAAC,YAAY,YAAY,KAAA;EACjD,cAAY;EAJd,UAAA,CAMG,UAAU,WACT,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAe;KAAa;KAAQ,WAAU;IAAc,CAAA;IAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KAAkD,UAAA;IAAc,CAAA;IAC/E,aACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,cAAW;KACX,eAAe,YAAY,IAAI;KAC/B,WAAU;KAEV,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,MAAD;MAAM,MAAMS,qBAAAA;MAAc,OAAO;MAAI,QAAQ;KAAK,CAAA;IAC5C,CAAA;GAEP;EAEL,CAAA,IAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAe;KAAW;KAAM,aAAa;IAAI,CAAA;IACjD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KACb,UAAA;IACG,CAAA;IACL,aACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,cAAW;KACX,eAAe,YAAY,IAAI;KAC/B,WAAU;KAEV,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACT,aAAAA,MAAD;MAAM,MAAMS,qBAAAA;MAAc,OAAO;MAAI,QAAQ;KAAK,CAAA;IAC5C,CAAA;GAEP;EAEN,CAAA,GAAA,QAAQ,YACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACG,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,EAAiB,KAAO,CAAA,IAAI,MACnC,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,MAAY,CAAA,IAAI,IACjC;EACH,CAAA,IAAA,IACD;;CAGP,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAAC,kBAAAA,UAAA,EAAA,UAAA,CACG,WACC,iBAAA,GAAA,kBAAA,IAAA,CAACF,uBAAAA,gBAAD;EACS;EACP,MAAM;EACE;EACR,SAAS;EACT,WAAU;CACX,CAAA,IAED,MAED,aACC,iBAAA,GAAA,kBAAA,IAAA,CAACG,cAAAA,OAAD;EAAO,MAAM;EAAU,eAAe,YAAY,KAAK;EAAU;EAAO,MAAK;EAC3E,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,wBAAAA,iBAAD;GACS;GACP,GAAK,OAAO,EAAE,KAAK,IAAI,CAAC;GACxB,GAAK,OAAO,EAAE,KAAK,IAAI,CAAC;GACf;GACT,QAAQ;GACD;GACI;GACX,YAAY;GACH;EACV,CAAA;CACI,CAAA,CAET,EAAA,CAAA;AAEN"}
|
|
1
|
+
{"version":3,"file":"TimeseriesGauge.cjs","names":["cn","Icon","defaultTimeseriesFetcher","useState","useTimeseriesQueries","soleSeries","latestValue","formatUnit","useMemo","seriesStats","GaugeHoverCard","UiFullscreen","_Fragment","Modal","TimeseriesPanel"],"sources":["../../src/data/TimeseriesGauge.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { formatUnit } from \"../lib/format\";\nimport { Modal } from \"../overlay/Modal\";\nimport { UiFullscreen } from \"../icons\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport {\n TimeseriesPanel,\n type SeriesLoader,\n type TimeseriesResponse,\n type TimeseriesSeries,\n} from \"./TimeseriesPanel\";\nimport {\n defaultTimeseriesFetcher,\n latestValue,\n soleSeries,\n useTimeseriesQueries,\n} from \"./timeseries-query\";\nimport { GaugeHoverCard, type GaugeHoverRow } from \"./GaugeHoverCard\";\nimport { seriesStats } from \"./gauge-stats\";\n\n/**\n * A metric series whose latest value drives the gauge fill or its maximum. It\n * is requested as `baseUrl + id` through the widget's `fetcher`, or, when\n * `load` is set, loaded by calling `load` directly.\n */\nexport interface GaugeSeries {\n /**\n * Metric id appended to the gauge's baseUrl, e.g. \"k8s.statefulset.cycle.cpu.usage\".\n * With `load`, the id is the cache identity: loaded series are cached under\n * `[\"timeseries\", \"load\", id, range]`, so keep it unique per data source.\n */\n id: string;\n /** Maps the latest value before display (e.g. unit scaling). Identity when omitted. */\n transform?: (value: number) => number;\n /** Loads the series' points; when set, `baseUrl` and `fetcher` are not used. */\n load?: SeriesLoader;\n}\n\nexport type TimeseriesGaugeVariant = \"default\" | \"cell\";\n/** Gauge fill geometry: a half-circle arc (default) or a horizontal progress bar. */\nexport type TimeseriesGaugeShape = \"radial\" | \"linear\";\n\nexport interface TimeseriesGaugeProps {\n /** Common prefix; the value/max requests are `baseUrl + id` (unless a series has `load`). */\n baseUrl?: string;\n /** The metric whose latest value fills the gauge. */\n value: GaugeSeries;\n /**\n * The gauge maximum. Either a metric series (its latest value, e.g. a `.limit`\n * metric) or a fixed number. When omitted, or when the resolved max is 0, the\n * gauge shows the raw value with no fill (an unbounded reading).\n */\n max?: GaugeSeries | number;\n title: string;\n /** Iconify name or static icon component shown beside the label. */\n icon?: string | StaticIconComponent;\n /** Grafana-style unit key for the readout (e.g. \"bytes\", \"percent\", \"short\", \"ms\"). */\n unit?: string;\n /** Look-back window for the expand chart, passed as ?since=; defaults to \"1h\". */\n range?: string;\n /** Poll interval in ms; defaults to 5000. Pass 0 to disable polling. */\n refreshMs?: number;\n /** Show an expand button that opens the value/max time-series chart in a modal. Default true. */\n expandable?: boolean;\n /**\n * Utilisation thresholds (percent of max) at which the arc turns amber then\n * red. Defaults to [75, 90].\n */\n thresholds?: [warning: number, danger: number];\n /**\n * What to print in the centre: the formatted value (default) or the\n * utilisation percentage of max (e.g. CPU usage out of its millicore limit).\n */\n centerDisplay?: \"value\" | \"percent\";\n /** Visual density/layout. `cell` is a compact inline form for table/grid cells. */\n variant?: TimeseriesGaugeVariant;\n /** Fill geometry: a radial half-gauge (default) or a horizontal progress bar. */\n shape?: TimeseriesGaugeShape;\n /** Show the title text. Icons and values remain visible when false. */\n showLabel?: boolean;\n /**\n * Wrap the gauge in a hover card summarising the metric (label + current / min /\n * max / avg / capacity over the window). Defaults to true.\n */\n hoverCard?: boolean;\n /** Override the default fetch (e.g. to route through an app's API client). */\n fetcher?: (url: string) => Promise<TimeseriesResponse>;\n className?: string;\n}\n\n// Half-gauge SVG geometry: a 100×50 viewBox semicircle (radius 40, centre 50,50)\n// swept 180°. The arc length is π·r; stroke-dashoffset reveals value/max of it.\nconst GAUGE_RADIUS = 40;\nconst GAUGE_ARC = Math.PI * GAUGE_RADIUS;\nconst GAUGE_PATH = `M 10 50 A ${GAUGE_RADIUS} ${GAUGE_RADIUS} 0 0 1 90 50`;\n\nfunction toneClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"text-red-500\";\n if (pct >= warn) return \"text-amber-500\";\n return \"text-emerald-500\";\n}\n\n// toneBgClass mirrors toneClass for the linear bar's fill, which needs a\n// background colour rather than the arc's stroke (currentColor) tone.\nfunction toneBgClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"bg-red-500\";\n if (pct >= warn) return \"bg-amber-500\";\n return \"bg-emerald-500\";\n}\n\n// GaugeArc is the half-circle SVG shared by the cell and default radial gauges;\n// only the stroke width differs between the two densities.\nfunction GaugeArc({ pct, tone, strokeWidth }: { pct: number; tone: string; strokeWidth: number }) {\n return (\n <svg viewBox=\"0 0 100 50\" className=\"h-full w-full overflow-visible\">\n <path d={GAUGE_PATH} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" className=\"text-muted\" />\n <path\n d={GAUGE_PATH}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={tone}\n strokeDasharray={GAUGE_ARC}\n strokeDashoffset={GAUGE_ARC * (1 - pct / 100)}\n />\n </svg>\n );\n}\n\n// GaugeBar is the horizontal progress track shared by the cell and default linear\n// gauges; the caller sizes it via className (e.g. \"h-1.5 w-12\" or \"h-2 w-full\").\nfunction GaugeBar({ pct, toneBg, className }: { pct: number; toneBg: string; className?: string }) {\n return (\n <span className={cn(\"relative block overflow-hidden rounded-full bg-muted\", className)} aria-hidden=\"true\">\n <span\n className={cn(\"absolute inset-y-0 left-0 rounded-full transition-all duration-300\", toneBg)}\n style={{ width: `${pct}%` }}\n />\n </span>\n );\n}\n\nfunction GaugeIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n }\n return <Icon icon={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n}\n\n/**\n * TimeseriesGauge renders a half (180°) radial gauge whose fill is the latest\n * value of a metric over its maximum (a `.limit`-style metric or a fixed number),\n * both read live from the timeseries store. The centre shows the utilisation\n * percentage, with the value/max caption below; the arc colour crosses warning\n * and danger thresholds. An expand button opens the full value/max time-series\n * chart in a modal (a `TimeseriesPanel`), so the gauge gives the at-a-glance\n * reading and the chart the trend.\n */\nexport function TimeseriesGauge({\n baseUrl = \"\",\n value,\n max,\n title,\n icon,\n unit,\n range = \"1h\",\n refreshMs = 5000,\n expandable = true,\n thresholds = [75, 90],\n centerDisplay = \"value\",\n variant = \"default\",\n shape = \"radial\",\n showLabel = true,\n hoverCard = true,\n fetcher = defaultTimeseriesFetcher,\n className,\n}: TimeseriesGaugeProps) {\n const [expanded, setExpanded] = useState(false);\n\n const maxIsSeries = typeof max === \"object\";\n const maxSeries = maxIsSeries ? max : undefined;\n const results = useTimeseriesQueries(maxSeries ? [value, maxSeries] : [value], {\n baseUrl,\n range,\n refreshMs,\n fetcher,\n });\n\n const valueRead = soleSeries(value.id, results[0]);\n const maxRead = maxSeries ? soleSeries(maxSeries.id, results[1]) : undefined;\n const error = valueRead.error ?? maxRead?.error ?? null;\n const rawValue = latestValue(valueRead.data);\n const hasValue = rawValue !== undefined;\n const usage = value.transform ? value.transform(rawValue ?? 0) : (rawValue ?? 0);\n\n let limit: number | undefined;\n if (typeof max === \"number\") {\n limit = max;\n } else if (maxSeries) {\n const rawMax = latestValue(maxRead?.data);\n limit = rawMax === undefined ? undefined : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;\n }\n\n const bounded = hasValue && limit !== undefined && limit > 0;\n const pct = bounded ? Math.min(100, Math.round((usage / (limit as number)) * 100)) : 0;\n const tone = toneClass(pct, thresholds);\n const toneBg = toneBgClass(pct, thresholds);\n const readout =\n centerDisplay === \"percent\"\n ? bounded\n ? `${pct}%`\n : hasValue\n ? \"n/a\"\n : \"—\"\n : hasValue\n ? formatUnit(usage, unit)\n : \"—\";\n const titleText = `${title}: ${error ? error.message : readout}`;\n const canExpand = expandable && variant === \"default\";\n const readoutTone = bounded ? tone : \"text-foreground\";\n\n const chartSeries: TimeseriesSeries[] = useMemo(() => {\n const s: TimeseriesSeries[] = [{ ...value, label: \"value\" }];\n if (maxSeries) s.push({ ...maxSeries, label: \"max\" });\n return s;\n }, [value, maxSeries]);\n\n // Hover card: reduce the value's points to current/min/max/avg (transformed to\n // the display unit), plus the resolved capacity. The current row is tinted by\n // its threshold tone when the reading is bounded.\n const stats = seriesStats(valueRead.data?.points, value.transform);\n const fmt = (n: number) => formatUnit(n, unit);\n const hoverRows: GaugeHoverRow[] = error\n ? [{ label: \"Error\", value: error.message, tone: \"text-red-500\" }]\n : hasValue\n ? [\n { label: \"Current\", value: fmt(usage), ...(bounded ? { tone } : {}) },\n ...(stats\n ? [\n { label: \"Min\", value: fmt(stats.min) },\n { label: \"Max\", value: fmt(stats.max) },\n { label: \"Avg\", value: fmt(stats.avg) },\n ]\n : []),\n ...(limit !== undefined\n ? [{ label: \"Capacity\", value: fmt(limit) }]\n : []),\n ]\n : [];\n const useHover = hoverCard && hoverRows.length > 0;\n const footer = `over last ${range}`;\n\n if (variant === \"cell\") {\n const cell = (\n <span\n className={cn(\n \"inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap align-middle text-xs\",\n className,\n )}\n {...(useHover ? {} : { title: titleText })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span className=\"min-w-0 truncate text-muted-foreground\">{title}</span> : null}\n {shape === \"linear\" ? (\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-1.5 w-12 shrink-0\" />\n ) : (\n <span className=\"relative h-4 w-8 shrink-0\" aria-hidden=\"true\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={10} />\n </span>\n )}\n <span className={cn(\"shrink-0 font-semibold tabular-nums\", readoutTone)}>\n {readout}\n </span>\n </span>\n );\n return useHover ? (\n <GaugeHoverCard title={title} rows={hoverRows} footer={footer} trigger={cell} />\n ) : (\n cell\n );\n }\n\n const body = (\n <div\n className={cn(\"flex flex-col items-center gap-1\", className)}\n {...(useHover ? {} : { title: !showLabel ? titleText : undefined })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {shape === \"linear\" ? (\n <div className=\"flex w-full items-center gap-2\">\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-2 w-full\" />\n <span className=\"shrink-0 text-sm font-semibold text-foreground\">{readout}</span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"shrink-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n ) : (\n <div className=\"relative h-10 w-20\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={9} />\n <span className=\"absolute inset-x-0 bottom-0 text-center text-sm font-semibold text-foreground\">\n {readout}\n </span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"absolute right-0 top-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n )}\n {icon || showLabel ? (\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span>{title}</span> : null}\n </div>\n ) : null}\n </div>\n );\n\n return (\n <>\n {useHover ? (\n <GaugeHoverCard\n title={title}\n rows={hoverRows}\n footer={footer}\n trigger={body}\n className=\"w-full justify-center\"\n />\n ) : (\n body\n )}\n {canExpand && (\n <Modal open={expanded} onClose={() => setExpanded(false)} title={title} size=\"xl\">\n <TimeseriesPanel\n title={title}\n {...(icon ? { icon } : {})}\n {...(unit ? { unit } : {})}\n baseUrl={baseUrl}\n series={chartSeries}\n range={range}\n refreshMs={refreshMs}\n expandable={false}\n fetcher={fetcher}\n />\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesGauge.d.ts","sourceRoot":"","sources":["../../src/data/TimeseriesGauge.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAQ,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EAExB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"TimeseriesGauge.d.ts","sourceRoot":"","sources":["../../src/data/TimeseriesGauge.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAQ,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EAExB,MAAM,mBAAmB,CAAC;AAU3B;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,uFAAuF;IACvF,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACtC,gFAAgF;IAChF,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,MAAM,CAAC;AACxD,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,KAAK,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,uFAAuF;IACvF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iGAAiG;IACjG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,mFAAmF;IACnF,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,iFAAiF;IACjF,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8DD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,OAAY,EACZ,KAAK,EACL,GAAG,EACH,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAY,EACZ,SAAgB,EAChB,UAAiB,EACjB,UAAqB,EACrB,aAAuB,EACvB,OAAmB,EACnB,KAAgB,EAChB,SAAgB,EAChB,SAAgB,EAChB,OAAkC,EAClC,SAAS,GACV,EAAE,oBAAoB,+BA2LtB"}
|
|
@@ -3,7 +3,7 @@ import { UiFullscreen } from "../icons/components/UiFullscreen.js";
|
|
|
3
3
|
import { formatUnit } from "../lib/format.js";
|
|
4
4
|
import { Icon } from "./Icon.js";
|
|
5
5
|
import { Modal } from "../overlay/Modal.js";
|
|
6
|
-
import { defaultTimeseriesFetcher, latestValue, useTimeseriesQueries } from "./timeseries-query.js";
|
|
6
|
+
import { defaultTimeseriesFetcher, latestValue, soleSeries, useTimeseriesQueries } from "./timeseries-query.js";
|
|
7
7
|
import { TimeseriesPanel } from "./TimeseriesPanel.js";
|
|
8
8
|
import { GaugeHoverCard } from "./GaugeHoverCard.js";
|
|
9
9
|
import { seriesStats } from "./gauge-stats.js";
|
|
@@ -88,13 +88,16 @@ function TimeseriesGauge({ baseUrl = "", value, max, title, icon, unit, range =
|
|
|
88
88
|
refreshMs,
|
|
89
89
|
fetcher
|
|
90
90
|
});
|
|
91
|
-
const
|
|
91
|
+
const valueRead = soleSeries(value.id, results[0]);
|
|
92
|
+
const maxRead = maxSeries ? soleSeries(maxSeries.id, results[1]) : void 0;
|
|
93
|
+
const error = valueRead.error ?? maxRead?.error ?? null;
|
|
94
|
+
const rawValue = latestValue(valueRead.data);
|
|
92
95
|
const hasValue = rawValue !== void 0;
|
|
93
96
|
const usage = value.transform ? value.transform(rawValue ?? 0) : rawValue ?? 0;
|
|
94
97
|
let limit;
|
|
95
98
|
if (typeof max === "number") limit = max;
|
|
96
99
|
else if (maxSeries) {
|
|
97
|
-
const rawMax = latestValue(
|
|
100
|
+
const rawMax = latestValue(maxRead?.data);
|
|
98
101
|
limit = rawMax === void 0 ? void 0 : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;
|
|
99
102
|
}
|
|
100
103
|
const bounded = hasValue && limit !== void 0 && limit > 0;
|
|
@@ -102,7 +105,7 @@ function TimeseriesGauge({ baseUrl = "", value, max, title, icon, unit, range =
|
|
|
102
105
|
const tone = toneClass(pct, thresholds);
|
|
103
106
|
const toneBg = toneBgClass(pct, thresholds);
|
|
104
107
|
const readout = centerDisplay === "percent" ? bounded ? `${pct}%` : hasValue ? "n/a" : "—" : hasValue ? formatUnit(usage, unit) : "—";
|
|
105
|
-
const titleText = `${title}: ${readout}`;
|
|
108
|
+
const titleText = `${title}: ${error ? error.message : readout}`;
|
|
106
109
|
const canExpand = expandable && variant === "default";
|
|
107
110
|
const readoutTone = bounded ? tone : "text-foreground";
|
|
108
111
|
const chartSeries = useMemo(() => {
|
|
@@ -116,9 +119,13 @@ function TimeseriesGauge({ baseUrl = "", value, max, title, icon, unit, range =
|
|
|
116
119
|
});
|
|
117
120
|
return s;
|
|
118
121
|
}, [value, maxSeries]);
|
|
119
|
-
const stats = seriesStats(
|
|
122
|
+
const stats = seriesStats(valueRead.data?.points, value.transform);
|
|
120
123
|
const fmt = (n) => formatUnit(n, unit);
|
|
121
|
-
const hoverRows =
|
|
124
|
+
const hoverRows = error ? [{
|
|
125
|
+
label: "Error",
|
|
126
|
+
value: error.message,
|
|
127
|
+
tone: "text-red-500"
|
|
128
|
+
}] : hasValue ? [
|
|
122
129
|
{
|
|
123
130
|
label: "Current",
|
|
124
131
|
value: fmt(usage),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesGauge.js","names":["_Fragment"],"sources":["../../src/data/TimeseriesGauge.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { formatUnit } from \"../lib/format\";\nimport { Modal } from \"../overlay/Modal\";\nimport { UiFullscreen } from \"../icons\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport {\n TimeseriesPanel,\n type SeriesLoader,\n type TimeseriesResponse,\n type TimeseriesSeries,\n} from \"./TimeseriesPanel\";\nimport { defaultTimeseriesFetcher, latestValue, useTimeseriesQueries } from \"./timeseries-query\";\nimport { GaugeHoverCard, type GaugeHoverRow } from \"./GaugeHoverCard\";\nimport { seriesStats } from \"./gauge-stats\";\n\n/**\n * A metric series whose latest value drives the gauge fill or its maximum. It\n * is requested as `baseUrl + id` through the widget's `fetcher`, or, when\n * `load` is set, loaded by calling `load` directly.\n */\nexport interface GaugeSeries {\n /**\n * Metric id appended to the gauge's baseUrl, e.g. \"k8s.statefulset.cycle.cpu.usage\".\n * With `load`, the id is the cache identity: loaded series are cached under\n * `[\"timeseries\", \"load\", id, range]`, so keep it unique per data source.\n */\n id: string;\n /** Maps the latest value before display (e.g. unit scaling). Identity when omitted. */\n transform?: (value: number) => number;\n /** Loads the series' points; when set, `baseUrl` and `fetcher` are not used. */\n load?: SeriesLoader;\n}\n\nexport type TimeseriesGaugeVariant = \"default\" | \"cell\";\n/** Gauge fill geometry: a half-circle arc (default) or a horizontal progress bar. */\nexport type TimeseriesGaugeShape = \"radial\" | \"linear\";\n\nexport interface TimeseriesGaugeProps {\n /** Common prefix; the value/max requests are `baseUrl + id` (unless a series has `load`). */\n baseUrl?: string;\n /** The metric whose latest value fills the gauge. */\n value: GaugeSeries;\n /**\n * The gauge maximum. Either a metric series (its latest value, e.g. a `.limit`\n * metric) or a fixed number. When omitted, or when the resolved max is 0, the\n * gauge shows the raw value with no fill (an unbounded reading).\n */\n max?: GaugeSeries | number;\n title: string;\n /** Iconify name or static icon component shown beside the label. */\n icon?: string | StaticIconComponent;\n /** Grafana-style unit key for the readout (e.g. \"bytes\", \"percent\", \"short\", \"ms\"). */\n unit?: string;\n /** Look-back window for the expand chart, passed as ?since=; defaults to \"1h\". */\n range?: string;\n /** Poll interval in ms; defaults to 5000. Pass 0 to disable polling. */\n refreshMs?: number;\n /** Show an expand button that opens the value/max time-series chart in a modal. Default true. */\n expandable?: boolean;\n /**\n * Utilisation thresholds (percent of max) at which the arc turns amber then\n * red. Defaults to [75, 90].\n */\n thresholds?: [warning: number, danger: number];\n /**\n * What to print in the centre: the formatted value (default) or the\n * utilisation percentage of max (e.g. CPU usage out of its millicore limit).\n */\n centerDisplay?: \"value\" | \"percent\";\n /** Visual density/layout. `cell` is a compact inline form for table/grid cells. */\n variant?: TimeseriesGaugeVariant;\n /** Fill geometry: a radial half-gauge (default) or a horizontal progress bar. */\n shape?: TimeseriesGaugeShape;\n /** Show the title text. Icons and values remain visible when false. */\n showLabel?: boolean;\n /**\n * Wrap the gauge in a hover card summarising the metric (label + current / min /\n * max / avg / capacity over the window). Defaults to true.\n */\n hoverCard?: boolean;\n /** Override the default fetch (e.g. to route through an app's API client). */\n fetcher?: (url: string) => Promise<TimeseriesResponse>;\n className?: string;\n}\n\n// Half-gauge SVG geometry: a 100×50 viewBox semicircle (radius 40, centre 50,50)\n// swept 180°. The arc length is π·r; stroke-dashoffset reveals value/max of it.\nconst GAUGE_RADIUS = 40;\nconst GAUGE_ARC = Math.PI * GAUGE_RADIUS;\nconst GAUGE_PATH = `M 10 50 A ${GAUGE_RADIUS} ${GAUGE_RADIUS} 0 0 1 90 50`;\n\nfunction toneClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"text-red-500\";\n if (pct >= warn) return \"text-amber-500\";\n return \"text-emerald-500\";\n}\n\n// toneBgClass mirrors toneClass for the linear bar's fill, which needs a\n// background colour rather than the arc's stroke (currentColor) tone.\nfunction toneBgClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"bg-red-500\";\n if (pct >= warn) return \"bg-amber-500\";\n return \"bg-emerald-500\";\n}\n\n// GaugeArc is the half-circle SVG shared by the cell and default radial gauges;\n// only the stroke width differs between the two densities.\nfunction GaugeArc({ pct, tone, strokeWidth }: { pct: number; tone: string; strokeWidth: number }) {\n return (\n <svg viewBox=\"0 0 100 50\" className=\"h-full w-full overflow-visible\">\n <path d={GAUGE_PATH} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" className=\"text-muted\" />\n <path\n d={GAUGE_PATH}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={tone}\n strokeDasharray={GAUGE_ARC}\n strokeDashoffset={GAUGE_ARC * (1 - pct / 100)}\n />\n </svg>\n );\n}\n\n// GaugeBar is the horizontal progress track shared by the cell and default linear\n// gauges; the caller sizes it via className (e.g. \"h-1.5 w-12\" or \"h-2 w-full\").\nfunction GaugeBar({ pct, toneBg, className }: { pct: number; toneBg: string; className?: string }) {\n return (\n <span className={cn(\"relative block overflow-hidden rounded-full bg-muted\", className)} aria-hidden=\"true\">\n <span\n className={cn(\"absolute inset-y-0 left-0 rounded-full transition-all duration-300\", toneBg)}\n style={{ width: `${pct}%` }}\n />\n </span>\n );\n}\n\nfunction GaugeIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n }\n return <Icon icon={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n}\n\n/**\n * TimeseriesGauge renders a half (180°) radial gauge whose fill is the latest\n * value of a metric over its maximum (a `.limit`-style metric or a fixed number),\n * both read live from the timeseries store. The centre shows the utilisation\n * percentage, with the value/max caption below; the arc colour crosses warning\n * and danger thresholds. An expand button opens the full value/max time-series\n * chart in a modal (a `TimeseriesPanel`), so the gauge gives the at-a-glance\n * reading and the chart the trend.\n */\nexport function TimeseriesGauge({\n baseUrl = \"\",\n value,\n max,\n title,\n icon,\n unit,\n range = \"1h\",\n refreshMs = 5000,\n expandable = true,\n thresholds = [75, 90],\n centerDisplay = \"value\",\n variant = \"default\",\n shape = \"radial\",\n showLabel = true,\n hoverCard = true,\n fetcher = defaultTimeseriesFetcher,\n className,\n}: TimeseriesGaugeProps) {\n const [expanded, setExpanded] = useState(false);\n\n const maxIsSeries = typeof max === \"object\";\n const maxSeries = maxIsSeries ? max : undefined;\n const results = useTimeseriesQueries(maxSeries ? [value, maxSeries] : [value], {\n baseUrl,\n range,\n refreshMs,\n fetcher,\n });\n\n const rawValue = latestValue(results[0]?.data);\n const hasValue = rawValue !== undefined;\n const usage = value.transform ? value.transform(rawValue ?? 0) : (rawValue ?? 0);\n\n let limit: number | undefined;\n if (typeof max === \"number\") {\n limit = max;\n } else if (maxSeries) {\n const rawMax = latestValue(results[1]?.data);\n limit = rawMax === undefined ? undefined : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;\n }\n\n const bounded = hasValue && limit !== undefined && limit > 0;\n const pct = bounded ? Math.min(100, Math.round((usage / (limit as number)) * 100)) : 0;\n const tone = toneClass(pct, thresholds);\n const toneBg = toneBgClass(pct, thresholds);\n const readout =\n centerDisplay === \"percent\"\n ? bounded\n ? `${pct}%`\n : hasValue\n ? \"n/a\"\n : \"—\"\n : hasValue\n ? formatUnit(usage, unit)\n : \"—\";\n const titleText = `${title}: ${readout}`;\n const canExpand = expandable && variant === \"default\";\n const readoutTone = bounded ? tone : \"text-foreground\";\n\n const chartSeries: TimeseriesSeries[] = useMemo(() => {\n const s: TimeseriesSeries[] = [{ ...value, label: \"value\" }];\n if (maxSeries) s.push({ ...maxSeries, label: \"max\" });\n return s;\n }, [value, maxSeries]);\n\n // Hover card: reduce the value's points to current/min/max/avg (transformed to\n // the display unit), plus the resolved capacity. The current row is tinted by\n // its threshold tone when the reading is bounded.\n const stats = seriesStats(results[0]?.data?.points, value.transform);\n const fmt = (n: number) => formatUnit(n, unit);\n const hoverRows: GaugeHoverRow[] = hasValue\n ? [\n { label: \"Current\", value: fmt(usage), ...(bounded ? { tone } : {}) },\n ...(stats\n ? [\n { label: \"Min\", value: fmt(stats.min) },\n { label: \"Max\", value: fmt(stats.max) },\n { label: \"Avg\", value: fmt(stats.avg) },\n ]\n : []),\n ...(limit !== undefined\n ? [{ label: \"Capacity\", value: fmt(limit) }]\n : []),\n ]\n : [];\n const useHover = hoverCard && hoverRows.length > 0;\n const footer = `over last ${range}`;\n\n if (variant === \"cell\") {\n const cell = (\n <span\n className={cn(\n \"inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap align-middle text-xs\",\n className,\n )}\n {...(useHover ? {} : { title: titleText })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span className=\"min-w-0 truncate text-muted-foreground\">{title}</span> : null}\n {shape === \"linear\" ? (\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-1.5 w-12 shrink-0\" />\n ) : (\n <span className=\"relative h-4 w-8 shrink-0\" aria-hidden=\"true\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={10} />\n </span>\n )}\n <span className={cn(\"shrink-0 font-semibold tabular-nums\", readoutTone)}>\n {readout}\n </span>\n </span>\n );\n return useHover ? (\n <GaugeHoverCard title={title} rows={hoverRows} footer={footer} trigger={cell} />\n ) : (\n cell\n );\n }\n\n const body = (\n <div\n className={cn(\"flex flex-col items-center gap-1\", className)}\n {...(useHover ? {} : { title: !showLabel ? titleText : undefined })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {shape === \"linear\" ? (\n <div className=\"flex w-full items-center gap-2\">\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-2 w-full\" />\n <span className=\"shrink-0 text-sm font-semibold text-foreground\">{readout}</span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"shrink-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n ) : (\n <div className=\"relative h-10 w-20\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={9} />\n <span className=\"absolute inset-x-0 bottom-0 text-center text-sm font-semibold text-foreground\">\n {readout}\n </span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"absolute right-0 top-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n )}\n {icon || showLabel ? (\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span>{title}</span> : null}\n </div>\n ) : null}\n </div>\n );\n\n return (\n <>\n {useHover ? (\n <GaugeHoverCard\n title={title}\n rows={hoverRows}\n footer={footer}\n trigger={body}\n className=\"w-full justify-center\"\n />\n ) : (\n body\n )}\n {canExpand && (\n <Modal open={expanded} onClose={() => setExpanded(false)} title={title} size=\"xl\">\n <TimeseriesPanel\n title={title}\n {...(icon ? { icon } : {})}\n {...(unit ? { unit } : {})}\n baseUrl={baseUrl}\n series={chartSeries}\n range={range}\n refreshMs={refreshMs}\n expandable={false}\n fetcher={fetcher}\n />\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimeseriesGauge.js","names":["_Fragment"],"sources":["../../src/data/TimeseriesGauge.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { formatUnit } from \"../lib/format\";\nimport { Modal } from \"../overlay/Modal\";\nimport { UiFullscreen } from \"../icons\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport {\n TimeseriesPanel,\n type SeriesLoader,\n type TimeseriesResponse,\n type TimeseriesSeries,\n} from \"./TimeseriesPanel\";\nimport {\n defaultTimeseriesFetcher,\n latestValue,\n soleSeries,\n useTimeseriesQueries,\n} from \"./timeseries-query\";\nimport { GaugeHoverCard, type GaugeHoverRow } from \"./GaugeHoverCard\";\nimport { seriesStats } from \"./gauge-stats\";\n\n/**\n * A metric series whose latest value drives the gauge fill or its maximum. It\n * is requested as `baseUrl + id` through the widget's `fetcher`, or, when\n * `load` is set, loaded by calling `load` directly.\n */\nexport interface GaugeSeries {\n /**\n * Metric id appended to the gauge's baseUrl, e.g. \"k8s.statefulset.cycle.cpu.usage\".\n * With `load`, the id is the cache identity: loaded series are cached under\n * `[\"timeseries\", \"load\", id, range]`, so keep it unique per data source.\n */\n id: string;\n /** Maps the latest value before display (e.g. unit scaling). Identity when omitted. */\n transform?: (value: number) => number;\n /** Loads the series' points; when set, `baseUrl` and `fetcher` are not used. */\n load?: SeriesLoader;\n}\n\nexport type TimeseriesGaugeVariant = \"default\" | \"cell\";\n/** Gauge fill geometry: a half-circle arc (default) or a horizontal progress bar. */\nexport type TimeseriesGaugeShape = \"radial\" | \"linear\";\n\nexport interface TimeseriesGaugeProps {\n /** Common prefix; the value/max requests are `baseUrl + id` (unless a series has `load`). */\n baseUrl?: string;\n /** The metric whose latest value fills the gauge. */\n value: GaugeSeries;\n /**\n * The gauge maximum. Either a metric series (its latest value, e.g. a `.limit`\n * metric) or a fixed number. When omitted, or when the resolved max is 0, the\n * gauge shows the raw value with no fill (an unbounded reading).\n */\n max?: GaugeSeries | number;\n title: string;\n /** Iconify name or static icon component shown beside the label. */\n icon?: string | StaticIconComponent;\n /** Grafana-style unit key for the readout (e.g. \"bytes\", \"percent\", \"short\", \"ms\"). */\n unit?: string;\n /** Look-back window for the expand chart, passed as ?since=; defaults to \"1h\". */\n range?: string;\n /** Poll interval in ms; defaults to 5000. Pass 0 to disable polling. */\n refreshMs?: number;\n /** Show an expand button that opens the value/max time-series chart in a modal. Default true. */\n expandable?: boolean;\n /**\n * Utilisation thresholds (percent of max) at which the arc turns amber then\n * red. Defaults to [75, 90].\n */\n thresholds?: [warning: number, danger: number];\n /**\n * What to print in the centre: the formatted value (default) or the\n * utilisation percentage of max (e.g. CPU usage out of its millicore limit).\n */\n centerDisplay?: \"value\" | \"percent\";\n /** Visual density/layout. `cell` is a compact inline form for table/grid cells. */\n variant?: TimeseriesGaugeVariant;\n /** Fill geometry: a radial half-gauge (default) or a horizontal progress bar. */\n shape?: TimeseriesGaugeShape;\n /** Show the title text. Icons and values remain visible when false. */\n showLabel?: boolean;\n /**\n * Wrap the gauge in a hover card summarising the metric (label + current / min /\n * max / avg / capacity over the window). Defaults to true.\n */\n hoverCard?: boolean;\n /** Override the default fetch (e.g. to route through an app's API client). */\n fetcher?: (url: string) => Promise<TimeseriesResponse>;\n className?: string;\n}\n\n// Half-gauge SVG geometry: a 100×50 viewBox semicircle (radius 40, centre 50,50)\n// swept 180°. The arc length is π·r; stroke-dashoffset reveals value/max of it.\nconst GAUGE_RADIUS = 40;\nconst GAUGE_ARC = Math.PI * GAUGE_RADIUS;\nconst GAUGE_PATH = `M 10 50 A ${GAUGE_RADIUS} ${GAUGE_RADIUS} 0 0 1 90 50`;\n\nfunction toneClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"text-red-500\";\n if (pct >= warn) return \"text-amber-500\";\n return \"text-emerald-500\";\n}\n\n// toneBgClass mirrors toneClass for the linear bar's fill, which needs a\n// background colour rather than the arc's stroke (currentColor) tone.\nfunction toneBgClass(pct: number, [warn, danger]: [number, number]): string {\n if (pct >= danger) return \"bg-red-500\";\n if (pct >= warn) return \"bg-amber-500\";\n return \"bg-emerald-500\";\n}\n\n// GaugeArc is the half-circle SVG shared by the cell and default radial gauges;\n// only the stroke width differs between the two densities.\nfunction GaugeArc({ pct, tone, strokeWidth }: { pct: number; tone: string; strokeWidth: number }) {\n return (\n <svg viewBox=\"0 0 100 50\" className=\"h-full w-full overflow-visible\">\n <path d={GAUGE_PATH} fill=\"none\" stroke=\"currentColor\" strokeWidth={strokeWidth} strokeLinecap=\"round\" className=\"text-muted\" />\n <path\n d={GAUGE_PATH}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n className={tone}\n strokeDasharray={GAUGE_ARC}\n strokeDashoffset={GAUGE_ARC * (1 - pct / 100)}\n />\n </svg>\n );\n}\n\n// GaugeBar is the horizontal progress track shared by the cell and default linear\n// gauges; the caller sizes it via className (e.g. \"h-1.5 w-12\" or \"h-2 w-full\").\nfunction GaugeBar({ pct, toneBg, className }: { pct: number; toneBg: string; className?: string }) {\n return (\n <span className={cn(\"relative block overflow-hidden rounded-full bg-muted\", className)} aria-hidden=\"true\">\n <span\n className={cn(\"absolute inset-y-0 left-0 rounded-full transition-all duration-300\", toneBg)}\n style={{ width: `${pct}%` }}\n />\n </span>\n );\n}\n\nfunction GaugeIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n }\n return <Icon icon={icon} width={14} height={14} className=\"text-muted-foreground\" />;\n}\n\n/**\n * TimeseriesGauge renders a half (180°) radial gauge whose fill is the latest\n * value of a metric over its maximum (a `.limit`-style metric or a fixed number),\n * both read live from the timeseries store. The centre shows the utilisation\n * percentage, with the value/max caption below; the arc colour crosses warning\n * and danger thresholds. An expand button opens the full value/max time-series\n * chart in a modal (a `TimeseriesPanel`), so the gauge gives the at-a-glance\n * reading and the chart the trend.\n */\nexport function TimeseriesGauge({\n baseUrl = \"\",\n value,\n max,\n title,\n icon,\n unit,\n range = \"1h\",\n refreshMs = 5000,\n expandable = true,\n thresholds = [75, 90],\n centerDisplay = \"value\",\n variant = \"default\",\n shape = \"radial\",\n showLabel = true,\n hoverCard = true,\n fetcher = defaultTimeseriesFetcher,\n className,\n}: TimeseriesGaugeProps) {\n const [expanded, setExpanded] = useState(false);\n\n const maxIsSeries = typeof max === \"object\";\n const maxSeries = maxIsSeries ? max : undefined;\n const results = useTimeseriesQueries(maxSeries ? [value, maxSeries] : [value], {\n baseUrl,\n range,\n refreshMs,\n fetcher,\n });\n\n const valueRead = soleSeries(value.id, results[0]);\n const maxRead = maxSeries ? soleSeries(maxSeries.id, results[1]) : undefined;\n const error = valueRead.error ?? maxRead?.error ?? null;\n const rawValue = latestValue(valueRead.data);\n const hasValue = rawValue !== undefined;\n const usage = value.transform ? value.transform(rawValue ?? 0) : (rawValue ?? 0);\n\n let limit: number | undefined;\n if (typeof max === \"number\") {\n limit = max;\n } else if (maxSeries) {\n const rawMax = latestValue(maxRead?.data);\n limit = rawMax === undefined ? undefined : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;\n }\n\n const bounded = hasValue && limit !== undefined && limit > 0;\n const pct = bounded ? Math.min(100, Math.round((usage / (limit as number)) * 100)) : 0;\n const tone = toneClass(pct, thresholds);\n const toneBg = toneBgClass(pct, thresholds);\n const readout =\n centerDisplay === \"percent\"\n ? bounded\n ? `${pct}%`\n : hasValue\n ? \"n/a\"\n : \"—\"\n : hasValue\n ? formatUnit(usage, unit)\n : \"—\";\n const titleText = `${title}: ${error ? error.message : readout}`;\n const canExpand = expandable && variant === \"default\";\n const readoutTone = bounded ? tone : \"text-foreground\";\n\n const chartSeries: TimeseriesSeries[] = useMemo(() => {\n const s: TimeseriesSeries[] = [{ ...value, label: \"value\" }];\n if (maxSeries) s.push({ ...maxSeries, label: \"max\" });\n return s;\n }, [value, maxSeries]);\n\n // Hover card: reduce the value's points to current/min/max/avg (transformed to\n // the display unit), plus the resolved capacity. The current row is tinted by\n // its threshold tone when the reading is bounded.\n const stats = seriesStats(valueRead.data?.points, value.transform);\n const fmt = (n: number) => formatUnit(n, unit);\n const hoverRows: GaugeHoverRow[] = error\n ? [{ label: \"Error\", value: error.message, tone: \"text-red-500\" }]\n : hasValue\n ? [\n { label: \"Current\", value: fmt(usage), ...(bounded ? { tone } : {}) },\n ...(stats\n ? [\n { label: \"Min\", value: fmt(stats.min) },\n { label: \"Max\", value: fmt(stats.max) },\n { label: \"Avg\", value: fmt(stats.avg) },\n ]\n : []),\n ...(limit !== undefined\n ? [{ label: \"Capacity\", value: fmt(limit) }]\n : []),\n ]\n : [];\n const useHover = hoverCard && hoverRows.length > 0;\n const footer = `over last ${range}`;\n\n if (variant === \"cell\") {\n const cell = (\n <span\n className={cn(\n \"inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap align-middle text-xs\",\n className,\n )}\n {...(useHover ? {} : { title: titleText })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span className=\"min-w-0 truncate text-muted-foreground\">{title}</span> : null}\n {shape === \"linear\" ? (\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-1.5 w-12 shrink-0\" />\n ) : (\n <span className=\"relative h-4 w-8 shrink-0\" aria-hidden=\"true\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={10} />\n </span>\n )}\n <span className={cn(\"shrink-0 font-semibold tabular-nums\", readoutTone)}>\n {readout}\n </span>\n </span>\n );\n return useHover ? (\n <GaugeHoverCard title={title} rows={hoverRows} footer={footer} trigger={cell} />\n ) : (\n cell\n );\n }\n\n const body = (\n <div\n className={cn(\"flex flex-col items-center gap-1\", className)}\n {...(useHover ? {} : { title: !showLabel ? titleText : undefined })}\n aria-label={useHover || !showLabel ? titleText : undefined}\n data-shape={shape}\n >\n {shape === \"linear\" ? (\n <div className=\"flex w-full items-center gap-2\">\n <GaugeBar pct={pct} toneBg={toneBg} className=\"h-2 w-full\" />\n <span className=\"shrink-0 text-sm font-semibold text-foreground\">{readout}</span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"shrink-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n ) : (\n <div className=\"relative h-10 w-20\">\n <GaugeArc pct={pct} tone={tone} strokeWidth={9} />\n <span className=\"absolute inset-x-0 bottom-0 text-center text-sm font-semibold text-foreground\">\n {readout}\n </span>\n {canExpand && (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"absolute right-0 top-0 text-muted-foreground hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={12} height={12} />\n </button>\n )}\n </div>\n )}\n {icon || showLabel ? (\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {icon ? <GaugeIcon icon={icon} /> : null}\n {showLabel ? <span>{title}</span> : null}\n </div>\n ) : null}\n </div>\n );\n\n return (\n <>\n {useHover ? (\n <GaugeHoverCard\n title={title}\n rows={hoverRows}\n footer={footer}\n trigger={body}\n className=\"w-full justify-center\"\n />\n ) : (\n body\n )}\n {canExpand && (\n <Modal open={expanded} onClose={() => setExpanded(false)} title={title} size=\"xl\">\n <TimeseriesPanel\n title={title}\n {...(icon ? { icon } : {})}\n {...(unit ? { unit } : {})}\n baseUrl={baseUrl}\n series={chartSeries}\n range={range}\n refreshMs={refreshMs}\n expandable={false}\n fetcher={fetcher}\n />\n </Modal>\n )}\n </>\n );\n}\n"],"mappings":"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"}
|
|
@@ -26,8 +26,8 @@ function TimeseriesPanel(props) {
|
|
|
26
26
|
const chartVariant = isBreakdown ? "area" : variant;
|
|
27
27
|
const expandVariant = props.expandVariant ?? chartVariant;
|
|
28
28
|
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
29
|
-
const
|
|
30
|
-
const results = require_timeseries_query.useTimeseriesQueries(
|
|
29
|
+
const requested = (0, react.useMemo)(() => require_TimeseriesPanel_model.resolveSeries(props), [props]);
|
|
30
|
+
const results = require_timeseries_query.useTimeseriesQueries(requested.map((s) => ({
|
|
31
31
|
id: s.key,
|
|
32
32
|
load: s.load
|
|
33
33
|
})), {
|
|
@@ -37,11 +37,12 @@ function TimeseriesPanel(props) {
|
|
|
37
37
|
fetcher
|
|
38
38
|
});
|
|
39
39
|
const refs = referenceLines ?? [];
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const isLoading = results.some((r) => r.isLoading) && results.every((r) => !r.
|
|
43
|
-
const
|
|
44
|
-
const
|
|
40
|
+
const error = results.find((r) => r.error)?.error ?? null;
|
|
41
|
+
const isError = error !== null;
|
|
42
|
+
const isLoading = results.some((r) => r.isLoading) && results.every((r) => !r.series);
|
|
43
|
+
const served = results.map((r) => r.series);
|
|
44
|
+
const { series, points } = (0, react.useMemo)(() => require_TimeseriesPanel_model.expandServedSeries(props, served), [props, served]);
|
|
45
|
+
const rows = (0, react.useMemo)(() => require_TimeseriesPanel_model.mergeSeries(series, points), [series, points]);
|
|
45
46
|
const hasMirrored = series.some((s) => s.transform);
|
|
46
47
|
const breakdown = (0, react.useMemo)(() => isBreakdown ? require_TimeseriesPanel_model.resolveBreakdown(series, rows, total) : null, [
|
|
47
48
|
isBreakdown,
|
|
@@ -86,11 +87,11 @@ function TimeseriesPanel(props) {
|
|
|
86
87
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
87
88
|
className: "mt-2",
|
|
88
89
|
style: breakdown ? void 0 : { height },
|
|
89
|
-
children: breakdown ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BreakdownView, {
|
|
90
|
+
children: error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelMessage, { children: error.message || "Failed to load metric" }) : breakdown ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BreakdownView, {
|
|
90
91
|
total: breakdown.total,
|
|
91
92
|
unit,
|
|
92
93
|
items: breakdown.items
|
|
93
|
-
}) :
|
|
94
|
+
}) : isLoading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelMessage, { children: "Loading…" }) : rows.length < 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelMessage, { children: "Collecting data…" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chart, {
|
|
94
95
|
rows,
|
|
95
96
|
series,
|
|
96
97
|
variant: chartVariant,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesPanel.cjs","names":["defaultTimeseriesFetcher","useState","useMemo","resolveSeries","useTimeseriesQueries","mergeSeries","resolveBreakdown","cn","Icon","UiFullscreen","Modal","latestOf","formatUnit","resolveCssColor","ProgressBar","assignAxes","_Fragment","CartesianGrid","XAxis","YAxis","Tooltip","ReferenceLine","ResponsiveContainer","LineChart","Line","AreaChart","Area"],"sources":["../../src/data/TimeseriesPanel.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport {\n Area,\n AreaChart,\n CartesianGrid,\n Line,\n LineChart,\n ReferenceLine,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { cn } from \"../lib/utils\";\nimport { resolveCssColor } from \"../lib/color\";\nimport { formatUnit } from \"../lib/format\";\nimport { Modal } from \"../overlay/Modal\";\nimport { ProgressBar, type ProgressSegment } from \"./ProgressBar\";\nimport { UiFullscreen } from \"../icons\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport { assignAxes, latestOf } from \"./TimeseriesPanel.axes\";\nimport {\n mergeSeries,\n resolveBreakdown,\n resolveSeries,\n type BreakdownItem,\n type MergedRow,\n type ResolvedSeries,\n type TimeseriesPanelProps,\n type TimeseriesReferenceLine,\n} from \"./TimeseriesPanel.model\";\nimport { defaultTimeseriesFetcher, useTimeseriesQueries } from \"./timeseries-query\";\n\nexport type { AxisAssignment, AxisOrientation, AxisSpec } from \"./TimeseriesPanel.axes\";\nexport type {\n BreakdownItem,\n MergedRow,\n ResolvedSeries,\n SeriesLoadContext,\n SeriesLoader,\n TimeseriesPanelProps,\n TimeseriesPoint,\n TimeseriesReferenceLine,\n TimeseriesResponse,\n TimeseriesSeries,\n} from \"./TimeseriesPanel.model\";\n\nfunction formatClock(at: string): string {\n const date = new Date(at);\n if (Number.isNaN(date.getTime())) return \"\";\n return date.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n}\n\nexport function TimeseriesPanel(props: TimeseriesPanelProps) {\n const {\n title,\n icon,\n unit,\n range = \"1h\",\n refreshMs = 5000,\n height = 160,\n variant = \"area\",\n expandable = true,\n total,\n referenceLines,\n fetcher = defaultTimeseriesFetcher,\n className,\n } = props;\n const isBreakdown = variant === \"breakdown\";\n // The inline chart (non-breakdown only) and the expand modal both need a\n // time-series variant; breakdown has no inline chart and expands to \"area\".\n const chartVariant: ChartVariant = isBreakdown ? \"area\" : variant;\n const expandVariant = props.expandVariant ?? chartVariant;\n\n const [expanded, setExpanded] = useState(false);\n\n const series = useMemo(() => resolveSeries(props), [props]);\n const results = useTimeseriesQueries(\n series.map((s) => ({ id: s.key, load: s.load })),\n { baseUrl: props.baseUrl ?? \"\", range, refreshMs, fetcher },\n );\n const refs = referenceLines ?? [];\n\n const isError = results.some((r) => r.isError);\n const error = results.find((r) => r.isError)?.error;\n const isLoading = results.some((r) => r.isLoading) && results.every((r) => !r.data);\n const pointsBySeries = results.map((r) => r.data?.points);\n const rows = useMemo(() => mergeSeries(series, pointsBySeries), [series, pointsBySeries]);\n const hasMirrored = series.some((s) => s.transform);\n const breakdown = useMemo(\n () => (isBreakdown ? resolveBreakdown(series, rows, total) : null),\n [isBreakdown, series, rows, total],\n );\n\n // Breakdown renders instantly from `current`; the modal still needs polled\n // history. Other variants gate on having ≥2 points to draw a line.\n const canExpand = expandable && rows.length >= 2;\n\n return (\n <div className={cn(\"flex flex-col rounded-lg border border-border bg-card p-3\", className)}>\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex min-w-0 items-center gap-1.5\">\n {icon ? <PanelIcon icon={icon} /> : null}\n <span className=\"truncate font-medium text-foreground\">{title}</span>\n </span>\n <span className=\"inline-flex shrink-0 items-center gap-1.5\">\n {breakdown ? (\n <BreakdownReadout total={breakdown.total} unit={unit} items={breakdown.items} />\n ) : (\n <LatestReadout series={series} rows={rows} />\n )}\n {canExpand ? (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={14} height={14} />\n </button>\n ) : null}\n </span>\n </div>\n <div className=\"mt-2\" style={breakdown ? undefined : { height }}>\n {breakdown ? (\n <BreakdownView total={breakdown.total} unit={unit} items={breakdown.items} />\n ) : isError ? (\n <PanelMessage>{(error as Error)?.message ?? \"Failed to load metric\"}</PanelMessage>\n ) : isLoading ? (\n <PanelMessage>Loading…</PanelMessage>\n ) : rows.length < 2 ? (\n <PanelMessage>Collecting data…</PanelMessage>\n ) : (\n <Chart\n rows={rows}\n series={series}\n variant={chartVariant}\n unit={unit}\n showZeroLine={hasMirrored}\n referenceLines={refs}\n />\n )}\n </div>\n {!breakdown && !isError && !isLoading && rows.length >= 2 && series.length + refs.length > 1 ? (\n <ChartLegend series={series} rows={rows} referenceLines={refs} unit={unit} />\n ) : null}\n {canExpand ? (\n <Modal open={expanded} onClose={() => setExpanded(false)} title={title} size=\"xl\">\n <div style={{ height: 360 }}>\n <Chart\n rows={rows}\n series={series}\n variant={expandVariant}\n unit={unit}\n showZeroLine={hasMirrored}\n referenceLines={refs}\n />\n </div>\n {series.length + refs.length > 1 ? (\n <ChartLegend series={series} rows={rows} referenceLines={refs} unit={unit} />\n ) : null}\n </Modal>\n ) : null}\n </div>\n );\n}\n\n/**\n * Header readout for a single-series panel: the latest value, formatted with the\n * series' unit. Multi-series panels render the per-series values in {@link ChartLegend}\n * below the chart instead, so this returns null for them to avoid overlapping the title.\n */\nfunction LatestReadout({ series, rows }: { series: ResolvedSeries[]; rows: MergedRow[] }) {\n const only = series.length === 1 ? series[0] : undefined;\n if (!only) return null;\n const v = latestOf(rows, only.key);\n if (v === undefined) return null;\n return <span className=\"tabular-nums\">{formatUnit(Math.abs(v), only.unit)}</span>;\n}\n\nconst REFERENCE_LINE_COLOR = \"var(--muted-foreground, #64748b)\";\n\nfunction referenceColor(ref: TimeseriesReferenceLine): string {\n return resolveCssColor(ref.color ?? REFERENCE_LINE_COLOR);\n}\n\n/**\n * Wrapping color-keyed legend for the time-series variants: dot + label + latest\n * value, then each reference line with its fixed value.\n */\nfunction ChartLegend({\n series,\n rows,\n referenceLines,\n unit,\n}: {\n series: ResolvedSeries[];\n rows: MergedRow[];\n referenceLines: TimeseriesReferenceLine[];\n unit: string | undefined;\n}) {\n return (\n <ul className=\"mt-1.5 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n {series.map((s) => {\n const v = latestOf(rows, s.key);\n return (\n <li key={s.key} className=\"inline-flex min-w-0 items-center gap-1.5\">\n <span\n className=\"h-2 w-2 shrink-0 rounded-full\"\n style={{ backgroundColor: resolveCssColor(s.color) }}\n aria-hidden\n />\n <span className=\"truncate text-foreground\">{s.label}</span>\n {v !== undefined ? (\n <span className=\"tabular-nums\">{formatUnit(Math.abs(v), s.unit)}</span>\n ) : null}\n </li>\n );\n })}\n {referenceLines.map((ref, i) => (\n <li key={`ref-${i}`} className=\"inline-flex min-w-0 items-center gap-1.5\">\n <span\n className=\"h-0.5 w-2.5 shrink-0\"\n style={{ backgroundColor: referenceColor(ref) }}\n aria-hidden\n />\n <span className=\"truncate text-foreground\">{ref.label}</span>\n <span className=\"tabular-nums\">{formatUnit(ref.value, ref.unit ?? unit)}</span>\n </li>\n ))}\n </ul>\n );\n}\n\n/** Breakdown header readout: `used / total · pct%`, where used is the sum of segments. */\nfunction BreakdownReadout({\n total,\n unit,\n items,\n}: {\n total: number;\n unit: string | undefined;\n items: BreakdownItem[];\n}) {\n const used = items.reduce((acc, it) => acc + it.value, 0);\n const pct = total > 0 ? Math.min(100, (used / total) * 100) : 0;\n return (\n <span className=\"font-mono tabular-nums\">\n {formatUnit(used, unit)} / {formatUnit(total, unit)} · {pct.toFixed(0)}%\n </span>\n );\n}\n\n/** Instantaneous stacked bar + legend list. The expand button (in the panel header) opens the graph. */\nfunction BreakdownView({\n total,\n unit,\n items,\n}: {\n total: number;\n unit: string | undefined;\n items: BreakdownItem[];\n}) {\n const segments: ProgressSegment[] = items.map((it) => ({\n count: it.value,\n color: it.color,\n label: it.label,\n }));\n return (\n <div className=\"flex flex-col gap-2\">\n <ProgressBar segments={segments} total={total > 0 ? total : 1} height=\"h-3\" />\n {items.length > 0 ? (\n <ul className=\"grid grid-cols-1 gap-y-1 text-xs\">\n {items.map((it) => (\n <li key={it.key} className=\"flex items-center gap-2\">\n <span\n className=\"h-2 w-2 shrink-0 rounded-full\"\n style={{ backgroundColor: resolveCssColor(it.color) }}\n aria-hidden\n />\n <span className=\"min-w-0 flex-1 truncate font-mono text-muted-foreground\">\n {it.label}\n </span>\n <span className=\"font-mono tabular-nums text-foreground\">\n {formatUnit(it.value, it.unit ?? unit)}\n </span>\n <span className=\"w-10 text-right font-mono tabular-nums text-muted-foreground\">\n {it.percent.toFixed(0)}%\n </span>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n );\n}\n\ntype ChartVariant = \"area\" | \"line\" | \"stacked\";\n\nfunction Chart({\n rows,\n series,\n variant,\n unit,\n showZeroLine,\n referenceLines,\n}: {\n rows: MergedRow[];\n series: ResolvedSeries[];\n variant: ChartVariant;\n unit: string | undefined;\n showZeroLine: boolean;\n referenceLines: TimeseriesReferenceLine[];\n}) {\n const stacked = variant === \"stacked\";\n // Mirrored series carry negative values; show magnitudes on axis and tooltip.\n const seriesByKey = new Map(series.map((s) => [s.key, s]));\n // recharts needs a CSS color value; a series may carry a Tailwind class.\n const strokeOf = (s: ResolvedSeries) => resolveCssColor(s.color);\n // Distinct units map to a left and (when present) right axis; each series draws\n // against the axis for its unit so mixed-unit panels keep independent scales.\n const { axes: yAxes, axisOfKey } = useMemo(() => assignAxes(series), [series]);\n const axisOf = (key: string): \"left\" | \"right\" => axisOfKey.get(key) ?? \"left\";\n // A reference line draws against the axis formatting its unit, else the left.\n const axisOfUnit = (u: string | undefined): \"left\" | \"right\" =>\n yAxes.find((ax) => ax.unit === u)?.id ?? \"left\";\n const axes = (\n <>\n <CartesianGrid strokeOpacity={0.12} vertical={false} />\n <XAxis\n dataKey=\"at\"\n tickFormatter={formatClock}\n tick={{ fontSize: 10 }}\n stroke=\"currentColor\"\n strokeOpacity={0.35}\n minTickGap={32}\n />\n {yAxes.map((ax) => (\n <YAxis\n key={ax.id}\n yAxisId={ax.id}\n orientation={ax.orientation}\n tick={{ fontSize: 10 }}\n stroke=\"currentColor\"\n strokeOpacity={0.35}\n width={40}\n tickFormatter={(v: number) => formatUnit(Math.abs(v), ax.unit)}\n />\n ))}\n <Tooltip\n labelFormatter={(label) => formatClock(String(label))}\n formatter={(value, name) => {\n const s = seriesByKey.get(String(name));\n return [formatUnit(Math.abs(Number(value) || 0), s?.unit ?? unit), s?.label ?? String(name)];\n }}\n contentStyle={{ fontSize: 12 }}\n />\n {showZeroLine ? (\n <ReferenceLine yAxisId=\"left\" y={0} stroke=\"currentColor\" strokeOpacity={0.35} />\n ) : null}\n {referenceLines.map((ref, i) => (\n <ReferenceLine\n key={`ref-${i}`}\n yAxisId={axisOfUnit(ref.unit ?? unit)}\n y={ref.value}\n stroke={referenceColor(ref)}\n strokeDasharray=\"4 4\"\n ifOverflow=\"extendDomain\"\n />\n ))}\n </>\n );\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {variant === \"line\" ? (\n <LineChart data={rows} margin={{ top: 4, right: 8, bottom: 0, left: 0 }}>\n {axes}\n {series.map((s) => (\n <Line\n key={s.key}\n yAxisId={axisOf(s.key)}\n type=\"monotone\"\n dataKey={s.key}\n name={s.key}\n stroke={strokeOf(s)}\n strokeWidth={2}\n dot={false}\n connectNulls\n isAnimationActive={false}\n />\n ))}\n </LineChart>\n ) : (\n <AreaChart data={rows} margin={{ top: 4, right: 8, bottom: 0, left: 0 }}>\n {axes}\n {series.map((s) => (\n <Area\n key={s.key}\n yAxisId={axisOf(s.key)}\n type=\"monotone\"\n dataKey={s.key}\n name={s.key}\n stroke={strokeOf(s)}\n fill={strokeOf(s)}\n {...(stacked ? { stackId: `stack-${axisOf(s.key)}` } : {})}\n fillOpacity={stacked ? 0.7 : 0.12}\n strokeWidth={stacked ? 0 : 2}\n connectNulls\n isAnimationActive={false}\n />\n ))}\n </AreaChart>\n )}\n </ResponsiveContainer>\n );\n}\n\nfunction PanelMessage({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"flex h-full items-center justify-center text-xs text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction PanelIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={16} height={16} className=\"text-muted-foreground\" />;\n }\n return <Icon icon={icon} width={16} height={16} className=\"text-muted-foreground\" />;\n}\n"],"mappings":";;;;;;;;;;;;;;AA+CA,SAAS,YAAY,IAAoB;CACvC,MAAM,OAAO,IAAI,KAAK,EAAE;CACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG,OAAO;CACzC,OAAO,KAAK,mBAAmB,CAAC,GAAG;EAAE,MAAM;EAAW,QAAQ;CAAU,CAAC;AAC3E;AAEA,SAAgB,gBAAgB,OAA6B;CAC3D,MAAM,EACJ,OACA,MACA,MACA,QAAQ,MACR,YAAY,KACZ,SAAS,KACT,UAAU,QACV,aAAa,MACb,OACA,gBACA,UAAUA,yBAAAA,0BACV,cACE;CACJ,MAAM,cAAc,YAAY;CAGhC,MAAM,eAA6B,cAAc,SAAS;CAC1D,MAAM,gBAAgB,MAAM,iBAAiB;CAE7C,MAAM,CAAC,UAAU,gBAAA,GAAeC,MAAAA,SAAAA,CAAS,KAAK;CAE9C,MAAM,UAAA,GAASC,MAAAA,QAAAA,OAAcC,8BAAAA,cAAc,KAAK,GAAG,CAAC,KAAK,CAAC;CAC1D,MAAM,UAAUC,yBAAAA,qBACd,OAAO,KAAK,OAAO;EAAE,IAAI,EAAE;EAAK,MAAM,EAAE;CAAK,EAAE,GAC/C;EAAE,SAAS,MAAM,WAAW;EAAI;EAAO;EAAW;CAAQ,CAC5D;CACA,MAAM,OAAO,kBAAkB,CAAC;CAEhC,MAAM,UAAU,QAAQ,MAAM,MAAM,EAAE,OAAO;CAC7C,MAAM,QAAQ,QAAQ,MAAM,MAAM,EAAE,OAAO,CAAC,EAAE;CAC9C,MAAM,YAAY,QAAQ,MAAM,MAAM,EAAE,SAAS,KAAK,QAAQ,OAAO,MAAM,CAAC,EAAE,IAAI;CAClF,MAAM,iBAAiB,QAAQ,KAAK,MAAM,EAAE,MAAM,MAAM;CACxD,MAAM,QAAA,GAAOF,MAAAA,QAAAA,OAAcG,8BAAAA,YAAY,QAAQ,cAAc,GAAG,CAAC,QAAQ,cAAc,CAAC;CACxF,MAAM,cAAc,OAAO,MAAM,MAAM,EAAE,SAAS;CAClD,MAAM,aAAA,GAAYH,MAAAA,QAAAA,OACT,cAAcI,8BAAAA,iBAAiB,QAAQ,MAAM,KAAK,IAAI,MAC7D;EAAC;EAAa;EAAQ;EAAM;CAAK,CACnC;CAIA,MAAM,YAAY,cAAc,KAAK,UAAU;CAE/C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWC,cAAAA,GAAG,6DAA6D,SAAS;EAAzF,UAAA;GACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACG,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,WAAD,EAAiB,KAAO,CAAA,IAAI,MACpC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAU;MAAwC,UAAA;KAAY,CAAA,CAChE;IACN,CAAA,GAAA,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CACG,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD;MAAkB,OAAO,UAAU;MAAa;MAAM,OAAO,UAAU;KAAQ,CAAA,IAE/E,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MAAuB;MAAc;KAAO,CAAA,GAE7C,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MACE,MAAK;MACL,cAAW;MACX,eAAe,YAAY,IAAI;MAC/B,WAAU;MAEV,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,MAAD;OAAM,MAAMC,qBAAAA;OAAc,OAAO;OAAI,QAAQ;MAAK,CAAA;KAC5C,CAAA,IACN,IACA;IACH,CAAA,CAAA;;GACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAU;IAAO,OAAO,YAAY,KAAA,IAAY,EAAE,OAAO;IAC3D,UAAA,YACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;KAAe,OAAO,UAAU;KAAa;KAAM,OAAO,UAAU;IAAQ,CAAA,IAC1E,UACF,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAA,UAAgB,OAAiB,WAAW,wBAAsC,CAAA,IAChF,YACF,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAA,UAAc,WAAsB,CAAA,IAClC,KAAK,SAAS,IAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD,EAAA,UAAc,mBAA8B,CAAA,IAE5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KACQ;KACE;KACR,SAAS;KACH;KACN,cAAc;KACd,gBAAgB;IACjB,CAAA;GAEA,CAAA;GACJ,CAAC,aAAa,CAAC,WAAW,CAAC,aAAa,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,SAAS,IACzF,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;IAAqB;IAAc;IAAM,gBAAgB;IAAY;GAAO,CAAA,IAC1E;GACH,YACC,iBAAA,GAAA,kBAAA,KAAA,CAACC,cAAAA,OAAD;IAAO,MAAM;IAAU,eAAe,YAAY,KAAK;IAAU;IAAO,MAAK;IAA7E,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,OAAO,EAAE,QAAQ,IAAI;KACxB,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MACQ;MACE;MACR,SAAS;MACH;MACN,cAAc;MACd,gBAAgB;KACjB,CAAA;IACE,CAAA,GACJ,OAAO,SAAS,KAAK,SAAS,IAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;KAAqB;KAAc;KAAM,gBAAgB;KAAY;IAAO,CAAA,IAC1E,IACC;GACL,CAAA,IAAA;EACD;;AAET;;;;;;AAOA,SAAS,cAAc,EAAE,QAAQ,QAAyD;CACxF,MAAM,OAAO,OAAO,WAAW,IAAI,OAAO,KAAK,KAAA;CAC/C,IAAI,CAAC,MAAM,OAAO;CAClB,MAAM,IAAIC,6BAAAA,SAAS,MAAM,KAAK,GAAG;CACjC,IAAI,MAAM,KAAA,GAAW,OAAO;CAC5B,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EAAM,WAAU;EAAgB,UAAAC,eAAAA,WAAW,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI;CAAQ,CAAA;AAClF;AAEA,IAAM,uBAAuB;AAE7B,SAAS,eAAe,KAAsC;CAC5D,OAAOC,cAAAA,gBAAgB,IAAI,SAAS,oBAAoB;AAC1D;;;;;AAMA,SAAS,YAAY,EACnB,QACA,MACA,gBACA,QAMC;CACD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;EAAI,WAAU;EAAd,UAAA,CACG,OAAO,KAAK,MAAM;GACjB,MAAM,IAAIF,6BAAAA,SAAS,MAAM,EAAE,GAAG;GAC9B,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAgB,WAAU;IAA1B,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MACE,WAAU;MACV,OAAO,EAAE,iBAAiBE,cAAAA,gBAAgB,EAAE,KAAK,EAAE;MACnD,eAAA;KACD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAU;MAA4B,UAAA,EAAE;KAAY,CAAA;KACzD,MAAM,KAAA,IACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAU;MAAgB,UAAAD,eAAAA,WAAW,KAAK,IAAI,CAAC,GAAG,EAAE,IAAI;KAAQ,CAAA,IACpE;IACF;GAVK,GAAA,EAAE,GAUP;EAER,CAAC,GACA,eAAe,KAAK,KAAK,MACxB,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;GAAqB,WAAU;GAA/B,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,WAAU;KACV,OAAO,EAAE,iBAAiB,eAAe,GAAG,EAAE;KAC9C,eAAA;IACD,CAAA;IACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KAA4B,UAAA,IAAI;IAAY,CAAA;IAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAU;KAAgB,UAAAA,eAAAA,WAAW,IAAI,OAAO,IAAI,QAAQ,IAAI;IAAQ,CAAA;GAC5E;EARK,GAAA,OAAO,GAQZ,CACL,CACC;;AAER;;AAGA,SAAS,iBAAiB,EACxB,OACA,MACA,SAKC;CACD,MAAM,OAAO,MAAM,QAAQ,KAAK,OAAO,MAAM,GAAG,OAAO,CAAC;CACxD,MAAM,MAAM,QAAQ,IAAI,KAAK,IAAI,KAAM,OAAO,QAAS,GAAG,IAAI;CAC9D,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;EAAM,WAAU;EAAhB,UAAA;GACGA,eAAAA,WAAW,MAAM,IAAI;GAAE;GAAIA,eAAAA,WAAW,OAAO,IAAI;GAAE;GAAI,IAAI,QAAQ,CAAC;GAAE;EACnE;;AAEV;;AAGA,SAAS,cAAc,EACrB,OACA,MACA,SAKC;CACD,MAAM,WAA8B,MAAM,KAAK,QAAQ;EACrD,OAAO,GAAG;EACV,OAAO,GAAG;EACV,OAAO,GAAG;CACZ,EAAE;CACF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACE,oBAAAA,aAAD;GAAuB;GAAU,OAAO,QAAQ,IAAI,QAAQ;GAAG,QAAO;EAAO,CAAA,GAC5E,MAAM,SAAS,IACd,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;GAAI,WAAU;GACX,UAAA,MAAM,KAAK,OACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAiB,WAAU;IAA3B,UAAA;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MACE,WAAU;MACV,OAAO,EAAE,iBAAiBD,cAAAA,gBAAgB,GAAG,KAAK,EAAE;MACpD,eAAA;KACD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAU;MACb,UAAA,GAAG;KACA,CAAA;KACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAU;MACb,UAAAD,eAAAA,WAAW,GAAG,OAAO,GAAG,QAAQ,IAAI;KACjC,CAAA;KACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAU;MAAhB,UAAA,CACG,GAAG,QAAQ,QAAQ,CAAC,GAAE,GACnB;;IACJ;GAfK,GAAA,GAAG,GAeR,CACL;EACC,CAAA,IACF,IACD;;AAET;AAIA,SAAS,MAAM,EACb,MACA,QACA,SACA,MACA,cACA,kBAQC;CACD,MAAM,UAAU,YAAY;CAE5B,MAAM,cAAc,IAAI,IAAI,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;CAEzD,MAAM,YAAY,MAAsBC,cAAAA,gBAAgB,EAAE,KAAK;CAG/D,MAAM,EAAE,MAAM,OAAO,eAAA,GAAcX,MAAAA,QAAAA,OAAca,6BAAAA,WAAW,MAAM,GAAG,CAAC,MAAM,CAAC;CAC7E,MAAM,UAAU,QAAkC,UAAU,IAAI,GAAG,KAAK;CAExE,MAAM,cAAc,MAClB,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,EAAE,MAAM;CAC3C,MAAM,OACJ,iBAAA,GAAA,kBAAA,KAAA,CAAAC,kBAAAA,UAAA,EAAA,UAAA;EACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,SAAAA,eAAD;GAAe,eAAe;GAAM,UAAU;EAAQ,CAAA;EACtD,iBAAA,GAAA,kBAAA,IAAA,CAACC,SAAAA,OAAD;GACE,SAAQ;GACR,eAAe;GACf,MAAM,EAAE,UAAU,GAAG;GACrB,QAAO;GACP,eAAe;GACf,YAAY;EACb,CAAA;EACA,MAAM,KAAK,OACV,iBAAA,GAAA,kBAAA,IAAA,CAACC,SAAAA,OAAD;GAEE,SAAS,GAAG;GACZ,aAAa,GAAG;GAChB,MAAM,EAAE,UAAU,GAAG;GACrB,QAAO;GACP,eAAe;GACf,OAAO;GACP,gBAAgB,MAAcP,eAAAA,WAAW,KAAK,IAAI,CAAC,GAAG,GAAG,IAAI;EAC9D,GARM,GAAG,EAQT,CACF;EACD,iBAAA,GAAA,kBAAA,IAAA,CAACQ,SAAAA,SAAD;GACE,iBAAiB,UAAU,YAAY,OAAO,KAAK,CAAC;GACpD,YAAY,OAAO,SAAS;IAC1B,MAAM,IAAI,YAAY,IAAI,OAAO,IAAI,CAAC;IACtC,OAAO,CAACR,eAAAA,WAAW,KAAK,IAAI,OAAO,KAAK,KAAK,CAAC,GAAG,GAAG,QAAQ,IAAI,GAAG,GAAG,SAAS,OAAO,IAAI,CAAC;GAC7F;GACA,cAAc,EAAE,UAAU,GAAG;EAC9B,CAAA;EACA,eACC,iBAAA,GAAA,kBAAA,IAAA,CAACS,SAAAA,eAAD;GAAe,SAAQ;GAAO,GAAG;GAAG,QAAO;GAAe,eAAe;EAAO,CAAA,IAC9E;EACH,eAAe,KAAK,KAAK,MACxB,iBAAA,GAAA,kBAAA,IAAA,CAACA,SAAAA,eAAD;GAEE,SAAS,WAAW,IAAI,QAAQ,IAAI;GACpC,GAAG,IAAI;GACP,QAAQ,eAAe,GAAG;GAC1B,iBAAgB;GAChB,YAAW;EACZ,GANM,OAAO,GAMb,CACF;CACD,EAAA,CAAA;CAGJ,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,SAAAA,qBAAD;EAAqB,OAAM;EAAO,QAAO;EACtC,UAAA,YAAY,SACX,iBAAA,GAAA,kBAAA,KAAA,CAACC,SAAAA,WAAD;GAAW,MAAM;GAAM,QAAQ;IAAE,KAAK;IAAG,OAAO;IAAG,QAAQ;IAAG,MAAM;GAAE;GAAtE,UAAA,CACG,MACA,OAAO,KAAK,MACX,iBAAA,GAAA,kBAAA,IAAA,CAACC,SAAAA,MAAD;IAEE,SAAS,OAAO,EAAE,GAAG;IACrB,MAAK;IACL,SAAS,EAAE;IACX,MAAM,EAAE;IACR,QAAQ,SAAS,CAAC;IAClB,aAAa;IACb,KAAK;IACL,cAAA;IACA,mBAAmB;GACpB,GAVM,EAAE,GAUR,CACF,CACQ;EAEX,CAAA,IAAA,iBAAA,GAAA,kBAAA,KAAA,CAACC,SAAAA,WAAD;GAAW,MAAM;GAAM,QAAQ;IAAE,KAAK;IAAG,OAAO;IAAG,QAAQ;IAAG,MAAM;GAAE;GAAtE,UAAA,CACG,MACA,OAAO,KAAK,MACX,iBAAA,GAAA,kBAAA,IAAA,CAACC,SAAAA,MAAD;IAEE,SAAS,OAAO,EAAE,GAAG;IACrB,MAAK;IACL,SAAS,EAAE;IACX,MAAM,EAAE;IACR,QAAQ,SAAS,CAAC;IAClB,MAAM,SAAS,CAAC;IAChB,GAAK,UAAU,EAAE,SAAS,SAAS,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC;IACxD,aAAa,UAAU,KAAM;IAC7B,aAAa,UAAU,IAAI;IAC3B,cAAA;IACA,mBAAmB;GACpB,GAZM,EAAE,GAYR,CACF,CACQ;;CAEM,CAAA;AAEzB;AAEA,SAAS,aAAa,EAAE,YAA2C;CACjE,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;EAAK,WAAU;EACZ;CACE,CAAA;AAET;AAEA,SAAS,UAAU,EAAE,QAAgD;CACnE,IAAI,OAAO,SAAS,UAClB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAClB,aAAAA,MAAD;EAAM,MAAM;EAAM,OAAO;EAAI,QAAQ;EAAI,WAAU;CAAyB,CAAA;CAErF,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAACA,aAAAA,MAAD;EAAY;EAAM,OAAO;EAAI,QAAQ;EAAI,WAAU;CAAyB,CAAA;AACrF"}
|
|
1
|
+
{"version":3,"file":"TimeseriesPanel.cjs","names":["defaultTimeseriesFetcher","useState","useMemo","resolveSeries","useTimeseriesQueries","expandServedSeries","mergeSeries","resolveBreakdown","cn","Icon","UiFullscreen","Modal","latestOf","formatUnit","resolveCssColor","ProgressBar","assignAxes","_Fragment","CartesianGrid","XAxis","YAxis","Tooltip","ReferenceLine","ResponsiveContainer","LineChart","Line","AreaChart","Area"],"sources":["../../src/data/TimeseriesPanel.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport {\n Area,\n AreaChart,\n CartesianGrid,\n Line,\n LineChart,\n ReferenceLine,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { cn } from \"../lib/utils\";\nimport { resolveCssColor } from \"../lib/color\";\nimport { formatUnit } from \"../lib/format\";\nimport { Modal } from \"../overlay/Modal\";\nimport { ProgressBar, type ProgressSegment } from \"./ProgressBar\";\nimport { UiFullscreen } from \"../icons\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport { assignAxes, latestOf } from \"./TimeseriesPanel.axes\";\nimport {\n expandServedSeries,\n mergeSeries,\n resolveBreakdown,\n resolveSeries,\n type BreakdownItem,\n type MergedRow,\n type ResolvedSeries,\n type TimeseriesPanelProps,\n type TimeseriesReferenceLine,\n} from \"./TimeseriesPanel.model\";\nimport { defaultTimeseriesFetcher, useTimeseriesQueries } from \"./timeseries-query\";\n\nexport type { AxisAssignment, AxisOrientation, AxisSpec } from \"./TimeseriesPanel.axes\";\nexport type {\n BreakdownItem,\n DisplaySeries,\n MergedRow,\n ResolvedSeries,\n SeriesLoadContext,\n SeriesLoader,\n TimeseriesPanelProps,\n TimeseriesPoint,\n TimeseriesReferenceLine,\n TimeseriesResponse,\n TimeseriesSeries,\n TimeseriesServerSeries,\n} from \"./TimeseriesPanel.model\";\n\nfunction formatClock(at: string): string {\n const date = new Date(at);\n if (Number.isNaN(date.getTime())) return \"\";\n return date.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n}\n\nexport function TimeseriesPanel(props: TimeseriesPanelProps) {\n const {\n title,\n icon,\n unit,\n range = \"1h\",\n refreshMs = 5000,\n height = 160,\n variant = \"area\",\n expandable = true,\n total,\n referenceLines,\n fetcher = defaultTimeseriesFetcher,\n className,\n } = props;\n const isBreakdown = variant === \"breakdown\";\n // The inline chart (non-breakdown only) and the expand modal both need a\n // time-series variant; breakdown has no inline chart and expands to \"area\".\n const chartVariant: ChartVariant = isBreakdown ? \"area\" : variant;\n const expandVariant = props.expandVariant ?? chartVariant;\n\n const [expanded, setExpanded] = useState(false);\n\n const requested = useMemo(() => resolveSeries(props), [props]);\n const results = useTimeseriesQueries(\n requested.map((s) => ({ id: s.key, load: s.load })),\n { baseUrl: props.baseUrl ?? \"\", range, refreshMs, fetcher },\n );\n const refs = referenceLines ?? [];\n\n const error = results.find((r) => r.error)?.error ?? null;\n const isError = error !== null;\n const isLoading = results.some((r) => r.isLoading) && results.every((r) => !r.series);\n const served = results.map((r) => r.series);\n const { series, points } = useMemo(() => expandServedSeries(props, served), [props, served]);\n const rows = useMemo(() => mergeSeries(series, points), [series, points]);\n const hasMirrored = series.some((s) => s.transform);\n const breakdown = useMemo(\n () => (isBreakdown ? resolveBreakdown(series, rows, total) : null),\n [isBreakdown, series, rows, total],\n );\n\n // Breakdown renders instantly from `current`; the modal still needs polled\n // history. Other variants gate on having ≥2 points to draw a line.\n const canExpand = expandable && rows.length >= 2;\n\n return (\n <div className={cn(\"flex flex-col rounded-lg border border-border bg-card p-3\", className)}>\n <div className=\"flex items-center justify-between gap-2 text-xs text-muted-foreground\">\n <span className=\"inline-flex min-w-0 items-center gap-1.5\">\n {icon ? <PanelIcon icon={icon} /> : null}\n <span className=\"truncate font-medium text-foreground\">{title}</span>\n </span>\n <span className=\"inline-flex shrink-0 items-center gap-1.5\">\n {breakdown ? (\n <BreakdownReadout total={breakdown.total} unit={unit} items={breakdown.items} />\n ) : (\n <LatestReadout series={series} rows={rows} />\n )}\n {canExpand ? (\n <button\n type=\"button\"\n aria-label=\"Expand chart\"\n onClick={() => setExpanded(true)}\n className=\"text-muted-foreground transition-colors hover:text-foreground\"\n >\n <Icon icon={UiFullscreen} width={14} height={14} />\n </button>\n ) : null}\n </span>\n </div>\n <div className=\"mt-2\" style={breakdown ? undefined : { height }}>\n {error ? (\n <PanelMessage>{error.message || \"Failed to load metric\"}</PanelMessage>\n ) : breakdown ? (\n <BreakdownView total={breakdown.total} unit={unit} items={breakdown.items} />\n ) : isLoading ? (\n <PanelMessage>Loading…</PanelMessage>\n ) : rows.length < 2 ? (\n <PanelMessage>Collecting data…</PanelMessage>\n ) : (\n <Chart\n rows={rows}\n series={series}\n variant={chartVariant}\n unit={unit}\n showZeroLine={hasMirrored}\n referenceLines={refs}\n />\n )}\n </div>\n {!breakdown && !isError && !isLoading && rows.length >= 2 && series.length + refs.length > 1 ? (\n <ChartLegend series={series} rows={rows} referenceLines={refs} unit={unit} />\n ) : null}\n {canExpand ? (\n <Modal open={expanded} onClose={() => setExpanded(false)} title={title} size=\"xl\">\n <div style={{ height: 360 }}>\n <Chart\n rows={rows}\n series={series}\n variant={expandVariant}\n unit={unit}\n showZeroLine={hasMirrored}\n referenceLines={refs}\n />\n </div>\n {series.length + refs.length > 1 ? (\n <ChartLegend series={series} rows={rows} referenceLines={refs} unit={unit} />\n ) : null}\n </Modal>\n ) : null}\n </div>\n );\n}\n\n/**\n * Header readout for a single-series panel: the latest value, formatted with the\n * series' unit. Multi-series panels render the per-series values in {@link ChartLegend}\n * below the chart instead, so this returns null for them to avoid overlapping the title.\n */\nfunction LatestReadout({ series, rows }: { series: ResolvedSeries[]; rows: MergedRow[] }) {\n const only = series.length === 1 ? series[0] : undefined;\n if (!only) return null;\n const v = latestOf(rows, only.key);\n if (v === undefined) return null;\n return <span className=\"tabular-nums\">{formatUnit(Math.abs(v), only.unit)}</span>;\n}\n\nconst REFERENCE_LINE_COLOR = \"var(--muted-foreground, #64748b)\";\n\nfunction referenceColor(ref: TimeseriesReferenceLine): string {\n return resolveCssColor(ref.color ?? REFERENCE_LINE_COLOR);\n}\n\n/**\n * Wrapping color-keyed legend for the time-series variants: dot + label + latest\n * value, then each reference line with its fixed value.\n */\nfunction ChartLegend({\n series,\n rows,\n referenceLines,\n unit,\n}: {\n series: ResolvedSeries[];\n rows: MergedRow[];\n referenceLines: TimeseriesReferenceLine[];\n unit: string | undefined;\n}) {\n return (\n <ul className=\"mt-1.5 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground\">\n {series.map((s) => {\n const v = latestOf(rows, s.key);\n return (\n <li key={s.key} className=\"inline-flex min-w-0 items-center gap-1.5\">\n <span\n className=\"h-2 w-2 shrink-0 rounded-full\"\n style={{ backgroundColor: resolveCssColor(s.color) }}\n aria-hidden\n />\n <span className=\"truncate text-foreground\">{s.label}</span>\n {v !== undefined ? (\n <span className=\"tabular-nums\">{formatUnit(Math.abs(v), s.unit)}</span>\n ) : null}\n </li>\n );\n })}\n {referenceLines.map((ref, i) => (\n <li key={`ref-${i}`} className=\"inline-flex min-w-0 items-center gap-1.5\">\n <span\n className=\"h-0.5 w-2.5 shrink-0\"\n style={{ backgroundColor: referenceColor(ref) }}\n aria-hidden\n />\n <span className=\"truncate text-foreground\">{ref.label}</span>\n <span className=\"tabular-nums\">{formatUnit(ref.value, ref.unit ?? unit)}</span>\n </li>\n ))}\n </ul>\n );\n}\n\n/** Breakdown header readout: `used / total · pct%`, where used is the sum of segments. */\nfunction BreakdownReadout({\n total,\n unit,\n items,\n}: {\n total: number;\n unit: string | undefined;\n items: BreakdownItem[];\n}) {\n const used = items.reduce((acc, it) => acc + it.value, 0);\n const pct = total > 0 ? Math.min(100, (used / total) * 100) : 0;\n return (\n <span className=\"font-mono tabular-nums\">\n {formatUnit(used, unit)} / {formatUnit(total, unit)} · {pct.toFixed(0)}%\n </span>\n );\n}\n\n/** Instantaneous stacked bar + legend list. The expand button (in the panel header) opens the graph. */\nfunction BreakdownView({\n total,\n unit,\n items,\n}: {\n total: number;\n unit: string | undefined;\n items: BreakdownItem[];\n}) {\n const segments: ProgressSegment[] = items.map((it) => ({\n count: it.value,\n color: it.color,\n label: it.label,\n }));\n return (\n <div className=\"flex flex-col gap-2\">\n <ProgressBar segments={segments} total={total > 0 ? total : 1} height=\"h-3\" />\n {items.length > 0 ? (\n <ul className=\"grid grid-cols-1 gap-y-1 text-xs\">\n {items.map((it) => (\n <li key={it.key} className=\"flex items-center gap-2\">\n <span\n className=\"h-2 w-2 shrink-0 rounded-full\"\n style={{ backgroundColor: resolveCssColor(it.color) }}\n aria-hidden\n />\n <span className=\"min-w-0 flex-1 truncate font-mono text-muted-foreground\">\n {it.label}\n </span>\n <span className=\"font-mono tabular-nums text-foreground\">\n {formatUnit(it.value, it.unit ?? unit)}\n </span>\n <span className=\"w-10 text-right font-mono tabular-nums text-muted-foreground\">\n {it.percent.toFixed(0)}%\n </span>\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n );\n}\n\ntype ChartVariant = \"area\" | \"line\" | \"stacked\";\n\nfunction Chart({\n rows,\n series,\n variant,\n unit,\n showZeroLine,\n referenceLines,\n}: {\n rows: MergedRow[];\n series: ResolvedSeries[];\n variant: ChartVariant;\n unit: string | undefined;\n showZeroLine: boolean;\n referenceLines: TimeseriesReferenceLine[];\n}) {\n const stacked = variant === \"stacked\";\n // Mirrored series carry negative values; show magnitudes on axis and tooltip.\n const seriesByKey = new Map(series.map((s) => [s.key, s]));\n // recharts needs a CSS color value; a series may carry a Tailwind class.\n const strokeOf = (s: ResolvedSeries) => resolveCssColor(s.color);\n // Distinct units map to a left and (when present) right axis; each series draws\n // against the axis for its unit so mixed-unit panels keep independent scales.\n const { axes: yAxes, axisOfKey } = useMemo(() => assignAxes(series), [series]);\n const axisOf = (key: string): \"left\" | \"right\" => axisOfKey.get(key) ?? \"left\";\n // A reference line draws against the axis formatting its unit, else the left.\n const axisOfUnit = (u: string | undefined): \"left\" | \"right\" =>\n yAxes.find((ax) => ax.unit === u)?.id ?? \"left\";\n const axes = (\n <>\n <CartesianGrid strokeOpacity={0.12} vertical={false} />\n <XAxis\n dataKey=\"at\"\n tickFormatter={formatClock}\n tick={{ fontSize: 10 }}\n stroke=\"currentColor\"\n strokeOpacity={0.35}\n minTickGap={32}\n />\n {yAxes.map((ax) => (\n <YAxis\n key={ax.id}\n yAxisId={ax.id}\n orientation={ax.orientation}\n tick={{ fontSize: 10 }}\n stroke=\"currentColor\"\n strokeOpacity={0.35}\n width={40}\n tickFormatter={(v: number) => formatUnit(Math.abs(v), ax.unit)}\n />\n ))}\n <Tooltip\n labelFormatter={(label) => formatClock(String(label))}\n formatter={(value, name) => {\n const s = seriesByKey.get(String(name));\n return [formatUnit(Math.abs(Number(value) || 0), s?.unit ?? unit), s?.label ?? String(name)];\n }}\n contentStyle={{ fontSize: 12 }}\n />\n {showZeroLine ? (\n <ReferenceLine yAxisId=\"left\" y={0} stroke=\"currentColor\" strokeOpacity={0.35} />\n ) : null}\n {referenceLines.map((ref, i) => (\n <ReferenceLine\n key={`ref-${i}`}\n yAxisId={axisOfUnit(ref.unit ?? unit)}\n y={ref.value}\n stroke={referenceColor(ref)}\n strokeDasharray=\"4 4\"\n ifOverflow=\"extendDomain\"\n />\n ))}\n </>\n );\n\n return (\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {variant === \"line\" ? (\n <LineChart data={rows} margin={{ top: 4, right: 8, bottom: 0, left: 0 }}>\n {axes}\n {series.map((s) => (\n <Line\n key={s.key}\n yAxisId={axisOf(s.key)}\n type=\"monotone\"\n dataKey={s.key}\n name={s.key}\n stroke={strokeOf(s)}\n strokeWidth={2}\n dot={false}\n connectNulls\n isAnimationActive={false}\n />\n ))}\n </LineChart>\n ) : (\n <AreaChart data={rows} margin={{ top: 4, right: 8, bottom: 0, left: 0 }}>\n {axes}\n {series.map((s) => (\n <Area\n key={s.key}\n yAxisId={axisOf(s.key)}\n type=\"monotone\"\n dataKey={s.key}\n name={s.key}\n stroke={strokeOf(s)}\n fill={strokeOf(s)}\n {...(stacked ? { stackId: `stack-${axisOf(s.key)}` } : {})}\n fillOpacity={stacked ? 0.7 : 0.12}\n strokeWidth={stacked ? 0 : 2}\n connectNulls\n isAnimationActive={false}\n />\n ))}\n </AreaChart>\n )}\n </ResponsiveContainer>\n );\n}\n\nfunction PanelMessage({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"flex h-full items-center justify-center text-xs text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction PanelIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return <Icon name={icon} width={16} height={16} className=\"text-muted-foreground\" />;\n }\n return <Icon icon={icon} width={16} height={16} className=\"text-muted-foreground\" />;\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TimeseriesPanelProps } from './TimeseriesPanel.model.js';
|
|
2
2
|
export type { AxisAssignment, AxisOrientation, AxisSpec } from './TimeseriesPanel.axes.js';
|
|
3
|
-
export type { BreakdownItem, MergedRow, ResolvedSeries, SeriesLoadContext, SeriesLoader, TimeseriesPanelProps, TimeseriesPoint, TimeseriesReferenceLine, TimeseriesResponse, TimeseriesSeries, } from './TimeseriesPanel.model.js';
|
|
3
|
+
export type { BreakdownItem, DisplaySeries, MergedRow, ResolvedSeries, SeriesLoadContext, SeriesLoader, TimeseriesPanelProps, TimeseriesPoint, TimeseriesReferenceLine, TimeseriesResponse, TimeseriesSeries, TimeseriesServerSeries, } from './TimeseriesPanel.model.js';
|
|
4
4
|
export declare function TimeseriesPanel(props: TimeseriesPanelProps): import("react").JSX.Element;
|
|
5
5
|
//# sourceMappingURL=TimeseriesPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesPanel.d.ts","sourceRoot":"","sources":["../../src/data/TimeseriesPanel.tsx"],"names":[],"mappings":"AAqBA,OAAO,
|
|
1
|
+
{"version":3,"file":"TimeseriesPanel.d.ts","sourceRoot":"","sources":["../../src/data/TimeseriesPanel.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAQL,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxF,YAAY,EACV,aAAa,EACb,aAAa,EACb,SAAS,EACT,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAQjC,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAiH1D"}
|
|
@@ -6,7 +6,7 @@ import { Modal } from "../overlay/Modal.js";
|
|
|
6
6
|
import { resolveCssColor } from "../lib/color.js";
|
|
7
7
|
import { ProgressBar } from "./ProgressBar.js";
|
|
8
8
|
import { assignAxes, latestOf } from "./TimeseriesPanel.axes.js";
|
|
9
|
-
import { mergeSeries, resolveBreakdown, resolveSeries } from "./TimeseriesPanel.model.js";
|
|
9
|
+
import { expandServedSeries, mergeSeries, resolveBreakdown, resolveSeries } from "./TimeseriesPanel.model.js";
|
|
10
10
|
import { defaultTimeseriesFetcher, useTimeseriesQueries } from "./timeseries-query.js";
|
|
11
11
|
import { useMemo, useState } from "react";
|
|
12
12
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -26,8 +26,8 @@ function TimeseriesPanel(props) {
|
|
|
26
26
|
const chartVariant = isBreakdown ? "area" : variant;
|
|
27
27
|
const expandVariant = props.expandVariant ?? chartVariant;
|
|
28
28
|
const [expanded, setExpanded] = useState(false);
|
|
29
|
-
const
|
|
30
|
-
const results = useTimeseriesQueries(
|
|
29
|
+
const requested = useMemo(() => resolveSeries(props), [props]);
|
|
30
|
+
const results = useTimeseriesQueries(requested.map((s) => ({
|
|
31
31
|
id: s.key,
|
|
32
32
|
load: s.load
|
|
33
33
|
})), {
|
|
@@ -37,11 +37,12 @@ function TimeseriesPanel(props) {
|
|
|
37
37
|
fetcher
|
|
38
38
|
});
|
|
39
39
|
const refs = referenceLines ?? [];
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const isLoading = results.some((r) => r.isLoading) && results.every((r) => !r.
|
|
43
|
-
const
|
|
44
|
-
const
|
|
40
|
+
const error = results.find((r) => r.error)?.error ?? null;
|
|
41
|
+
const isError = error !== null;
|
|
42
|
+
const isLoading = results.some((r) => r.isLoading) && results.every((r) => !r.series);
|
|
43
|
+
const served = results.map((r) => r.series);
|
|
44
|
+
const { series, points } = useMemo(() => expandServedSeries(props, served), [props, served]);
|
|
45
|
+
const rows = useMemo(() => mergeSeries(series, points), [series, points]);
|
|
45
46
|
const hasMirrored = series.some((s) => s.transform);
|
|
46
47
|
const breakdown = useMemo(() => isBreakdown ? resolveBreakdown(series, rows, total) : null, [
|
|
47
48
|
isBreakdown,
|
|
@@ -86,11 +87,11 @@ function TimeseriesPanel(props) {
|
|
|
86
87
|
/* @__PURE__ */ jsx("div", {
|
|
87
88
|
className: "mt-2",
|
|
88
89
|
style: breakdown ? void 0 : { height },
|
|
89
|
-
children: breakdown ? /* @__PURE__ */ jsx(BreakdownView, {
|
|
90
|
+
children: error ? /* @__PURE__ */ jsx(PanelMessage, { children: error.message || "Failed to load metric" }) : breakdown ? /* @__PURE__ */ jsx(BreakdownView, {
|
|
90
91
|
total: breakdown.total,
|
|
91
92
|
unit,
|
|
92
93
|
items: breakdown.items
|
|
93
|
-
}) :
|
|
94
|
+
}) : isLoading ? /* @__PURE__ */ jsx(PanelMessage, { children: "Loading…" }) : rows.length < 2 ? /* @__PURE__ */ jsx(PanelMessage, { children: "Collecting data…" }) : /* @__PURE__ */ jsx(Chart, {
|
|
94
95
|
rows,
|
|
95
96
|
series,
|
|
96
97
|
variant: chartVariant,
|