@flanksource/clicky-ui 0.3.1 → 0.3.3
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/dist/comments/CommentAuthor.cjs +58 -0
- package/dist/comments/CommentAuthor.cjs.map +1 -0
- package/dist/comments/CommentAuthor.d.ts +17 -0
- package/dist/comments/CommentAuthor.d.ts.map +1 -0
- package/dist/comments/CommentAuthor.js +58 -0
- package/dist/comments/CommentAuthor.js.map +1 -0
- package/dist/comments/CommentCard.cjs +343 -0
- package/dist/comments/CommentCard.cjs.map +1 -0
- package/dist/comments/CommentCard.d.ts +27 -0
- package/dist/comments/CommentCard.d.ts.map +1 -0
- package/dist/comments/CommentCard.js +343 -0
- package/dist/comments/CommentCard.js.map +1 -0
- package/dist/comments/CommentComposer.cjs +207 -0
- package/dist/comments/CommentComposer.cjs.map +1 -0
- package/dist/comments/CommentComposer.d.ts +23 -0
- package/dist/comments/CommentComposer.d.ts.map +1 -0
- package/dist/comments/CommentComposer.js +207 -0
- package/dist/comments/CommentComposer.js.map +1 -0
- package/dist/comments/CommentFilterBar.cjs +145 -0
- package/dist/comments/CommentFilterBar.cjs.map +1 -0
- package/dist/comments/CommentFilterBar.d.ts +15 -0
- package/dist/comments/CommentFilterBar.d.ts.map +1 -0
- package/dist/comments/CommentFilterBar.js +145 -0
- package/dist/comments/CommentFilterBar.js.map +1 -0
- package/dist/comments/CommentMarkdown.cjs +156 -0
- package/dist/comments/CommentMarkdown.cjs.map +1 -0
- package/dist/comments/CommentMarkdown.d.ts +13 -0
- package/dist/comments/CommentMarkdown.d.ts.map +1 -0
- package/dist/comments/CommentMarkdown.js +156 -0
- package/dist/comments/CommentMarkdown.js.map +1 -0
- package/dist/comments/CommentProgress.cjs +86 -0
- package/dist/comments/CommentProgress.cjs.map +1 -0
- package/dist/comments/CommentProgress.d.ts +16 -0
- package/dist/comments/CommentProgress.d.ts.map +1 -0
- package/dist/comments/CommentProgress.js +86 -0
- package/dist/comments/CommentProgress.js.map +1 -0
- package/dist/comments/CommentProvider.cjs +99 -0
- package/dist/comments/CommentProvider.cjs.map +1 -0
- package/dist/comments/CommentProvider.d.ts +19 -0
- package/dist/comments/CommentProvider.d.ts.map +1 -0
- package/dist/comments/CommentProvider.js +99 -0
- package/dist/comments/CommentProvider.js.map +1 -0
- package/dist/comments/CommentSidePanel.cjs +219 -0
- package/dist/comments/CommentSidePanel.cjs.map +1 -0
- package/dist/comments/CommentSidePanel.d.ts +16 -0
- package/dist/comments/CommentSidePanel.d.ts.map +1 -0
- package/dist/comments/CommentSidePanel.js +219 -0
- package/dist/comments/CommentSidePanel.js.map +1 -0
- package/dist/comments/CommentThread.cjs +57 -0
- package/dist/comments/CommentThread.cjs.map +1 -0
- package/dist/comments/CommentThread.d.ts +24 -0
- package/dist/comments/CommentThread.d.ts.map +1 -0
- package/dist/comments/CommentThread.js +57 -0
- package/dist/comments/CommentThread.js.map +1 -0
- package/dist/comments/CommentThreadList.cjs +124 -0
- package/dist/comments/CommentThreadList.cjs.map +1 -0
- package/dist/comments/CommentThreadList.d.ts +25 -0
- package/dist/comments/CommentThreadList.d.ts.map +1 -0
- package/dist/comments/CommentThreadList.js +124 -0
- package/dist/comments/CommentThreadList.js.map +1 -0
- package/dist/comments/GroupedComments.cjs +74 -0
- package/dist/comments/GroupedComments.cjs.map +1 -0
- package/dist/comments/GroupedComments.d.ts +18 -0
- package/dist/comments/GroupedComments.d.ts.map +1 -0
- package/dist/comments/GroupedComments.js +74 -0
- package/dist/comments/GroupedComments.js.map +1 -0
- package/dist/comments/MentionTextarea.cjs +253 -0
- package/dist/comments/MentionTextarea.cjs.map +1 -0
- package/dist/comments/MentionTextarea.d.ts +28 -0
- package/dist/comments/MentionTextarea.d.ts.map +1 -0
- package/dist/comments/MentionTextarea.js +253 -0
- package/dist/comments/MentionTextarea.js.map +1 -0
- package/dist/comments/comment-context.cjs +33 -0
- package/dist/comments/comment-context.cjs.map +1 -0
- package/dist/comments/comment-context.d.ts +32 -0
- package/dist/comments/comment-context.d.ts.map +1 -0
- package/dist/comments/comment-context.js +33 -0
- package/dist/comments/comment-context.js.map +1 -0
- package/dist/comments/comment-fixtures.d.ts +11 -0
- package/dist/comments/comment-fixtures.d.ts.map +1 -0
- package/dist/comments/comment-types.cjs +19 -0
- package/dist/comments/comment-types.cjs.map +1 -0
- package/dist/comments/comment-types.d.ts +170 -0
- package/dist/comments/comment-types.d.ts.map +1 -0
- package/dist/comments/comment-types.js +19 -0
- package/dist/comments/comment-types.js.map +1 -0
- package/dist/comments/comment-utils.cjs +216 -0
- package/dist/comments/comment-utils.cjs.map +1 -0
- package/dist/comments/comment-utils.d.ts +59 -0
- package/dist/comments/comment-utils.d.ts.map +1 -0
- package/dist/comments/comment-utils.js +216 -0
- package/dist/comments/comment-utils.js.map +1 -0
- package/dist/comments.cjs +57 -0
- package/dist/comments.cjs.map +1 -0
- package/dist/comments.d.ts +16 -0
- package/dist/comments.d.ts.map +1 -0
- package/dist/comments.js +57 -0
- package/dist/comments.js.map +1 -0
- package/dist/components/FilterBar.cjs +13 -3
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.js +13 -3
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +20 -6
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +22 -8
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/NamespacePicker.cjs +52 -0
- package/dist/components/NamespacePicker.cjs.map +1 -0
- package/dist/components/NamespacePicker.d.ts +17 -0
- package/dist/components/NamespacePicker.d.ts.map +1 -0
- package/dist/components/NamespacePicker.js +52 -0
- package/dist/components/NamespacePicker.js.map +1 -0
- package/dist/components/form-lookup-context.cjs +36 -0
- package/dist/components/form-lookup-context.cjs.map +1 -0
- package/dist/components/form-lookup-context.d.ts +9 -0
- package/dist/components/form-lookup-context.d.ts.map +1 -0
- package/dist/components/form-lookup-context.js +36 -0
- package/dist/components/form-lookup-context.js.map +1 -0
- package/dist/components/json-schema-form-discriminator.cjs +67 -0
- package/dist/components/json-schema-form-discriminator.cjs.map +1 -0
- package/dist/components/json-schema-form-discriminator.d.ts +10 -0
- package/dist/components/json-schema-form-discriminator.d.ts.map +1 -0
- package/dist/components/json-schema-form-discriminator.js +67 -0
- package/dist/components/json-schema-form-discriminator.js.map +1 -0
- package/dist/components/json-schema-form-fields.cjs +66 -1
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts +7 -0
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +66 -1
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-grid.cjs +92 -0
- package/dist/components/json-schema-form-grid.cjs.map +1 -0
- package/dist/components/json-schema-form-grid.d.ts +9 -0
- package/dist/components/json-schema-form-grid.d.ts.map +1 -0
- package/dist/components/json-schema-form-grid.js +92 -0
- package/dist/components/json-schema-form-grid.js.map +1 -0
- package/dist/components/json-schema-form-render.cjs +20 -3
- 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 +22 -5
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +24 -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 +24 -2
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +37 -2
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.cjs +8 -0
- package/dist/components/json-schema-form-utils.cjs.map +1 -1
- package/dist/components/json-schema-form-utils.d.ts +1 -0
- package/dist/components/json-schema-form-utils.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.js +8 -0
- package/dist/components/json-schema-form-utils.js.map +1 -1
- package/dist/components/workload-picker-utils.cjs.map +1 -1
- package/dist/components/workload-picker-utils.d.ts +11 -1
- package/dist/components/workload-picker-utils.d.ts.map +1 -1
- package/dist/components/workload-picker-utils.js.map +1 -1
- package/dist/components.cjs +6 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +4 -2
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +6 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +225 -60
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts +7 -1
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.fixtures.d.ts +3 -1
- package/dist/data/Clicky.fixtures.d.ts.map +1 -1
- package/dist/data/Clicky.js +226 -61
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/ExecutionTree.cjs +68 -0
- package/dist/data/ExecutionTree.cjs.map +1 -0
- package/dist/data/ExecutionTree.d.ts +40 -0
- package/dist/data/ExecutionTree.d.ts.map +1 -0
- package/dist/data/ExecutionTree.js +68 -0
- package/dist/data/ExecutionTree.js.map +1 -0
- package/dist/data/GaugeHoverCard.cjs +35 -0
- package/dist/data/GaugeHoverCard.cjs.map +1 -0
- package/dist/data/GaugeHoverCard.d.ts +25 -0
- package/dist/data/GaugeHoverCard.d.ts.map +1 -0
- package/dist/data/GaugeHoverCard.js +35 -0
- package/dist/data/GaugeHoverCard.js.map +1 -0
- package/dist/data/MarkdownEditor.cjs +616 -0
- package/dist/data/MarkdownEditor.cjs.map +1 -0
- package/dist/data/MarkdownEditor.d.ts +61 -0
- package/dist/data/MarkdownEditor.d.ts.map +1 -0
- package/dist/data/MarkdownEditor.js +616 -0
- package/dist/data/MarkdownEditor.js.map +1 -0
- package/dist/data/MarkdownEditor.model.cjs +27 -0
- package/dist/data/MarkdownEditor.model.cjs.map +1 -0
- package/dist/data/MarkdownEditor.model.d.ts +38 -0
- package/dist/data/MarkdownEditor.model.d.ts.map +1 -0
- package/dist/data/MarkdownEditor.model.js +27 -0
- package/dist/data/MarkdownEditor.model.js.map +1 -0
- package/dist/data/ObjectGraph.cjs +44 -0
- package/dist/data/ObjectGraph.cjs.map +1 -0
- package/dist/data/ObjectGraph.d.ts +39 -0
- package/dist/data/ObjectGraph.d.ts.map +1 -0
- package/dist/data/ObjectGraph.js +44 -0
- package/dist/data/ObjectGraph.js.map +1 -0
- package/dist/data/SchemaViewer.cjs +152 -0
- package/dist/data/SchemaViewer.cjs.map +1 -0
- package/dist/data/SchemaViewer.d.ts +27 -0
- package/dist/data/SchemaViewer.d.ts.map +1 -0
- package/dist/data/SchemaViewer.js +152 -0
- package/dist/data/SchemaViewer.js.map +1 -0
- package/dist/data/TimeseriesCoreBars.cjs +51 -12
- package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.d.ts +32 -5
- package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.js +51 -12
- package/dist/data/TimeseriesCoreBars.js.map +1 -1
- package/dist/data/TimeseriesCoreBars.model.cjs +5 -5
- package/dist/data/TimeseriesCoreBars.model.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.model.d.ts +4 -4
- package/dist/data/TimeseriesCoreBars.model.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.model.js +5 -5
- package/dist/data/TimeseriesCoreBars.model.js.map +1 -1
- package/dist/data/TimeseriesGauge.cjs +103 -65
- package/dist/data/TimeseriesGauge.cjs.map +1 -1
- package/dist/data/TimeseriesGauge.d.ts +10 -1
- package/dist/data/TimeseriesGauge.d.ts.map +1 -1
- package/dist/data/TimeseriesGauge.js +104 -66
- package/dist/data/TimeseriesGauge.js.map +1 -1
- package/dist/data/WorkloadCard.cjs +4 -4
- package/dist/data/WorkloadCard.cjs.map +1 -1
- package/dist/data/WorkloadCard.d.ts +3 -2
- package/dist/data/WorkloadCard.d.ts.map +1 -1
- package/dist/data/WorkloadCard.js +4 -4
- package/dist/data/WorkloadCard.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +11 -19
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +1 -7
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +11 -19
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindowRequestBody.cjs +20 -0
- package/dist/data/ai/ChatWindowRequestBody.cjs.map +1 -0
- package/dist/data/ai/ChatWindowRequestBody.d.ts +9 -0
- package/dist/data/ai/ChatWindowRequestBody.d.ts.map +1 -0
- package/dist/data/ai/ChatWindowRequestBody.js +20 -0
- package/dist/data/ai/ChatWindowRequestBody.js.map +1 -0
- package/dist/data/chat/Chat.cjs +12 -0
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts +8 -1
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.js +12 -0
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/gauge-stats.cjs +19 -0
- package/dist/data/gauge-stats.cjs.map +1 -0
- package/dist/data/gauge-stats.d.ts +15 -0
- package/dist/data/gauge-stats.d.ts.map +1 -0
- package/dist/data/gauge-stats.js +19 -0
- package/dist/data/gauge-stats.js.map +1 -0
- package/dist/data/schema-viewer-model.cjs +436 -0
- package/dist/data/schema-viewer-model.cjs.map +1 -0
- package/dist/data/schema-viewer-model.d.ts +64 -0
- package/dist/data/schema-viewer-model.d.ts.map +1 -0
- package/dist/data/schema-viewer-model.js +436 -0
- package/dist/data/schema-viewer-model.js.map +1 -0
- package/dist/data/version-info.cjs +2 -2
- package/dist/data/version-info.js +2 -2
- package/dist/data.cjs +23 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +11 -3
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +23 -0
- package/dist/data.js.map +1 -1
- package/dist/index.cjs +87 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +87 -2
- package/dist/index.js.map +1 -1
- package/dist/rpc/EntityExplorerApp.cjs +102 -143
- package/dist/rpc/EntityExplorerApp.cjs.map +1 -1
- package/dist/rpc/EntityExplorerApp.d.ts +34 -1
- package/dist/rpc/EntityExplorerApp.d.ts.map +1 -1
- package/dist/rpc/EntityExplorerApp.js +105 -146
- package/dist/rpc/EntityExplorerApp.js.map +1 -1
- package/dist/rpc/OperationActionBar.cjs +135 -0
- package/dist/rpc/OperationActionBar.cjs.map +1 -0
- package/dist/rpc/OperationActionBar.d.ts +20 -0
- package/dist/rpc/OperationActionBar.d.ts.map +1 -0
- package/dist/rpc/OperationActionBar.js +135 -0
- package/dist/rpc/OperationActionBar.js.map +1 -0
- package/dist/rpc/OperationCatalog.cjs +79 -116
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +8 -1
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +80 -117
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs +134 -223
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js +135 -224
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/OperationEntityPage.cjs +49 -100
- package/dist/rpc/OperationEntityPage.cjs.map +1 -1
- package/dist/rpc/OperationEntityPage.d.ts +6 -1
- package/dist/rpc/OperationEntityPage.d.ts.map +1 -1
- package/dist/rpc/OperationEntityPage.js +50 -101
- package/dist/rpc/OperationEntityPage.js.map +1 -1
- package/dist/rpc/OperationResultView.cjs +43 -0
- package/dist/rpc/OperationResultView.cjs.map +1 -0
- package/dist/rpc/OperationResultView.d.ts +30 -0
- package/dist/rpc/OperationResultView.d.ts.map +1 -0
- package/dist/rpc/OperationResultView.js +43 -0
- package/dist/rpc/OperationResultView.js.map +1 -0
- package/dist/rpc/SchemaActionForm.cjs +102 -0
- package/dist/rpc/SchemaActionForm.cjs.map +1 -0
- package/dist/rpc/SchemaActionForm.d.ts +23 -0
- package/dist/rpc/SchemaActionForm.d.ts.map +1 -0
- package/dist/rpc/SchemaActionForm.js +102 -0
- package/dist/rpc/SchemaActionForm.js.map +1 -0
- package/dist/rpc/accept-options.cjs.map +1 -1
- package/dist/rpc/accept-options.d.ts +0 -1
- package/dist/rpc/accept-options.d.ts.map +1 -1
- package/dist/rpc/accept-options.js.map +1 -1
- package/dist/rpc/apiClient.cjs +34 -2
- package/dist/rpc/apiClient.cjs.map +1 -1
- package/dist/rpc/apiClient.d.ts +4 -1
- package/dist/rpc/apiClient.d.ts.map +1 -1
- package/dist/rpc/apiClient.js +34 -2
- package/dist/rpc/apiClient.js.map +1 -1
- package/dist/rpc/clickyMetadata.cjs +4 -4
- package/dist/rpc/clickyMetadata.cjs.map +1 -1
- package/dist/rpc/clickyMetadata.d.ts +0 -1
- package/dist/rpc/clickyMetadata.d.ts.map +1 -1
- package/dist/rpc/clickyMetadata.js +4 -4
- package/dist/rpc/clickyMetadata.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +1 -0
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts +6 -1
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +1 -0
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc/rowNavigation.cjs +86 -0
- package/dist/rpc/rowNavigation.cjs.map +1 -0
- package/dist/rpc/rowNavigation.d.ts +14 -0
- package/dist/rpc/rowNavigation.d.ts.map +1 -0
- package/dist/rpc/rowNavigation.js +86 -0
- package/dist/rpc/rowNavigation.js.map +1 -0
- package/dist/rpc/schemaActionPath.cjs +22 -0
- package/dist/rpc/schemaActionPath.cjs.map +1 -0
- package/dist/rpc/schemaActionPath.d.ts +4 -0
- package/dist/rpc/schemaActionPath.d.ts.map +1 -0
- package/dist/rpc/schemaActionPath.js +22 -0
- package/dist/rpc/schemaActionPath.js.map +1 -0
- package/dist/rpc/surfaceIconMap.cjs +35 -0
- package/dist/rpc/surfaceIconMap.cjs.map +1 -0
- package/dist/rpc/surfaceIconMap.d.ts +3 -0
- package/dist/rpc/surfaceIconMap.d.ts.map +1 -0
- package/dist/rpc/surfaceIconMap.js +35 -0
- package/dist/rpc/surfaceIconMap.js.map +1 -0
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +2 -0
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/rpc/useOperations.cjs.map +1 -1
- package/dist/rpc/useOperations.d.ts +4 -1
- package/dist/rpc/useOperations.d.ts.map +1 -1
- package/dist/rpc/useOperations.js.map +1 -1
- package/dist/rpc.cjs +4 -2
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +7 -6
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +4 -2
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
- package/dist/rpc/AcceptPicker.cjs +0 -137
- package/dist/rpc/AcceptPicker.cjs.map +0 -1
- package/dist/rpc/AcceptPicker.d.ts +0 -12
- package/dist/rpc/AcceptPicker.d.ts.map +0 -1
- package/dist/rpc/AcceptPicker.js +0 -137
- package/dist/rpc/AcceptPicker.js.map +0 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { rehydrateRefs } from "../components/json-schema-form-refs.js";
|
|
4
|
+
import { cn } from "../lib/utils.js";
|
|
5
|
+
import { CodeBlock } from "./CodeBlock.js";
|
|
6
|
+
import { Tree } from "./Tree.js";
|
|
7
|
+
import { buildSchemaTree } from "./schema-viewer-model.js";
|
|
8
|
+
function isDetailOnly(node) {
|
|
9
|
+
var _a;
|
|
10
|
+
const [child] = node.children ?? [];
|
|
11
|
+
return ((_a = node.children) == null ? void 0 : _a.length) === 1 && Boolean(child == null ? void 0 : child.detail);
|
|
12
|
+
}
|
|
13
|
+
function SchemaViewer({
|
|
14
|
+
schema,
|
|
15
|
+
roots: scopedRoots,
|
|
16
|
+
buildTree = buildSchemaTree,
|
|
17
|
+
className,
|
|
18
|
+
empty = /* @__PURE__ */ jsx("p", { className: "p-3 text-sm text-muted-foreground", children: "This schema has no fields." }),
|
|
19
|
+
showControls,
|
|
20
|
+
toolbarClassName,
|
|
21
|
+
defaultOpenDepth = 1,
|
|
22
|
+
renderDetail
|
|
23
|
+
}) {
|
|
24
|
+
const roots = useMemo(
|
|
25
|
+
() => scopedRoots ?? buildTree(rehydrateRefs(schema)),
|
|
26
|
+
[buildTree, scopedRoots, schema]
|
|
27
|
+
);
|
|
28
|
+
return /* @__PURE__ */ jsx(
|
|
29
|
+
Tree,
|
|
30
|
+
{
|
|
31
|
+
className: cn("text-sm", className),
|
|
32
|
+
roots,
|
|
33
|
+
getKey: (node) => node.key,
|
|
34
|
+
getChildren: (node) => node.children,
|
|
35
|
+
isSecondary: (node) => Boolean(node.detail),
|
|
36
|
+
getSearchText: (node) => node.detail ? "" : `${node.label} ${node.badge ?? ""} ${node.platformType ?? ""} ${node.ascode ?? ""}`,
|
|
37
|
+
defaultOpen: (node, depth) => depth < defaultOpenDepth && !isDetailOnly(node),
|
|
38
|
+
rowClass: (node, selected) => node.detail ? "cursor-default" : selected ? "bg-primary/10 border-l-2 border-primary" : "hover:bg-accent",
|
|
39
|
+
renderRow: ({ node }) => node.detail ? /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: renderDetail ? renderDetail(node.detail) : /* @__PURE__ */ jsx(SchemaFieldMetaPanel, { meta: node.detail }) }) : /* @__PURE__ */ jsx(SchemaViewerRow, { node }),
|
|
40
|
+
empty,
|
|
41
|
+
...showControls !== void 0 ? { showControls } : {},
|
|
42
|
+
...toolbarClassName !== void 0 ? { toolbarClassName } : {}
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
const BADGE_TONE = {
|
|
47
|
+
branch: "bg-violet-100 text-violet-700 dark:bg-violet-950/50 dark:text-violet-200",
|
|
48
|
+
group: "bg-violet-100 text-violet-700 dark:bg-violet-950/50 dark:text-violet-200",
|
|
49
|
+
activity: "bg-emerald-100 text-emerald-700 dark:bg-emerald-950/50 dark:text-emerald-200",
|
|
50
|
+
clientType: "bg-sky-100 text-sky-700 dark:bg-sky-950/50 dark:text-sky-200",
|
|
51
|
+
clientTypes: "bg-sky-100 text-sky-700 dark:bg-sky-950/50 dark:text-sky-200",
|
|
52
|
+
fields: "bg-amber-100 text-amber-700 dark:bg-amber-950/50 dark:text-amber-200",
|
|
53
|
+
object: "bg-muted text-muted-foreground",
|
|
54
|
+
array: "bg-muted text-muted-foreground",
|
|
55
|
+
string: "bg-muted text-muted-foreground",
|
|
56
|
+
number: "bg-muted text-muted-foreground",
|
|
57
|
+
integer: "bg-muted text-muted-foreground",
|
|
58
|
+
boolean: "bg-muted text-muted-foreground",
|
|
59
|
+
const: "bg-muted text-muted-foreground"
|
|
60
|
+
};
|
|
61
|
+
function SchemaViewerRow({ node }) {
|
|
62
|
+
const tone = node.badge ? BADGE_TONE[node.badge] : void 0;
|
|
63
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex w-full min-w-0 items-center gap-2", children: [
|
|
64
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate font-mono", children: node.label }),
|
|
65
|
+
node.badge && /* @__PURE__ */ jsx(
|
|
66
|
+
"span",
|
|
67
|
+
{
|
|
68
|
+
className: cn(
|
|
69
|
+
"shrink-0 rounded px-1.5 py-0.5 text-[10px] font-medium",
|
|
70
|
+
tone ?? "bg-muted text-muted-foreground"
|
|
71
|
+
),
|
|
72
|
+
children: node.badge
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
node.count !== void 0 && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] tabular-nums text-muted-foreground", children: node.count }),
|
|
76
|
+
node.platformType && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded bg-indigo-50 px-1.5 py-0.5 text-[10px] text-indigo-700 dark:bg-indigo-950/50 dark:text-indigo-200", children: node.platformType }),
|
|
77
|
+
node.ascode && /* @__PURE__ */ jsxs("span", { className: "shrink-0 rounded bg-rose-50 px-1.5 py-0.5 text-[10px] text-rose-700 dark:bg-rose-950/50 dark:text-rose-200", children: [
|
|
78
|
+
"code: ",
|
|
79
|
+
node.ascode
|
|
80
|
+
] }),
|
|
81
|
+
node.description && /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-xs text-muted-foreground", children: node.description })
|
|
82
|
+
] });
|
|
83
|
+
}
|
|
84
|
+
const ENUM_LIMIT = 12;
|
|
85
|
+
const PLATFORM_TYPE_LABEL = ["OI", "PA type"].join("");
|
|
86
|
+
function SchemaFieldMetaPanel({ meta }) {
|
|
87
|
+
var _a;
|
|
88
|
+
const enums = meta.enumValues ?? [];
|
|
89
|
+
const shown = enums.slice(0, ENUM_LIMIT);
|
|
90
|
+
const hidden = enums.length - shown.length;
|
|
91
|
+
const loc = meta.location;
|
|
92
|
+
return /* @__PURE__ */ jsxs("div", { className: "my-1 space-y-2 rounded-md border border-border bg-muted/30 p-2 text-xs", children: [
|
|
93
|
+
/* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5", children: [
|
|
94
|
+
/* @__PURE__ */ jsx(Row, { label: PLATFORM_TYPE_LABEL, value: meta.platformType }),
|
|
95
|
+
/* @__PURE__ */ jsx(Row, { label: "AsCode", value: meta.ascode }),
|
|
96
|
+
/* @__PURE__ */ jsx(Row, { label: "Format", value: meta.format }),
|
|
97
|
+
/* @__PURE__ */ jsx(Row, { label: "Layout", value: meta.layout }),
|
|
98
|
+
/* @__PURE__ */ jsx(Row, { label: "Client ref", value: meta.clientRef ? "yes" : void 0 }),
|
|
99
|
+
(_a = meta.annotations) == null ? void 0 : _a.map((annotation) => /* @__PURE__ */ jsx(Row, { label: annotation.key, value: annotation.value }, annotation.key))
|
|
100
|
+
] }),
|
|
101
|
+
meta.description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: meta.description }),
|
|
102
|
+
enums.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
103
|
+
/* @__PURE__ */ jsxs("p", { className: "font-medium text-muted-foreground", children: [
|
|
104
|
+
"Enum (",
|
|
105
|
+
enums.length,
|
|
106
|
+
")"
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ jsx("ul", { className: "max-h-48 space-y-0.5 overflow-auto", children: shown.map((entry) => /* @__PURE__ */ jsxs("li", { children: [
|
|
109
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: entry.value }),
|
|
110
|
+
entry.label && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
111
|
+
" - ",
|
|
112
|
+
entry.label
|
|
113
|
+
] })
|
|
114
|
+
] }, entry.value)) }),
|
|
115
|
+
hidden > 0 && /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
|
|
116
|
+
"+",
|
|
117
|
+
hidden,
|
|
118
|
+
" more"
|
|
119
|
+
] })
|
|
120
|
+
] }),
|
|
121
|
+
meta.query && /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
122
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-muted-foreground", children: "Query" }),
|
|
123
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto", children: /* @__PURE__ */ jsx(CodeBlock, { language: "sql", source: meta.query }) })
|
|
124
|
+
] }),
|
|
125
|
+
loc && /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
126
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-muted-foreground", children: "Source location" }),
|
|
127
|
+
/* @__PURE__ */ jsx("p", { className: "break-all font-mono", children: formatLocation(loc.path, loc.startLine, loc.endLine) })
|
|
128
|
+
] }),
|
|
129
|
+
meta.source && /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
130
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-muted-foreground", children: "Source" }),
|
|
131
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto", children: /* @__PURE__ */ jsx(CodeBlock, { language: "xml", source: meta.source }) })
|
|
132
|
+
] })
|
|
133
|
+
] });
|
|
134
|
+
}
|
|
135
|
+
function Row({ label, value }) {
|
|
136
|
+
if (value === void 0 || value === null) return null;
|
|
137
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
138
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: label }),
|
|
139
|
+
/* @__PURE__ */ jsx("dd", { className: "break-all font-mono", children: value })
|
|
140
|
+
] });
|
|
141
|
+
}
|
|
142
|
+
function formatLocation(path, startLine, endLine) {
|
|
143
|
+
if (startLine === void 0) return path;
|
|
144
|
+
if (endLine === void 0 || endLine === startLine) return `${path}:${startLine}`;
|
|
145
|
+
return `${path}:${startLine}-${endLine}`;
|
|
146
|
+
}
|
|
147
|
+
export {
|
|
148
|
+
SchemaFieldMetaPanel,
|
|
149
|
+
SchemaViewer,
|
|
150
|
+
SchemaViewerRow
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=SchemaViewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaViewer.js","sources":["../../src/data/SchemaViewer.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from \"react\";\nimport { rehydrateRefs } from \"../components/json-schema-form-refs\";\nimport type { JsonSchemaObject } from \"../components/json-schema-form-types\";\nimport { cn } from \"../lib/utils\";\nimport { CodeBlock } from \"./CodeBlock\";\nimport { Tree } from \"./Tree\";\nimport {\n buildSchemaTree,\n type SchemaViewerFieldMeta,\n type SchemaViewerNode,\n} from \"./schema-viewer-model\";\n\nexport interface SchemaViewerProps {\n schema: JsonSchemaObject;\n /** Pre-scoped tree roots, for dialogs that want to show a single schema branch. */\n roots?: SchemaViewerNode[];\n /** Custom tree builder. Defaults to buildSchemaTree. */\n buildTree?: (schema: JsonSchemaObject) => SchemaViewerNode[];\n className?: string;\n empty?: ReactNode;\n showControls?: boolean;\n toolbarClassName?: string;\n /** Root depth opened by default. Defaults to 1, matching the platform tree. */\n defaultOpenDepth?: number;\n /** Override the expanded detail panel for annotated fields. */\n renderDetail?: (meta: SchemaViewerFieldMeta) => ReactNode;\n}\n\nfunction isDetailOnly(node: SchemaViewerNode): boolean {\n const [child] = node.children ?? [];\n return node.children?.length === 1 && Boolean(child?.detail);\n}\n\nexport function SchemaViewer({\n schema,\n roots: scopedRoots,\n buildTree = buildSchemaTree,\n className,\n empty = <p className=\"p-3 text-sm text-muted-foreground\">This schema has no fields.</p>,\n showControls,\n toolbarClassName,\n defaultOpenDepth = 1,\n renderDetail,\n}: SchemaViewerProps) {\n const roots = useMemo(\n () => scopedRoots ?? buildTree(rehydrateRefs(schema)),\n [buildTree, scopedRoots, schema],\n );\n\n return (\n <Tree<SchemaViewerNode>\n className={cn(\"text-sm\", className)}\n roots={roots}\n getKey={(node) => node.key}\n getChildren={(node) => node.children}\n isSecondary={(node) => Boolean(node.detail)}\n getSearchText={(node) =>\n node.detail ? \"\" : `${node.label} ${node.badge ?? \"\"} ${node.platformType ?? \"\"} ${node.ascode ?? \"\"}`\n }\n defaultOpen={(node, depth) => depth < defaultOpenDepth && !isDetailOnly(node)}\n rowClass={(node, selected) =>\n node.detail\n ? \"cursor-default\"\n : selected\n ? \"bg-primary/10 border-l-2 border-primary\"\n : \"hover:bg-accent\"\n }\n renderRow={({ node }) =>\n node.detail ? (\n <div className=\"min-w-0 flex-1\">\n {renderDetail ? renderDetail(node.detail) : <SchemaFieldMetaPanel meta={node.detail} />}\n </div>\n ) : (\n <SchemaViewerRow node={node} />\n )\n }\n empty={empty}\n {...(showControls !== undefined ? { showControls } : {})}\n {...(toolbarClassName !== undefined ? { toolbarClassName } : {})}\n />\n );\n}\n\nconst BADGE_TONE: Record<string, string> = {\n branch: \"bg-violet-100 text-violet-700 dark:bg-violet-950/50 dark:text-violet-200\",\n group: \"bg-violet-100 text-violet-700 dark:bg-violet-950/50 dark:text-violet-200\",\n activity: \"bg-emerald-100 text-emerald-700 dark:bg-emerald-950/50 dark:text-emerald-200\",\n clientType: \"bg-sky-100 text-sky-700 dark:bg-sky-950/50 dark:text-sky-200\",\n clientTypes: \"bg-sky-100 text-sky-700 dark:bg-sky-950/50 dark:text-sky-200\",\n fields: \"bg-amber-100 text-amber-700 dark:bg-amber-950/50 dark:text-amber-200\",\n object: \"bg-muted text-muted-foreground\",\n array: \"bg-muted text-muted-foreground\",\n string: \"bg-muted text-muted-foreground\",\n number: \"bg-muted text-muted-foreground\",\n integer: \"bg-muted text-muted-foreground\",\n boolean: \"bg-muted text-muted-foreground\",\n const: \"bg-muted text-muted-foreground\",\n};\n\nexport function SchemaViewerRow({ node }: { node: SchemaViewerNode }) {\n const tone = node.badge ? BADGE_TONE[node.badge] : undefined;\n return (\n <span className=\"flex w-full min-w-0 items-center gap-2\">\n <span className=\"min-w-0 truncate font-mono\">{node.label}</span>\n {node.badge && (\n <span\n className={cn(\n \"shrink-0 rounded px-1.5 py-0.5 text-[10px] font-medium\",\n tone ?? \"bg-muted text-muted-foreground\",\n )}\n >\n {node.badge}\n </span>\n )}\n {node.count !== undefined && (\n <span className=\"shrink-0 rounded-full bg-muted px-1.5 py-0.5 text-[10px] tabular-nums text-muted-foreground\">\n {node.count}\n </span>\n )}\n {node.platformType && (\n <span className=\"shrink-0 rounded bg-indigo-50 px-1.5 py-0.5 text-[10px] text-indigo-700 dark:bg-indigo-950/50 dark:text-indigo-200\">\n {node.platformType}\n </span>\n )}\n {node.ascode && (\n <span className=\"shrink-0 rounded bg-rose-50 px-1.5 py-0.5 text-[10px] text-rose-700 dark:bg-rose-950/50 dark:text-rose-200\">\n code: {node.ascode}\n </span>\n )}\n {node.description && (\n <span className=\"min-w-0 truncate text-xs text-muted-foreground\">{node.description}</span>\n )}\n </span>\n );\n}\n\nexport interface SchemaFieldMetaPanelProps {\n meta: SchemaViewerFieldMeta;\n}\n\nconst ENUM_LIMIT = 12;\nconst PLATFORM_TYPE_LABEL = [\"OI\", \"PA type\"].join(\"\");\n\nexport function SchemaFieldMetaPanel({ meta }: SchemaFieldMetaPanelProps) {\n const enums = meta.enumValues ?? [];\n const shown = enums.slice(0, ENUM_LIMIT);\n const hidden = enums.length - shown.length;\n const loc = meta.location;\n\n return (\n <div className=\"my-1 space-y-2 rounded-md border border-border bg-muted/30 p-2 text-xs\">\n <dl className=\"grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5\">\n <Row label={PLATFORM_TYPE_LABEL} value={meta.platformType} />\n <Row label=\"AsCode\" value={meta.ascode} />\n <Row label=\"Format\" value={meta.format} />\n <Row label=\"Layout\" value={meta.layout} />\n <Row label=\"Client ref\" value={meta.clientRef ? \"yes\" : undefined} />\n {meta.annotations?.map((annotation) => (\n <Row key={annotation.key} label={annotation.key} value={annotation.value} />\n ))}\n </dl>\n\n {meta.description && <p className=\"text-muted-foreground\">{meta.description}</p>}\n\n {enums.length > 0 && (\n <div className=\"space-y-0.5\">\n <p className=\"font-medium text-muted-foreground\">Enum ({enums.length})</p>\n <ul className=\"max-h-48 space-y-0.5 overflow-auto\">\n {shown.map((entry) => (\n <li key={entry.value}>\n <span className=\"font-mono\">{entry.value}</span>\n {entry.label && <span className=\"text-muted-foreground\"> - {entry.label}</span>}\n </li>\n ))}\n </ul>\n {hidden > 0 && <p className=\"text-muted-foreground\">+{hidden} more</p>}\n </div>\n )}\n\n {meta.query && (\n <div className=\"space-y-0.5\">\n <p className=\"font-medium text-muted-foreground\">Query</p>\n <div className=\"max-h-64 overflow-auto\">\n <CodeBlock language=\"sql\" source={meta.query} />\n </div>\n </div>\n )}\n\n {loc && (\n <div className=\"space-y-0.5\">\n <p className=\"font-medium text-muted-foreground\">Source location</p>\n <p className=\"break-all font-mono\">{formatLocation(loc.path, loc.startLine, loc.endLine)}</p>\n </div>\n )}\n\n {meta.source && (\n <div className=\"space-y-0.5\">\n <p className=\"font-medium text-muted-foreground\">Source</p>\n <div className=\"max-h-64 overflow-auto\">\n <CodeBlock language=\"xml\" source={meta.source} />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: ReactNode }): ReactNode {\n if (value === undefined || value === null) return null;\n return (\n <>\n <dt className=\"text-muted-foreground\">{label}</dt>\n <dd className=\"break-all font-mono\">{value}</dd>\n </>\n );\n}\n\nfunction formatLocation(path: string, startLine?: number, endLine?: number): string {\n if (startLine === undefined) return path;\n if (endLine === undefined || endLine === startLine) return `${path}:${startLine}`;\n return `${path}:${startLine}-${endLine}`;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,8 @@ const react = require("react");
|
|
|
6
6
|
const utils = require("../lib/utils.cjs");
|
|
7
7
|
const Icon = require("./Icon.cjs");
|
|
8
8
|
const TimeseriesCoreBars_model = require("./TimeseriesCoreBars.model.cjs");
|
|
9
|
+
const GaugeHoverCard = require("./GaugeHoverCard.cjs");
|
|
10
|
+
const gaugeStats = require("./gauge-stats.cjs");
|
|
9
11
|
const defaultFetcher = async (url) => {
|
|
10
12
|
const res = await fetch(url);
|
|
11
13
|
if (!res.ok) throw new Error(`metrics request failed: ${res.status}`);
|
|
@@ -51,6 +53,7 @@ function TimeseriesCoreBars({
|
|
|
51
53
|
baseUrl = "",
|
|
52
54
|
value,
|
|
53
55
|
max,
|
|
56
|
+
unit,
|
|
54
57
|
title,
|
|
55
58
|
icon,
|
|
56
59
|
range = "1h",
|
|
@@ -59,11 +62,17 @@ function TimeseriesCoreBars({
|
|
|
59
62
|
variant = "default",
|
|
60
63
|
showLabel = true,
|
|
61
64
|
showValue = true,
|
|
65
|
+
showCapacity = false,
|
|
62
66
|
orientation,
|
|
67
|
+
hoverCard = true,
|
|
63
68
|
fetcher = defaultFetcher,
|
|
64
69
|
className
|
|
65
70
|
}) {
|
|
66
|
-
var _a, _b;
|
|
71
|
+
var _a, _b, _c, _d;
|
|
72
|
+
const perBar = (unit == null ? void 0 : unit.perBar) ?? 1e3;
|
|
73
|
+
const unitLabel = (unit == null ? void 0 : unit.label) ?? "cores";
|
|
74
|
+
const barLabel = (unit == null ? void 0 : unit.barLabel) ?? "core";
|
|
75
|
+
const formatUnits = (unit == null ? void 0 : unit.format) ?? formatCores;
|
|
67
76
|
const maxIsSeries = typeof max === "object";
|
|
68
77
|
const maxSeries = maxIsSeries ? max : void 0;
|
|
69
78
|
const ids = react.useMemo(() => {
|
|
@@ -94,12 +103,29 @@ function TimeseriesCoreBars({
|
|
|
94
103
|
const rawMax = latestValue((_b = results[1]) == null ? void 0 : _b.data);
|
|
95
104
|
limit = rawMax === void 0 ? void 0 : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;
|
|
96
105
|
}
|
|
97
|
-
const model = TimeseriesCoreBars_model.deriveCoreBars(usage, limit);
|
|
106
|
+
const model = TimeseriesCoreBars_model.deriveCoreBars(usage, limit, perBar);
|
|
98
107
|
const tone = toneClass(model.pct, thresholds);
|
|
99
|
-
const
|
|
100
|
-
const
|
|
108
|
+
const usageText = formatUnits(model.usageCores);
|
|
109
|
+
const capacityText = model.limitCores !== void 0 ? formatUnits(model.limitCores) : "?";
|
|
110
|
+
const caption = !model.hasUsage ? "—" : showCapacity ? `${usageText} / ${capacityText} ${unitLabel}` : `${usageText} ${unitLabel}`;
|
|
111
|
+
const compactCaption = !model.hasUsage ? "—" : showCapacity ? `${usageText}/${capacityText} ${unitLabel}` : `${usageText} ${unitLabel}`;
|
|
101
112
|
const titleText = `${title}: ${compactCaption}`;
|
|
102
113
|
const isCell = variant === "cell";
|
|
114
|
+
const pctTone = model.limitCores === void 0 ? void 0 : model.pct >= thresholds[1] ? "text-red-500" : model.pct >= thresholds[0] ? "text-amber-500" : "text-emerald-500";
|
|
115
|
+
const stats = gaugeStats.seriesStats(
|
|
116
|
+
(_d = (_c = results[0]) == null ? void 0 : _c.data) == null ? void 0 : _d.points,
|
|
117
|
+
(v) => (value.transform ? value.transform(v) : v) / perBar
|
|
118
|
+
);
|
|
119
|
+
const fmt = (n) => `${formatUnits(n)} ${unitLabel}`;
|
|
120
|
+
const hoverRows = model.hasUsage ? [
|
|
121
|
+
{ label: "Current", value: fmt(model.usageCores), ...pctTone ? { tone: pctTone } : {} },
|
|
122
|
+
...stats ? [
|
|
123
|
+
{ label: "Min", value: fmt(stats.min) },
|
|
124
|
+
{ label: "Max", value: fmt(stats.max) },
|
|
125
|
+
{ label: "Avg", value: fmt(stats.avg) }
|
|
126
|
+
] : [],
|
|
127
|
+
...model.limitCores !== void 0 ? [{ label: "Capacity", value: fmt(model.limitCores) }] : []
|
|
128
|
+
] : [];
|
|
103
129
|
const resolvedOrientation = orientation ?? "vertical";
|
|
104
130
|
const isDense = model.coreCount > 4;
|
|
105
131
|
const valueText = isCell ? compactCaption : caption;
|
|
@@ -130,8 +156,8 @@ function TimeseriesCoreBars({
|
|
|
130
156
|
isCell ? isDense ? "w-[3px] rounded-[2px]" : "w-1.5 rounded-[2px]" : isDense ? "w-1 rounded-sm" : "w-2 rounded-sm"
|
|
131
157
|
) : utils.cn("min-h-px w-full flex-1 rounded-[2px]")
|
|
132
158
|
),
|
|
133
|
-
title:
|
|
134
|
-
"aria-label": !isCell ?
|
|
159
|
+
title: `${barLabel} ${i + 1}: ${corePct}%`,
|
|
160
|
+
"aria-label": !isCell ? `${barLabel} ${i + 1}: ${corePct}%` : void 0,
|
|
135
161
|
"data-fill": bar.fill,
|
|
136
162
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
137
163
|
"span",
|
|
@@ -171,16 +197,18 @@ function TimeseriesCoreBars({
|
|
|
171
197
|
]
|
|
172
198
|
}
|
|
173
199
|
) : null;
|
|
200
|
+
const useHover = hoverCard && hoverRows.length > 0;
|
|
201
|
+
const footer = `over last ${range}`;
|
|
174
202
|
if (isCell) {
|
|
175
|
-
|
|
203
|
+
const cell = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
176
204
|
"span",
|
|
177
205
|
{
|
|
178
206
|
className: utils.cn(
|
|
179
207
|
"inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap align-middle text-xs",
|
|
180
208
|
className
|
|
181
209
|
),
|
|
182
|
-
title: titleText,
|
|
183
|
-
"aria-label": hiddenAccessibleText,
|
|
210
|
+
...useHover ? {} : { title: titleText },
|
|
211
|
+
"aria-label": useHover ? titleText : hiddenAccessibleText,
|
|
184
212
|
children: [
|
|
185
213
|
label,
|
|
186
214
|
bars,
|
|
@@ -188,13 +216,14 @@ function TimeseriesCoreBars({
|
|
|
188
216
|
]
|
|
189
217
|
}
|
|
190
218
|
);
|
|
219
|
+
return useHover ? /* @__PURE__ */ jsxRuntime.jsx(GaugeHoverCard.GaugeHoverCard, { title, rows: hoverRows, footer, trigger: cell }) : cell;
|
|
191
220
|
}
|
|
192
|
-
|
|
221
|
+
const block = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
193
222
|
"div",
|
|
194
223
|
{
|
|
195
224
|
className: utils.cn("flex flex-col items-center gap-1", className),
|
|
196
|
-
title: hiddenAccessibleText,
|
|
197
|
-
"aria-label": hiddenAccessibleText,
|
|
225
|
+
...useHover ? {} : { title: hiddenAccessibleText },
|
|
226
|
+
"aria-label": useHover ? titleText : hiddenAccessibleText,
|
|
198
227
|
children: [
|
|
199
228
|
bars,
|
|
200
229
|
valueNode,
|
|
@@ -202,6 +231,16 @@ function TimeseriesCoreBars({
|
|
|
202
231
|
]
|
|
203
232
|
}
|
|
204
233
|
);
|
|
234
|
+
return useHover ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
235
|
+
GaugeHoverCard.GaugeHoverCard,
|
|
236
|
+
{
|
|
237
|
+
title,
|
|
238
|
+
rows: hoverRows,
|
|
239
|
+
footer,
|
|
240
|
+
trigger: block,
|
|
241
|
+
className: "w-full justify-center"
|
|
242
|
+
}
|
|
243
|
+
) : block;
|
|
205
244
|
}
|
|
206
245
|
exports.TimeseriesCoreBars = TimeseriesCoreBars;
|
|
207
246
|
//# sourceMappingURL=TimeseriesCoreBars.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesCoreBars.cjs","sources":["../../src/data/TimeseriesCoreBars.tsx"],"sourcesContent":["import { useQueries } from \"@tanstack/react-query\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport type { GaugeSeries } from \"./TimeseriesGauge\";\nimport type { TimeseriesResponse } from \"./TimeseriesPanel\";\nimport { deriveCoreBars } from \"./TimeseriesCoreBars.model\";\n\nexport type TimeseriesCoreBarsVariant = \"default\" | \"cell\";\nexport type TimeseriesCoreBarsOrientation = \"horizontal\" | \"vertical\";\n\nexport interface TimeseriesCoreBarsProps {\n /** Common prefix; the value/max requests are `baseUrl + id`. */\n baseUrl?: string;\n /** The metric whose latest value (CPU millicores) fills the bars. */\n value: GaugeSeries;\n /**\n * The CPU capacity. Either a `.limit`-style metric series (its latest value in\n * millicores) or a fixed number of millicores. Determines the number of bars\n * (one per core). When omitted or 0, the bar count falls back to the ceiling of\n * the usage in cores so an unbounded reading still renders.\n */\n max?: GaugeSeries | number;\n title: string;\n /** Iconify name or static icon component shown beside the label. */\n icon?: string | StaticIconComponent;\n /** Look-back window 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 /**\n * Utilisation thresholds (percent of capacity) at which the fill turns amber\n * then red. Defaults to [75, 90].\n */\n thresholds?: [warning: number, danger: number];\n /** Visual density/layout. `cell` is a compact inline form for table/grid cells. */\n variant?: TimeseriesCoreBarsVariant;\n /** Show the title text. Icons and values remain visible unless separately hidden. */\n showLabel?: boolean;\n /** Show the value/capacity caption. Icons and bars remain visible when false. */\n showValue?: boolean;\n /** Bar direction. Vertical bars fill bottom-up; horizontal bars fill left-to-right. */\n orientation?: TimeseriesCoreBarsOrientation;\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\nconst defaultFetcher = async (url: string): Promise<TimeseriesResponse> => {\n const res = await fetch(url);\n if (!res.ok) throw new Error(`metrics request failed: ${res.status}`);\n return res.json();\n};\n\nfunction latestValue(resp: TimeseriesResponse | undefined): number | undefined {\n const points = resp?.points;\n if (!points || points.length === 0) return undefined;\n return points[points.length - 1]?.value;\n}\n\nfunction toneClass(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\nfunction CoreBarsIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return (\n <Icon\n name={icon}\n width={14}\n height={14}\n className=\"text-muted-foreground\"\n />\n );\n }\n return (\n <Icon\n icon={icon}\n width={14}\n height={14}\n className=\"text-muted-foreground\"\n />\n );\n}\n\nfunction formatCores(cores: number): string {\n return Number.isInteger(cores) ? String(cores) : cores.toFixed(1);\n}\n\n/**\n * TimeseriesCoreBars renders CPU utilisation as a row of vertical bars — one bar\n * per core (the ceiling of the CPU limit) — filled left to right by the latest\n * usage. The bar that straddles the usage boundary is partially filled (\"blocked\n * out\") to show the fractional core in use, and the trailing bars stay empty to\n * show headroom. Both usage and limit are read live from the timeseries store,\n * mirroring TimeseriesGauge's data plumbing; the bar colour crosses warning and\n * danger thresholds. A \"<used> / <cores>\" caption sits below with the icon+title.\n */\nexport function TimeseriesCoreBars({\n baseUrl = \"\",\n value,\n max,\n title,\n icon,\n range = \"1h\",\n refreshMs = 5000,\n thresholds = [75, 90],\n variant = \"default\",\n showLabel = true,\n showValue = true,\n orientation,\n fetcher = defaultFetcher,\n className,\n}: TimeseriesCoreBarsProps) {\n const maxIsSeries = typeof max === \"object\";\n const maxSeries = maxIsSeries ? max : undefined;\n const ids = useMemo(() => {\n const list = [value.id];\n if (maxSeries) list.push(maxSeries.id);\n return list;\n }, [value.id, maxSeries]);\n\n const results = useQueries({\n queries: ids.map((id) => {\n const u = new URL(baseUrl + id, window.location.origin);\n if (range) u.searchParams.set(\"since\", range);\n const requestUrl = u.pathname + u.search;\n return {\n queryKey: [\"timeseries\", requestUrl],\n queryFn: () => fetcher(requestUrl),\n refetchInterval: refreshMs > 0 ? refreshMs : false,\n staleTime: 0,\n retry: 0,\n };\n }),\n });\n\n const rawValue = latestValue(results[0]?.data);\n const usage =\n rawValue === undefined\n ? undefined\n : value.transform\n ? value.transform(rawValue)\n : rawValue;\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 =\n rawMax === undefined\n ? undefined\n : maxSeries.transform\n ? maxSeries.transform(rawMax)\n : rawMax;\n }\n\n const model = deriveCoreBars(usage, limit);\n const tone = toneClass(model.pct, thresholds);\n const caption = model.hasUsage\n ? `${formatCores(model.usageCores)} / ${model.limitCores !== undefined ? formatCores(model.limitCores) : \"?\"} cores`\n : \"—\";\n const compactCaption = model.hasUsage\n ? `${formatCores(model.usageCores)}/${model.limitCores !== undefined ? formatCores(model.limitCores) : \"?\"} cores`\n : \"—\";\n const titleText = `${title}: ${compactCaption}`;\n const isCell = variant === \"cell\";\n const resolvedOrientation = orientation ?? \"vertical\";\n const isDense = model.coreCount > 4;\n const valueText = isCell ? compactCaption : caption;\n const hiddenAccessibleText = !showLabel || !showValue ? titleText : undefined;\n const bars = (\n <span\n className={cn(\n \"flex shrink-0\",\n resolvedOrientation === \"vertical\"\n ? cn(\"items-end\", isCell ? \"h-4 gap-px\" : \"h-10 gap-0.5\")\n : cn(\n \"flex-col justify-center\",\n isCell ? \"h-4 w-10 gap-px\" : \"h-10 w-16 gap-0.5\",\n ),\n )}\n aria-hidden={isCell ? \"true\" : undefined}\n data-orientation={resolvedOrientation}\n data-core-count={model.coreCount}\n data-core-density={isDense ? \"compact\" : \"default\"}\n >\n {model.bars.map((bar, i) => {\n const corePct = Math.round(bar.fill * 100);\n return (\n <span\n key={i}\n className={cn(\n \"relative overflow-hidden bg-muted\",\n resolvedOrientation === \"vertical\"\n ? cn(\n \"h-full\",\n isCell\n ? isDense\n ? \"w-[3px] rounded-[2px]\"\n : \"w-1.5 rounded-[2px]\"\n : isDense\n ? \"w-1 rounded-sm\"\n : \"w-2 rounded-sm\",\n )\n : cn(\"min-h-px w-full flex-1 rounded-[2px]\"),\n )}\n title={`core ${i + 1}: ${corePct}%`}\n aria-label={!isCell ? `core ${i + 1}: ${corePct}%` : undefined}\n data-fill={bar.fill}\n >\n <span\n className={cn(\n \"absolute bottom-0 left-0 transition-all duration-300\",\n tone,\n )}\n style={\n resolvedOrientation === \"vertical\"\n ? { height: `${corePct}%`, right: 0 }\n : { width: `${corePct}%`, top: 0 }\n }\n />\n </span>\n );\n })}\n </span>\n );\n const valueNode = showValue ? (\n <span\n className={cn(\n \"shrink-0 font-semibold tabular-nums text-foreground\",\n isCell ? null : \"text-xs\",\n )}\n >\n {valueText}\n </span>\n ) : null;\n const label =\n icon || showLabel ? (\n <span\n className={cn(\n \"inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground\",\n )}\n >\n {icon ? <CoreBarsIcon icon={icon} /> : null}\n {showLabel ? <span className=\"min-w-0 truncate\">{title}</span> : null}\n </span>\n ) : null;\n\n if (isCell) {\n return (\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 title={titleText}\n aria-label={hiddenAccessibleText}\n >\n {label}\n {bars}\n {valueNode}\n </span>\n );\n }\n\n return (\n <div\n className={cn(\"flex flex-col items-center gap-1\", className)}\n title={hiddenAccessibleText}\n aria-label={hiddenAccessibleText}\n >\n {bars}\n {valueNode}\n {label}\n </div>\n );\n}\n"],"names":["jsx","Icon","useMemo","useQueries","deriveCoreBars","cn","jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimeseriesCoreBars.cjs","sources":["../../src/data/TimeseriesCoreBars.tsx"],"sourcesContent":["import { useQueries } from \"@tanstack/react-query\";\nimport { useMemo } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon, type StaticIconComponent } from \"./Icon\";\nimport type { GaugeSeries } from \"./TimeseriesGauge\";\nimport type { TimeseriesResponse } from \"./TimeseriesPanel\";\nimport { deriveCoreBars } from \"./TimeseriesCoreBars.model\";\nimport { GaugeHoverCard, type GaugeHoverRow } from \"./GaugeHoverCard\";\nimport { seriesStats } from \"./gauge-stats\";\n\nexport type TimeseriesCoreBarsVariant = \"default\" | \"cell\";\nexport type TimeseriesCoreBarsOrientation = \"horizontal\" | \"vertical\";\n\n/**\n * Describes what one bar represents, letting the same component render CPU cores,\n * memory gigabytes, or any other quantised capacity. Defaults model CPU cores.\n */\nexport interface CoreBarsUnit {\n /** Raw value that fills one bar, in the domain of `value`/`max`. Default 1000 (millicores → 1 core). */\n perBar?: number;\n /** Caption/tooltip suffix naming the unit, plural. Default \"cores\". */\n label?: string;\n /** Per-bar hover tooltip noun, singular. Default \"core\". */\n barLabel?: string;\n /** Format a bar-unit count for the caption. Default: integers as-is, else 1 decimal. */\n format?: (units: number) => string;\n}\n\nexport interface TimeseriesCoreBarsProps {\n /** Common prefix; the value/max requests are `baseUrl + id`. */\n baseUrl?: string;\n /** The metric whose latest value (CPU millicores) fills the bars. */\n value: GaugeSeries;\n /**\n * The capacity. Either a `.limit`-style metric series (its latest value) or a\n * fixed number, in the same raw domain as `value`. Determines the number of\n * bars (one per `unit.perBar`). When omitted or 0, the bar count falls back to\n * the ceiling of the usage so an unbounded reading still renders.\n */\n max?: GaugeSeries | number;\n /** What one bar represents. Defaults to CPU cores (perBar 1000, label \"cores\"). */\n unit?: CoreBarsUnit;\n title: string;\n /** Iconify name or static icon component shown beside the label. */\n icon?: string | StaticIconComponent;\n /** Look-back window 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 /**\n * Utilisation thresholds (percent of capacity) at which the fill turns amber\n * then red. Defaults to [75, 90].\n */\n thresholds?: [warning: number, danger: number];\n /** Visual density/layout. `cell` is a compact inline form for table/grid cells. */\n variant?: TimeseriesCoreBarsVariant;\n /** Show the title text. Icons and values remain visible unless separately hidden. */\n showLabel?: boolean;\n /** Show the value/capacity caption. Icons and bars remain visible when false. */\n showValue?: boolean;\n /**\n * Include the capacity in the caption (\"2.3 / 4 cores\"). Defaults to false — the\n * caption shows only the current value (\"2.3 cores\") since the bars already\n * convey capacity. Set true to append the \"/ <capacity>\".\n */\n showCapacity?: boolean;\n /** Bar direction. Vertical bars fill bottom-up; horizontal bars fill left-to-right. */\n orientation?: TimeseriesCoreBarsOrientation;\n /**\n * Wrap the bars 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\nconst defaultFetcher = async (url: string): Promise<TimeseriesResponse> => {\n const res = await fetch(url);\n if (!res.ok) throw new Error(`metrics request failed: ${res.status}`);\n return res.json();\n};\n\nfunction latestValue(resp: TimeseriesResponse | undefined): number | undefined {\n const points = resp?.points;\n if (!points || points.length === 0) return undefined;\n return points[points.length - 1]?.value;\n}\n\nfunction toneClass(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\nfunction CoreBarsIcon({ icon }: { icon: string | StaticIconComponent }) {\n if (typeof icon === \"string\") {\n return (\n <Icon\n name={icon}\n width={14}\n height={14}\n className=\"text-muted-foreground\"\n />\n );\n }\n return (\n <Icon\n icon={icon}\n width={14}\n height={14}\n className=\"text-muted-foreground\"\n />\n );\n}\n\nfunction formatCores(cores: number): string {\n return Number.isInteger(cores) ? String(cores) : cores.toFixed(1);\n}\n\n/**\n * TimeseriesCoreBars renders CPU utilisation as a row of vertical bars — one bar\n * per core (the ceiling of the CPU limit) — filled left to right by the latest\n * usage. The bar that straddles the usage boundary is partially filled (\"blocked\n * out\") to show the fractional core in use, and the trailing bars stay empty to\n * show headroom. Both usage and limit are read live from the timeseries store,\n * mirroring TimeseriesGauge's data plumbing; the bar colour crosses warning and\n * danger thresholds. A \"<used> / <cores>\" caption sits below with the icon+title.\n */\nexport function TimeseriesCoreBars({\n baseUrl = \"\",\n value,\n max,\n unit,\n title,\n icon,\n range = \"1h\",\n refreshMs = 5000,\n thresholds = [75, 90],\n variant = \"default\",\n showLabel = true,\n showValue = true,\n showCapacity = false,\n orientation,\n hoverCard = true,\n fetcher = defaultFetcher,\n className,\n}: TimeseriesCoreBarsProps) {\n const perBar = unit?.perBar ?? 1000;\n const unitLabel = unit?.label ?? \"cores\";\n const barLabel = unit?.barLabel ?? \"core\";\n const formatUnits = unit?.format ?? formatCores;\n const maxIsSeries = typeof max === \"object\";\n const maxSeries = maxIsSeries ? max : undefined;\n const ids = useMemo(() => {\n const list = [value.id];\n if (maxSeries) list.push(maxSeries.id);\n return list;\n }, [value.id, maxSeries]);\n\n const results = useQueries({\n queries: ids.map((id) => {\n const u = new URL(baseUrl + id, window.location.origin);\n if (range) u.searchParams.set(\"since\", range);\n const requestUrl = u.pathname + u.search;\n return {\n queryKey: [\"timeseries\", requestUrl],\n queryFn: () => fetcher(requestUrl),\n refetchInterval: refreshMs > 0 ? refreshMs : false,\n staleTime: 0,\n retry: 0,\n };\n }),\n });\n\n const rawValue = latestValue(results[0]?.data);\n const usage =\n rawValue === undefined\n ? undefined\n : value.transform\n ? value.transform(rawValue)\n : rawValue;\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 =\n rawMax === undefined\n ? undefined\n : maxSeries.transform\n ? maxSeries.transform(rawMax)\n : rawMax;\n }\n\n const model = deriveCoreBars(usage, limit, perBar);\n const tone = toneClass(model.pct, thresholds);\n const usageText = formatUnits(model.usageCores);\n const capacityText =\n model.limitCores !== undefined ? formatUnits(model.limitCores) : \"?\";\n const caption = !model.hasUsage\n ? \"—\"\n : showCapacity\n ? `${usageText} / ${capacityText} ${unitLabel}`\n : `${usageText} ${unitLabel}`;\n const compactCaption = !model.hasUsage\n ? \"—\"\n : showCapacity\n ? `${usageText}/${capacityText} ${unitLabel}`\n : `${usageText} ${unitLabel}`;\n const titleText = `${title}: ${compactCaption}`;\n const isCell = variant === \"cell\";\n\n // Hover card: reduce the fetched points to current/min/max/avg in bar-units\n // (raw value transformed, then divided by perBar) so they read in the same unit\n // as the caption. A bounded reading colours the current row by its threshold.\n const pctTone =\n model.limitCores === undefined\n ? undefined\n : model.pct >= thresholds[1]\n ? \"text-red-500\"\n : model.pct >= thresholds[0]\n ? \"text-amber-500\"\n : \"text-emerald-500\";\n const stats = seriesStats(results[0]?.data?.points, (v) =>\n (value.transform ? value.transform(v) : v) / perBar,\n );\n const fmt = (n: number) => `${formatUnits(n)} ${unitLabel}`;\n const hoverRows: GaugeHoverRow[] = model.hasUsage\n ? [\n { label: \"Current\", value: fmt(model.usageCores), ...(pctTone ? { tone: pctTone } : {}) },\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 ...(model.limitCores !== undefined\n ? [{ label: \"Capacity\", value: fmt(model.limitCores) }]\n : []),\n ]\n : [];\n\n const resolvedOrientation = orientation ?? \"vertical\";\n const isDense = model.coreCount > 4;\n const valueText = isCell ? compactCaption : caption;\n const hiddenAccessibleText = !showLabel || !showValue ? titleText : undefined;\n const bars = (\n <span\n className={cn(\n \"flex shrink-0\",\n resolvedOrientation === \"vertical\"\n ? cn(\"items-end\", isCell ? \"h-4 gap-px\" : \"h-10 gap-0.5\")\n : cn(\n \"flex-col justify-center\",\n isCell ? \"h-4 w-10 gap-px\" : \"h-10 w-16 gap-0.5\",\n ),\n )}\n aria-hidden={isCell ? \"true\" : undefined}\n data-orientation={resolvedOrientation}\n data-core-count={model.coreCount}\n data-core-density={isDense ? \"compact\" : \"default\"}\n >\n {model.bars.map((bar, i) => {\n const corePct = Math.round(bar.fill * 100);\n return (\n <span\n key={i}\n className={cn(\n \"relative overflow-hidden bg-muted\",\n resolvedOrientation === \"vertical\"\n ? cn(\n \"h-full\",\n isCell\n ? isDense\n ? \"w-[3px] rounded-[2px]\"\n : \"w-1.5 rounded-[2px]\"\n : isDense\n ? \"w-1 rounded-sm\"\n : \"w-2 rounded-sm\",\n )\n : cn(\"min-h-px w-full flex-1 rounded-[2px]\"),\n )}\n title={`${barLabel} ${i + 1}: ${corePct}%`}\n aria-label={!isCell ? `${barLabel} ${i + 1}: ${corePct}%` : undefined}\n data-fill={bar.fill}\n >\n <span\n className={cn(\n \"absolute bottom-0 left-0 transition-all duration-300\",\n tone,\n )}\n style={\n resolvedOrientation === \"vertical\"\n ? { height: `${corePct}%`, right: 0 }\n : { width: `${corePct}%`, top: 0 }\n }\n />\n </span>\n );\n })}\n </span>\n );\n const valueNode = showValue ? (\n <span\n className={cn(\n \"shrink-0 font-semibold tabular-nums text-foreground\",\n isCell ? null : \"text-xs\",\n )}\n >\n {valueText}\n </span>\n ) : null;\n const label =\n icon || showLabel ? (\n <span\n className={cn(\n \"inline-flex min-w-0 items-center gap-1 text-xs text-muted-foreground\",\n )}\n >\n {icon ? <CoreBarsIcon icon={icon} /> : null}\n {showLabel ? <span className=\"min-w-0 truncate\">{title}</span> : null}\n </span>\n ) : null;\n\n const useHover = hoverCard && hoverRows.length > 0;\n const footer = `over last ${range}`;\n\n if (isCell) {\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 ? titleText : hiddenAccessibleText}\n >\n {label}\n {bars}\n {valueNode}\n </span>\n );\n return useHover ? (\n <GaugeHoverCard title={title} rows={hoverRows} footer={footer} trigger={cell} />\n ) : (\n cell\n );\n }\n\n const block = (\n <div\n className={cn(\"flex flex-col items-center gap-1\", className)}\n {...(useHover ? {} : { title: hiddenAccessibleText })}\n aria-label={useHover ? titleText : hiddenAccessibleText}\n >\n {bars}\n {valueNode}\n {label}\n </div>\n );\n return useHover ? (\n <GaugeHoverCard\n title={title}\n rows={hoverRows}\n footer={footer}\n trigger={block}\n className=\"w-full justify-center\"\n />\n ) : (\n block\n );\n}\n"],"names":["jsx","Icon","useMemo","useQueries","deriveCoreBars","seriesStats","cn","jsxs","GaugeHoverCard"],"mappings":"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"}
|
|
@@ -3,18 +3,34 @@ import { GaugeSeries } from './TimeseriesGauge';
|
|
|
3
3
|
import { TimeseriesResponse } from './TimeseriesPanel';
|
|
4
4
|
export type TimeseriesCoreBarsVariant = "default" | "cell";
|
|
5
5
|
export type TimeseriesCoreBarsOrientation = "horizontal" | "vertical";
|
|
6
|
+
/**
|
|
7
|
+
* Describes what one bar represents, letting the same component render CPU cores,
|
|
8
|
+
* memory gigabytes, or any other quantised capacity. Defaults model CPU cores.
|
|
9
|
+
*/
|
|
10
|
+
export interface CoreBarsUnit {
|
|
11
|
+
/** Raw value that fills one bar, in the domain of `value`/`max`. Default 1000 (millicores → 1 core). */
|
|
12
|
+
perBar?: number;
|
|
13
|
+
/** Caption/tooltip suffix naming the unit, plural. Default "cores". */
|
|
14
|
+
label?: string;
|
|
15
|
+
/** Per-bar hover tooltip noun, singular. Default "core". */
|
|
16
|
+
barLabel?: string;
|
|
17
|
+
/** Format a bar-unit count for the caption. Default: integers as-is, else 1 decimal. */
|
|
18
|
+
format?: (units: number) => string;
|
|
19
|
+
}
|
|
6
20
|
export interface TimeseriesCoreBarsProps {
|
|
7
21
|
/** Common prefix; the value/max requests are `baseUrl + id`. */
|
|
8
22
|
baseUrl?: string;
|
|
9
23
|
/** The metric whose latest value (CPU millicores) fills the bars. */
|
|
10
24
|
value: GaugeSeries;
|
|
11
25
|
/**
|
|
12
|
-
* The
|
|
13
|
-
*
|
|
14
|
-
* (one per
|
|
15
|
-
* the
|
|
26
|
+
* The capacity. Either a `.limit`-style metric series (its latest value) or a
|
|
27
|
+
* fixed number, in the same raw domain as `value`. Determines the number of
|
|
28
|
+
* bars (one per `unit.perBar`). When omitted or 0, the bar count falls back to
|
|
29
|
+
* the ceiling of the usage so an unbounded reading still renders.
|
|
16
30
|
*/
|
|
17
31
|
max?: GaugeSeries | number;
|
|
32
|
+
/** What one bar represents. Defaults to CPU cores (perBar 1000, label "cores"). */
|
|
33
|
+
unit?: CoreBarsUnit;
|
|
18
34
|
title: string;
|
|
19
35
|
/** Iconify name or static icon component shown beside the label. */
|
|
20
36
|
icon?: string | StaticIconComponent;
|
|
@@ -33,8 +49,19 @@ export interface TimeseriesCoreBarsProps {
|
|
|
33
49
|
showLabel?: boolean;
|
|
34
50
|
/** Show the value/capacity caption. Icons and bars remain visible when false. */
|
|
35
51
|
showValue?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Include the capacity in the caption ("2.3 / 4 cores"). Defaults to false — the
|
|
54
|
+
* caption shows only the current value ("2.3 cores") since the bars already
|
|
55
|
+
* convey capacity. Set true to append the "/ <capacity>".
|
|
56
|
+
*/
|
|
57
|
+
showCapacity?: boolean;
|
|
36
58
|
/** Bar direction. Vertical bars fill bottom-up; horizontal bars fill left-to-right. */
|
|
37
59
|
orientation?: TimeseriesCoreBarsOrientation;
|
|
60
|
+
/**
|
|
61
|
+
* Wrap the bars in a hover card summarising the metric (label + current / min /
|
|
62
|
+
* max / avg / capacity over the window). Defaults to true.
|
|
63
|
+
*/
|
|
64
|
+
hoverCard?: boolean;
|
|
38
65
|
/** Override the default fetch (e.g. to route through an app's API client). */
|
|
39
66
|
fetcher?: (url: string) => Promise<TimeseriesResponse>;
|
|
40
67
|
className?: string;
|
|
@@ -48,5 +75,5 @@ export interface TimeseriesCoreBarsProps {
|
|
|
48
75
|
* mirroring TimeseriesGauge's data plumbing; the bar colour crosses warning and
|
|
49
76
|
* danger thresholds. A "<used> / <cores>" caption sits below with the icon+title.
|
|
50
77
|
*/
|
|
51
|
-
export declare function TimeseriesCoreBars({ baseUrl, value, max, title, icon, range, refreshMs, thresholds, variant, showLabel, showValue, orientation, fetcher, className, }: TimeseriesCoreBarsProps): import("react/jsx-runtime").JSX.Element;
|
|
78
|
+
export declare function TimeseriesCoreBars({ baseUrl, value, max, unit, title, icon, range, refreshMs, thresholds, variant, showLabel, showValue, showCapacity, orientation, hoverCard, fetcher, className, }: TimeseriesCoreBarsProps): import("react/jsx-runtime").JSX.Element;
|
|
52
79
|
//# sourceMappingURL=TimeseriesCoreBars.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeseriesCoreBars.d.ts","sourceRoot":"","sources":["../../src/data/TimeseriesCoreBars.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAQ,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"TimeseriesCoreBars.d.ts","sourceRoot":"","sources":["../../src/data/TimeseriesCoreBars.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAQ,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK5D,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG,MAAM,CAAC;AAC3D,MAAM,MAAM,6BAA6B,GAAG,YAAY,GAAG,UAAU,CAAC;AAEtE;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,wGAAwG;IACxG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,KAAK,EAAE,WAAW,CAAC;IACnB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,mFAAmF;IACnF,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IACpC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,mFAAmF;IACnF,OAAO,CAAC,EAAE,yBAAyB,CAAC;IACpC,qFAAqF;IACrF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uFAAuF;IACvF,WAAW,CAAC,EAAE,6BAA6B,CAAC;IAC5C;;;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;AA6CD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAY,EACZ,KAAK,EACL,GAAG,EACH,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,KAAY,EACZ,SAAgB,EAChB,UAAqB,EACrB,OAAmB,EACnB,SAAgB,EAChB,SAAgB,EAChB,YAAoB,EACpB,WAAW,EACX,SAAgB,EAChB,OAAwB,EACxB,SAAS,GACV,EAAE,uBAAuB,2CAmOzB"}
|
|
@@ -4,6 +4,8 @@ import { useMemo } from "react";
|
|
|
4
4
|
import { cn } from "../lib/utils.js";
|
|
5
5
|
import { Icon } from "./Icon.js";
|
|
6
6
|
import { deriveCoreBars } from "./TimeseriesCoreBars.model.js";
|
|
7
|
+
import { GaugeHoverCard } from "./GaugeHoverCard.js";
|
|
8
|
+
import { seriesStats } from "./gauge-stats.js";
|
|
7
9
|
const defaultFetcher = async (url) => {
|
|
8
10
|
const res = await fetch(url);
|
|
9
11
|
if (!res.ok) throw new Error(`metrics request failed: ${res.status}`);
|
|
@@ -49,6 +51,7 @@ function TimeseriesCoreBars({
|
|
|
49
51
|
baseUrl = "",
|
|
50
52
|
value,
|
|
51
53
|
max,
|
|
54
|
+
unit,
|
|
52
55
|
title,
|
|
53
56
|
icon,
|
|
54
57
|
range = "1h",
|
|
@@ -57,11 +60,17 @@ function TimeseriesCoreBars({
|
|
|
57
60
|
variant = "default",
|
|
58
61
|
showLabel = true,
|
|
59
62
|
showValue = true,
|
|
63
|
+
showCapacity = false,
|
|
60
64
|
orientation,
|
|
65
|
+
hoverCard = true,
|
|
61
66
|
fetcher = defaultFetcher,
|
|
62
67
|
className
|
|
63
68
|
}) {
|
|
64
|
-
var _a, _b;
|
|
69
|
+
var _a, _b, _c, _d;
|
|
70
|
+
const perBar = (unit == null ? void 0 : unit.perBar) ?? 1e3;
|
|
71
|
+
const unitLabel = (unit == null ? void 0 : unit.label) ?? "cores";
|
|
72
|
+
const barLabel = (unit == null ? void 0 : unit.barLabel) ?? "core";
|
|
73
|
+
const formatUnits = (unit == null ? void 0 : unit.format) ?? formatCores;
|
|
65
74
|
const maxIsSeries = typeof max === "object";
|
|
66
75
|
const maxSeries = maxIsSeries ? max : void 0;
|
|
67
76
|
const ids = useMemo(() => {
|
|
@@ -92,12 +101,29 @@ function TimeseriesCoreBars({
|
|
|
92
101
|
const rawMax = latestValue((_b = results[1]) == null ? void 0 : _b.data);
|
|
93
102
|
limit = rawMax === void 0 ? void 0 : maxSeries.transform ? maxSeries.transform(rawMax) : rawMax;
|
|
94
103
|
}
|
|
95
|
-
const model = deriveCoreBars(usage, limit);
|
|
104
|
+
const model = deriveCoreBars(usage, limit, perBar);
|
|
96
105
|
const tone = toneClass(model.pct, thresholds);
|
|
97
|
-
const
|
|
98
|
-
const
|
|
106
|
+
const usageText = formatUnits(model.usageCores);
|
|
107
|
+
const capacityText = model.limitCores !== void 0 ? formatUnits(model.limitCores) : "?";
|
|
108
|
+
const caption = !model.hasUsage ? "—" : showCapacity ? `${usageText} / ${capacityText} ${unitLabel}` : `${usageText} ${unitLabel}`;
|
|
109
|
+
const compactCaption = !model.hasUsage ? "—" : showCapacity ? `${usageText}/${capacityText} ${unitLabel}` : `${usageText} ${unitLabel}`;
|
|
99
110
|
const titleText = `${title}: ${compactCaption}`;
|
|
100
111
|
const isCell = variant === "cell";
|
|
112
|
+
const pctTone = model.limitCores === void 0 ? void 0 : model.pct >= thresholds[1] ? "text-red-500" : model.pct >= thresholds[0] ? "text-amber-500" : "text-emerald-500";
|
|
113
|
+
const stats = seriesStats(
|
|
114
|
+
(_d = (_c = results[0]) == null ? void 0 : _c.data) == null ? void 0 : _d.points,
|
|
115
|
+
(v) => (value.transform ? value.transform(v) : v) / perBar
|
|
116
|
+
);
|
|
117
|
+
const fmt = (n) => `${formatUnits(n)} ${unitLabel}`;
|
|
118
|
+
const hoverRows = model.hasUsage ? [
|
|
119
|
+
{ label: "Current", value: fmt(model.usageCores), ...pctTone ? { tone: pctTone } : {} },
|
|
120
|
+
...stats ? [
|
|
121
|
+
{ label: "Min", value: fmt(stats.min) },
|
|
122
|
+
{ label: "Max", value: fmt(stats.max) },
|
|
123
|
+
{ label: "Avg", value: fmt(stats.avg) }
|
|
124
|
+
] : [],
|
|
125
|
+
...model.limitCores !== void 0 ? [{ label: "Capacity", value: fmt(model.limitCores) }] : []
|
|
126
|
+
] : [];
|
|
101
127
|
const resolvedOrientation = orientation ?? "vertical";
|
|
102
128
|
const isDense = model.coreCount > 4;
|
|
103
129
|
const valueText = isCell ? compactCaption : caption;
|
|
@@ -128,8 +154,8 @@ function TimeseriesCoreBars({
|
|
|
128
154
|
isCell ? isDense ? "w-[3px] rounded-[2px]" : "w-1.5 rounded-[2px]" : isDense ? "w-1 rounded-sm" : "w-2 rounded-sm"
|
|
129
155
|
) : cn("min-h-px w-full flex-1 rounded-[2px]")
|
|
130
156
|
),
|
|
131
|
-
title:
|
|
132
|
-
"aria-label": !isCell ?
|
|
157
|
+
title: `${barLabel} ${i + 1}: ${corePct}%`,
|
|
158
|
+
"aria-label": !isCell ? `${barLabel} ${i + 1}: ${corePct}%` : void 0,
|
|
133
159
|
"data-fill": bar.fill,
|
|
134
160
|
children: /* @__PURE__ */ jsx(
|
|
135
161
|
"span",
|
|
@@ -169,16 +195,18 @@ function TimeseriesCoreBars({
|
|
|
169
195
|
]
|
|
170
196
|
}
|
|
171
197
|
) : null;
|
|
198
|
+
const useHover = hoverCard && hoverRows.length > 0;
|
|
199
|
+
const footer = `over last ${range}`;
|
|
172
200
|
if (isCell) {
|
|
173
|
-
|
|
201
|
+
const cell = /* @__PURE__ */ jsxs(
|
|
174
202
|
"span",
|
|
175
203
|
{
|
|
176
204
|
className: cn(
|
|
177
205
|
"inline-flex min-w-0 items-center gap-1.5 whitespace-nowrap align-middle text-xs",
|
|
178
206
|
className
|
|
179
207
|
),
|
|
180
|
-
title: titleText,
|
|
181
|
-
"aria-label": hiddenAccessibleText,
|
|
208
|
+
...useHover ? {} : { title: titleText },
|
|
209
|
+
"aria-label": useHover ? titleText : hiddenAccessibleText,
|
|
182
210
|
children: [
|
|
183
211
|
label,
|
|
184
212
|
bars,
|
|
@@ -186,13 +214,14 @@ function TimeseriesCoreBars({
|
|
|
186
214
|
]
|
|
187
215
|
}
|
|
188
216
|
);
|
|
217
|
+
return useHover ? /* @__PURE__ */ jsx(GaugeHoverCard, { title, rows: hoverRows, footer, trigger: cell }) : cell;
|
|
189
218
|
}
|
|
190
|
-
|
|
219
|
+
const block = /* @__PURE__ */ jsxs(
|
|
191
220
|
"div",
|
|
192
221
|
{
|
|
193
222
|
className: cn("flex flex-col items-center gap-1", className),
|
|
194
|
-
title: hiddenAccessibleText,
|
|
195
|
-
"aria-label": hiddenAccessibleText,
|
|
223
|
+
...useHover ? {} : { title: hiddenAccessibleText },
|
|
224
|
+
"aria-label": useHover ? titleText : hiddenAccessibleText,
|
|
196
225
|
children: [
|
|
197
226
|
bars,
|
|
198
227
|
valueNode,
|
|
@@ -200,6 +229,16 @@ function TimeseriesCoreBars({
|
|
|
200
229
|
]
|
|
201
230
|
}
|
|
202
231
|
);
|
|
232
|
+
return useHover ? /* @__PURE__ */ jsx(
|
|
233
|
+
GaugeHoverCard,
|
|
234
|
+
{
|
|
235
|
+
title,
|
|
236
|
+
rows: hoverRows,
|
|
237
|
+
footer,
|
|
238
|
+
trigger: block,
|
|
239
|
+
className: "w-full justify-center"
|
|
240
|
+
}
|
|
241
|
+
) : block;
|
|
203
242
|
}
|
|
204
243
|
export {
|
|
205
244
|
TimeseriesCoreBars
|