@mastra/playground-ui 68.0.0-alpha.2 → 68.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{FilterBar-CQl04O6t.cjs → FilterBar-BSP2UTjc.cjs} +2 -2
- package/dist/{FilterBar-CQl04O6t.cjs.map → FilterBar-BSP2UTjc.cjs.map} +1 -1
- package/dist/{FilterBar-BgW2dqRQ.js → FilterBar-PSQ1OwqH.js} +2 -2
- package/dist/{FilterBar-BgW2dqRQ.js.map → FilterBar-PSQ1OwqH.js.map} +1 -1
- package/dist/KnowledgePageGraph.css +55 -0
- package/dist/{MarkdownRenderer-2GOXQJEv.js → MarkdownRenderer-CI30RqdB.js} +19 -6
- package/dist/MarkdownRenderer-CI30RqdB.js.map +1 -0
- package/dist/{MarkdownRenderer-CB8Z_CHc.cjs → MarkdownRenderer-y65WGBhC.cjs} +19 -6
- package/dist/MarkdownRenderer-y65WGBhC.cjs.map +1 -0
- package/dist/{MetricsCard-CEB-f2sv.cjs → MetricsCard-BEwiS7Pe.cjs} +8 -8
- package/dist/MetricsCard-BEwiS7Pe.cjs.map +1 -0
- package/dist/{MetricsCard-M8awJ2B_.js → MetricsCard-ua6C6b8a.js} +10 -10
- package/dist/MetricsCard-ua6C6b8a.js.map +1 -0
- package/dist/{MetricsLineChart-BhHoduO0.js → MetricsLineChart-4SwxBbQx.js} +14 -3
- package/dist/MetricsLineChart-4SwxBbQx.js.map +1 -0
- package/dist/{MetricsLineChart-CjBm4IXu.cjs → MetricsLineChart-tZxsauau.cjs} +13 -2
- package/dist/MetricsLineChart-tZxsauau.cjs.map +1 -0
- package/dist/{MetricsStackedBarChart-BdMlKv6G.cjs → MetricsStackedBarChart-CDLE76IB.cjs} +2 -2
- package/dist/{MetricsStackedBarChart-BdMlKv6G.cjs.map → MetricsStackedBarChart-CDLE76IB.cjs.map} +1 -1
- package/dist/{MetricsStackedBarChart-BRuA6MTE.js → MetricsStackedBarChart-D2QyS4-z.js} +2 -2
- package/dist/{MetricsStackedBarChart-BRuA6MTE.js.map → MetricsStackedBarChart-D2QyS4-z.js.map} +1 -1
- package/dist/{activity-rJ1NQl_2.js → activity-C8Ql81WM.js} +2 -2
- package/dist/{activity-rJ1NQl_2.js.map → activity-C8Ql81WM.js.map} +1 -1
- package/dist/{activity-DyB5H3gF.cjs → activity-CcQZeDYi.cjs} +2 -2
- package/dist/{activity-DyB5H3gF.cjs.map → activity-CcQZeDYi.cjs.map} +1 -1
- package/dist/components/DateTimeRangePicker.cjs.js +1 -1
- package/dist/components/DateTimeRangePicker.es.js +1 -1
- package/dist/components/FilterBar.cjs.js +2 -2
- package/dist/components/FilterBar.es.js +2 -2
- package/dist/components/MarkdownRenderer.cjs.js +1 -1
- package/dist/components/MarkdownRenderer.es.js +1 -1
- package/dist/components/MetricsCard.cjs.js +1 -1
- package/dist/components/MetricsCard.es.js +1 -1
- package/dist/components/MetricsLineChart.cjs.js +1 -1
- package/dist/components/MetricsLineChart.es.js +1 -1
- package/dist/components/MetricsStackedBarChart.cjs.js +1 -1
- package/dist/components/MetricsStackedBarChart.es.js +1 -1
- package/dist/components/SavedViews.cjs.js +1 -1
- package/dist/components/SavedViews.es.js +1 -1
- package/dist/components/ai/activity.cjs.js +1 -1
- package/dist/components/ai/activity.es.js +1 -1
- package/dist/components/ai/plan.cjs.js +1 -1
- package/dist/components/ai/plan.es.js +1 -1
- package/dist/components/ai/tool-approval.cjs.js +1 -1
- package/dist/components/ai/tool-approval.es.js +1 -1
- package/dist/components/ai/tool-call.cjs.js +2 -2
- package/dist/components/ai/tool-call.es.js +2 -2
- package/dist/{date-time-range-picker-CTt7Od0P.cjs → date-time-range-picker-CWGjoR3j.cjs} +40 -13
- package/dist/date-time-range-picker-CWGjoR3j.cjs.map +1 -0
- package/dist/{date-time-range-picker-DKh1K9Iy.js → date-time-range-picker-CdSiXwB4.js} +40 -13
- package/dist/date-time-range-picker-CdSiXwB4.js.map +1 -0
- package/dist/domains/chat/activity/activity-stretch-line.cjs.js +1 -1
- package/dist/domains/chat/activity/activity-stretch-line.es.js +1 -1
- package/dist/domains/chat/activity/components/activity-fold.cjs.js +1 -1
- package/dist/domains/chat/activity/components/activity-fold.es.js +1 -1
- package/dist/domains/chat/activity/components/activity-timed-trigger.cjs.js +1 -1
- package/dist/domains/chat/activity/components/activity-timed-trigger.es.js +1 -1
- package/dist/domains/chat/activity/components/calls-panel.cjs.js +1 -1
- package/dist/domains/chat/activity/components/calls-panel.es.js +1 -1
- package/dist/domains/chat/activity/components/stretch-content.cjs.js +1 -1
- package/dist/domains/chat/activity/components/stretch-content.es.js +1 -1
- package/dist/domains/chat/activity/components/stretch-thought.cjs.js +1 -1
- package/dist/domains/chat/activity/components/stretch-thought.es.js +1 -1
- package/dist/domains/chat/activity/model/activity-segments.cjs.js +1 -1
- package/dist/domains/chat/activity/model/activity-segments.es.js +1 -1
- package/dist/domains/chat/activity/model/activity-words.cjs.js +2 -2
- package/dist/domains/chat/activity/model/activity-words.es.js +2 -2
- package/dist/domains/chat/components/badge-wrapper.cjs.js +1 -1
- package/dist/domains/chat/components/badge-wrapper.es.js +1 -1
- package/dist/domains/chat/knowledge/knowledge-links.cjs.js +52 -6
- package/dist/domains/chat/knowledge/knowledge-links.cjs.js.map +1 -1
- package/dist/domains/chat/knowledge/knowledge-links.es.js +53 -9
- package/dist/domains/chat/knowledge/knowledge-links.es.js.map +1 -1
- package/dist/domains/chat/knowledge/pinned-knowledge-data.cjs.js +10 -3
- package/dist/domains/chat/knowledge/pinned-knowledge-data.cjs.js.map +1 -1
- package/dist/domains/chat/knowledge/pinned-knowledge-data.es.js +10 -3
- package/dist/domains/chat/knowledge/pinned-knowledge-data.es.js.map +1 -1
- package/dist/domains/chat/knowledge/pinned-knowledge.cjs.js +8 -3
- package/dist/domains/chat/knowledge/pinned-knowledge.cjs.js.map +1 -1
- package/dist/domains/chat/knowledge/pinned-knowledge.es.js +8 -3
- package/dist/domains/chat/knowledge/pinned-knowledge.es.js.map +1 -1
- package/dist/domains/chat/knowledge.cjs.js +2 -0
- package/dist/domains/chat/knowledge.es.js +2 -2
- package/dist/domains/chat/messages/message-row.cjs.js +3 -3
- package/dist/domains/chat/messages/message-row.es.js +3 -3
- package/dist/domains/chat/messages/notification-signal-notice.cjs.js +1 -1
- package/dist/domains/chat/messages/notification-signal-notice.es.js +1 -1
- package/dist/domains/chat/messages/reasoning-content.cjs.js +1 -1
- package/dist/domains/chat/messages/reasoning-content.es.js +1 -1
- package/dist/domains/chat/messages/renderers/message-text.cjs.js +35 -1
- package/dist/domains/chat/messages/renderers/message-text.cjs.js.map +1 -1
- package/dist/domains/chat/messages/renderers/message-text.es.js +36 -2
- package/dist/domains/chat/messages/renderers/message-text.es.js.map +1 -1
- package/dist/domains/chat/messages/renderers/reasoning-part-renderer.cjs.js +1 -1
- package/dist/domains/chat/messages/renderers/reasoning-part-renderer.es.js +1 -1
- package/dist/domains/chat/messages/signal-badge.cjs.js +1 -1
- package/dist/domains/chat/messages/signal-badge.es.js +1 -1
- package/dist/domains/chat/messages/skill-message.cjs.js +2 -2
- package/dist/domains/chat/messages/skill-message.es.js +2 -2
- package/dist/domains/chat/messages/system-reminder-badge.cjs.js +1 -1
- package/dist/domains/chat/messages/system-reminder-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge-wrapper.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge-wrapper.es.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/agent-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/file-tree-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/file-tree-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/knowledge-body-range.cjs.js +80 -0
- package/dist/domains/chat/tools/badges/knowledge-body-range.cjs.js.map +1 -0
- package/dist/domains/chat/tools/badges/knowledge-body-range.d.ts +1 -0
- package/dist/domains/chat/tools/badges/knowledge-body-range.es.js +78 -0
- package/dist/domains/chat/tools/badges/knowledge-body-range.es.js.map +1 -0
- package/dist/domains/chat/tools/badges/knowledge-tool-badge.cjs.js +163 -13
- package/dist/domains/chat/tools/badges/knowledge-tool-badge.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/knowledge-tool-badge.es.js +165 -15
- package/dist/domains/chat/tools/badges/knowledge-tool-badge.es.js.map +1 -1
- package/dist/domains/chat/tools/badges/mcp-input-request-badge.cjs.js +51 -0
- package/dist/domains/chat/tools/badges/mcp-input-request-badge.cjs.js.map +1 -0
- package/dist/domains/chat/tools/badges/mcp-input-request-badge.d.ts +1 -0
- package/dist/domains/chat/tools/badges/mcp-input-request-badge.es.js +49 -0
- package/dist/domains/chat/tools/badges/mcp-input-request-badge.es.js.map +1 -0
- package/dist/domains/chat/tools/badges/mcp-task-chip.cjs.js +7 -2
- package/dist/domains/chat/tools/badges/mcp-task-chip.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/mcp-task-chip.es.js +7 -2
- package/dist/domains/chat/tools/badges/mcp-task-chip.es.js.map +1 -1
- package/dist/domains/chat/tools/badges/observation-marker-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-details.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/observation-marker-details.es.js +2 -2
- package/dist/domains/chat/tools/badges/observation-renderer.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/observation-renderer.es.js +1 -1
- package/dist/domains/chat/tools/badges/sandbox-execution-badge.cjs.js +2 -2
- package/dist/domains/chat/tools/badges/sandbox-execution-badge.es.js +2 -2
- package/dist/domains/chat/tools/badges/tool-approval-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/tool-approval-badge.es.js +1 -1
- package/dist/domains/chat/tools/badges/tool-badge.cjs.js +9 -4
- package/dist/domains/chat/tools/badges/tool-badge.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/tool-badge.es.js +9 -4
- package/dist/domains/chat/tools/badges/tool-badge.es.js.map +1 -1
- package/dist/domains/chat/tools/badges/use-deferred-input-request.cjs.js +81 -0
- package/dist/domains/chat/tools/badges/use-deferred-input-request.cjs.js.map +1 -0
- package/dist/domains/chat/tools/badges/use-deferred-input-request.d.ts +1 -0
- package/dist/domains/chat/tools/badges/use-deferred-input-request.es.js +77 -0
- package/dist/domains/chat/tools/badges/use-deferred-input-request.es.js.map +1 -0
- package/dist/domains/chat/tools/badges/use-mcp-task-progress.cjs.js +11 -2
- package/dist/domains/chat/tools/badges/use-mcp-task-progress.cjs.js.map +1 -1
- package/dist/domains/chat/tools/badges/use-mcp-task-progress.es.js +11 -2
- package/dist/domains/chat/tools/badges/use-mcp-task-progress.es.js.map +1 -1
- package/dist/domains/chat/tools/badges/workflow-badge.cjs.js +1 -1
- package/dist/domains/chat/tools/badges/workflow-badge.es.js +1 -1
- package/dist/domains/chat/tools/connect-prompt-tool.cjs.js +79 -4
- package/dist/domains/chat/tools/connect-prompt-tool.cjs.js.map +1 -1
- package/dist/domains/chat/tools/connect-prompt-tool.es.js +79 -4
- package/dist/domains/chat/tools/connect-prompt-tool.es.js.map +1 -1
- package/dist/domains/chat/tools/mcp-input-request-tool.cjs.js +238 -0
- package/dist/domains/chat/tools/mcp-input-request-tool.cjs.js.map +1 -0
- package/dist/domains/chat/tools/mcp-input-request-tool.d.ts +1 -0
- package/dist/domains/chat/tools/mcp-input-request-tool.es.js +237 -0
- package/dist/domains/chat/tools/mcp-input-request-tool.es.js.map +1 -0
- package/dist/domains/chat/tools/mcp-input-request.cjs.js +40 -0
- package/dist/domains/chat/tools/mcp-input-request.cjs.js.map +1 -0
- package/dist/domains/chat/tools/mcp-input-request.d.ts +1 -0
- package/dist/domains/chat/tools/mcp-input-request.es.js +33 -0
- package/dist/domains/chat/tools/mcp-input-request.es.js.map +1 -0
- package/dist/domains/chat/tools/tool-card-kind.cjs.js +9 -4
- package/dist/domains/chat/tools/tool-card-kind.cjs.js.map +1 -1
- package/dist/domains/chat/tools/tool-card-kind.es.js +9 -5
- package/dist/domains/chat/tools/tool-card-kind.es.js.map +1 -1
- package/dist/domains/chat/tools/tool-card.cjs.js +1 -1
- package/dist/domains/chat/tools/tool-card.es.js +1 -1
- package/dist/domains/chat/tools/tool-groups.cjs.js +1 -1
- package/dist/domains/chat/tools/tool-groups.es.js +1 -1
- package/dist/domains/chat.cjs.js +5 -3
- package/dist/domains/chat.es.js +4 -4
- package/dist/domains/connect/types.cjs.js.map +1 -1
- package/dist/domains/connect/types.es.js.map +1 -1
- package/dist/domains/connect/use-user-connect.cjs.js +19 -2
- package/dist/domains/connect/use-user-connect.cjs.js.map +1 -1
- package/dist/domains/connect/use-user-connect.es.js +19 -2
- package/dist/domains/connect/use-user-connect.es.js.map +1 -1
- package/dist/domains/dashboards/components/dashboard-renderer.cjs.js +4 -3
- package/dist/domains/dashboards/components/dashboard-renderer.cjs.js.map +1 -1
- package/dist/domains/dashboards/components/dashboard-renderer.es.js +4 -3
- package/dist/domains/dashboards/components/dashboard-renderer.es.js.map +1 -1
- package/dist/domains/dashboards/components/widget-chrome.cjs.js +1 -1
- package/dist/domains/dashboards/components/widget-chrome.es.js +1 -1
- package/dist/domains/dashboards/components/widget-error.cjs.js +1 -1
- package/dist/domains/dashboards/components/widget-error.es.js +1 -1
- package/dist/domains/dashboards/hooks/use-widget-views.cjs.js +4 -3
- package/dist/domains/dashboards/hooks/use-widget-views.cjs.js.map +1 -1
- package/dist/domains/dashboards/hooks/use-widget-views.es.js +4 -3
- package/dist/domains/dashboards/hooks/use-widget-views.es.js.map +1 -1
- package/dist/domains/dashboards/kinds/scores/scores-widget.cjs.js +9 -6
- package/dist/domains/dashboards/kinds/scores/scores-widget.cjs.js.map +1 -1
- package/dist/domains/dashboards/kinds/scores/scores-widget.es.js +9 -6
- package/dist/domains/dashboards/kinds/scores/scores-widget.es.js.map +1 -1
- package/dist/domains/dashboards/kinds/table/table-tabs.cjs.js +2 -2
- package/dist/domains/dashboards/kinds/table/table-tabs.es.js +2 -2
- package/dist/domains/dashboards/kinds/table/table-widget.cjs.js +1 -1
- package/dist/domains/dashboards/kinds/table/table-widget.es.js +1 -1
- package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.cjs.js +6 -5
- package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.cjs.js.map +1 -1
- package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.es.js +6 -5
- package/dist/domains/dashboards/kinds/timeseries/timeseries-widget.es.js.map +1 -1
- package/dist/domains/dashboards/lib/chrome.cjs.js +9 -2
- package/dist/domains/dashboards/lib/chrome.cjs.js.map +1 -1
- package/dist/domains/dashboards/lib/chrome.es.js +9 -2
- package/dist/domains/dashboards/lib/chrome.es.js.map +1 -1
- package/dist/domains/dashboards/widget-kind.cjs.js.map +1 -1
- package/dist/domains/dashboards/widget-kind.es.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageCard.cjs.js +48 -0
- package/dist/domains/knowledge/components/KnowledgePageCard.cjs.js.map +1 -0
- package/dist/domains/knowledge/components/KnowledgePageCard.d.ts +1 -0
- package/dist/domains/knowledge/components/KnowledgePageCard.es.js +47 -0
- package/dist/domains/knowledge/components/KnowledgePageCard.es.js.map +1 -0
- package/dist/domains/knowledge/components/KnowledgePageDetail.cjs.js +63 -5
- package/dist/domains/knowledge/components/KnowledgePageDetail.cjs.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageDetail.es.js +64 -6
- package/dist/domains/knowledge/components/KnowledgePageDetail.es.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageExplorer.cjs.js +485 -47
- package/dist/domains/knowledge/components/KnowledgePageExplorer.cjs.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageExplorer.es.js +487 -50
- package/dist/domains/knowledge/components/KnowledgePageExplorer.es.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageGraph.cjs.js +1051 -123
- package/dist/domains/knowledge/components/KnowledgePageGraph.cjs.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageGraph.es.js +1054 -126
- package/dist/domains/knowledge/components/KnowledgePageGraph.es.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageTree.cjs.js +75 -3
- package/dist/domains/knowledge/components/KnowledgePageTree.cjs.js.map +1 -1
- package/dist/domains/knowledge/components/KnowledgePageTree.es.js +76 -4
- package/dist/domains/knowledge/components/KnowledgePageTree.es.js.map +1 -1
- package/dist/domains/knowledge/lib/circleText.cjs.js +9 -0
- package/dist/domains/knowledge/lib/circleText.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/circleText.d.ts +1 -0
- package/dist/domains/knowledge/lib/circleText.es.js +8 -0
- package/dist/domains/knowledge/lib/circleText.es.js.map +1 -0
- package/dist/domains/knowledge/lib/fitViewport.cjs.js +82 -0
- package/dist/domains/knowledge/lib/fitViewport.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/fitViewport.d.ts +1 -0
- package/dist/domains/knowledge/lib/fitViewport.es.js +73 -0
- package/dist/domains/knowledge/lib/fitViewport.es.js.map +1 -0
- package/dist/domains/knowledge/lib/graphShape.cjs.js +524 -0
- package/dist/domains/knowledge/lib/graphShape.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/graphShape.d.ts +1 -0
- package/dist/domains/knowledge/lib/graphShape.es.js +499 -0
- package/dist/domains/knowledge/lib/graphShape.es.js.map +1 -0
- package/dist/domains/knowledge/lib/linkCountsText.cjs.js +11 -0
- package/dist/domains/knowledge/lib/linkCountsText.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/linkCountsText.d.ts +1 -0
- package/dist/domains/knowledge/lib/linkCountsText.es.js +10 -0
- package/dist/domains/knowledge/lib/linkCountsText.es.js.map +1 -0
- package/dist/domains/knowledge/lib/pageAddress.cjs.js +29 -0
- package/dist/domains/knowledge/lib/pageAddress.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/pageAddress.d.ts +1 -0
- package/dist/domains/knowledge/lib/pageAddress.es.js +27 -0
- package/dist/domains/knowledge/lib/pageAddress.es.js.map +1 -0
- package/dist/domains/knowledge/lib/pageGraph.cjs.js +11 -11
- package/dist/domains/knowledge/lib/pageGraph.cjs.js.map +1 -1
- package/dist/domains/knowledge/lib/pageGraph.es.js +11 -11
- package/dist/domains/knowledge/lib/pageGraph.es.js.map +1 -1
- package/dist/domains/knowledge/lib/pageRefs.cjs.js +69 -0
- package/dist/domains/knowledge/lib/pageRefs.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/pageRefs.d.ts +1 -0
- package/dist/domains/knowledge/lib/pageRefs.es.js +66 -0
- package/dist/domains/knowledge/lib/pageRefs.es.js.map +1 -0
- package/dist/domains/knowledge/lib/pageTree.cjs.js +5 -0
- package/dist/domains/knowledge/lib/pageTree.cjs.js.map +1 -1
- package/dist/domains/knowledge/lib/pageTree.es.js +5 -1
- package/dist/domains/knowledge/lib/pageTree.es.js.map +1 -1
- package/dist/domains/knowledge/lib/remarkKnowledgeLinks.cjs.js +82 -0
- package/dist/domains/knowledge/lib/remarkKnowledgeLinks.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/remarkKnowledgeLinks.d.ts +1 -0
- package/dist/domains/knowledge/lib/remarkKnowledgeLinks.es.js +78 -0
- package/dist/domains/knowledge/lib/remarkKnowledgeLinks.es.js.map +1 -0
- package/dist/domains/knowledge/lib/tooltipSide.cjs.js +77 -0
- package/dist/domains/knowledge/lib/tooltipSide.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/tooltipSide.d.ts +1 -0
- package/dist/domains/knowledge/lib/tooltipSide.es.js +75 -0
- package/dist/domains/knowledge/lib/tooltipSide.es.js.map +1 -0
- package/dist/domains/knowledge/lib/useLeavingNodes.cjs.js +65 -0
- package/dist/domains/knowledge/lib/useLeavingNodes.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/useLeavingNodes.d.ts +1 -0
- package/dist/domains/knowledge/lib/useLeavingNodes.es.js +62 -0
- package/dist/domains/knowledge/lib/useLeavingNodes.es.js.map +1 -0
- package/dist/domains/knowledge/lib/useStableWhile.cjs.js +15 -0
- package/dist/domains/knowledge/lib/useStableWhile.cjs.js.map +1 -0
- package/dist/domains/knowledge/lib/useStableWhile.d.ts +1 -0
- package/dist/domains/knowledge/lib/useStableWhile.es.js +14 -0
- package/dist/domains/knowledge/lib/useStableWhile.es.js.map +1 -0
- package/dist/domains/metrics/components/agent-runs-card.cjs.js +3 -3
- package/dist/domains/metrics/components/agent-runs-card.es.js +3 -3
- package/dist/domains/metrics/components/breakdown/breakdown-tab-body.cjs.js +1 -1
- package/dist/domains/metrics/components/breakdown/breakdown-tab-body.es.js +1 -1
- package/dist/domains/metrics/components/breakdown-card.cjs.js +1 -1
- package/dist/domains/metrics/components/breakdown-card.es.js +1 -1
- package/dist/domains/metrics/components/chart-area.cjs.js +1 -1
- package/dist/domains/metrics/components/chart-area.es.js +1 -1
- package/dist/domains/metrics/components/chart-card-error.cjs.js +1 -1
- package/dist/domains/metrics/components/chart-card-error.es.js +1 -1
- package/dist/domains/metrics/components/chart-card.cjs.js +1 -1
- package/dist/domains/metrics/components/chart-card.es.js +1 -1
- package/dist/domains/metrics/components/date-range-selector.cjs.js +1 -1
- package/dist/domains/metrics/components/date-range-selector.es.js +1 -1
- package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.cjs.js +3 -2
- package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.cjs.js.map +1 -1
- package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.es.js +3 -2
- package/dist/domains/metrics/components/distinct-ids/distinct-ids-chart.es.js.map +1 -1
- package/dist/domains/metrics/components/failure-rate-card.cjs.js +3 -2
- package/dist/domains/metrics/components/failure-rate-card.cjs.js.map +1 -1
- package/dist/domains/metrics/components/failure-rate-card.es.js +3 -2
- package/dist/domains/metrics/components/failure-rate-card.es.js.map +1 -1
- package/dist/domains/metrics/components/latency-card.cjs.js +3 -2
- package/dist/domains/metrics/components/latency-card.cjs.js.map +1 -1
- package/dist/domains/metrics/components/latency-card.es.js +3 -2
- package/dist/domains/metrics/components/latency-card.es.js.map +1 -1
- package/dist/domains/metrics/components/metrics-time-range-chip.cjs.js +1 -1
- package/dist/domains/metrics/components/metrics-time-range-chip.es.js +1 -1
- package/dist/domains/metrics/components/scores-card.cjs.js +2 -1
- package/dist/domains/metrics/components/scores-card.cjs.js.map +1 -1
- package/dist/domains/metrics/components/scores-card.es.js +2 -1
- package/dist/domains/metrics/components/scores-card.es.js.map +1 -1
- package/dist/domains/metrics/components/token-usage-card.cjs.js +3 -3
- package/dist/domains/metrics/components/token-usage-card.es.js +3 -3
- package/dist/domains/metrics/components/trace-aggregate-card.cjs.js +1 -1
- package/dist/domains/metrics/components/trace-aggregate-card.es.js +1 -1
- package/dist/domains/observability/components/observability-histogram.cjs.js +1 -1
- package/dist/domains/observability/components/observability-histogram.es.js +1 -1
- package/dist/domains/scores/components/trace-scores-list.cjs.js +2 -2
- package/dist/domains/scores/components/trace-scores-list.es.js +2 -2
- package/dist/domains/skills/skill-simple-form.cjs.js +1 -1
- package/dist/domains/skills/skill-simple-form.es.js +1 -1
- package/dist/domains/spans/components/spans-filter-bar.cjs.js +2 -2
- package/dist/domains/spans/components/spans-filter-bar.es.js +2 -2
- package/dist/domains/spans/hooks/use-spans-filter-bar.cjs.js +1 -1
- package/dist/domains/spans/hooks/use-spans-filter-bar.es.js +1 -1
- package/dist/domains/threads/components/threads-filter-bar.cjs.js +2 -2
- package/dist/domains/threads/components/threads-filter-bar.es.js +2 -2
- package/dist/domains/threads/hooks/use-threads-filter-bar.cjs.js +1 -1
- package/dist/domains/threads/hooks/use-threads-filter-bar.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-error-renderer.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-error-renderer.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-input-renderers.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-input-renderers.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-output-renderers.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-output-renderers.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-messages.cjs.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-messages.es.js +2 -2
- package/dist/domains/traces/components/span-payload/span-payload-primitives.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-primitives.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-processor.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-processor.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-tool.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-payload-tool.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-processor-mutations.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-processor-mutations.es.js +1 -1
- package/dist/domains/traces/components/span-payload/span-tools-section.cjs.js +1 -1
- package/dist/domains/traces/components/span-payload/span-tools-section.es.js +1 -1
- package/dist/domains/traces/components/span-timeline-row.cjs.js +1 -1
- package/dist/domains/traces/components/span-timeline-row.es.js +1 -1
- package/dist/domains/traces/components/span-timing-hover-card.cjs.js +1 -1
- package/dist/domains/traces/components/span-timing-hover-card.es.js +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js +8 -2
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.es.js +8 -2
- package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
- package/dist/domains/traces/components/trace-error-cell.cjs.js +1 -1
- package/dist/domains/traces/components/trace-error-cell.es.js +1 -1
- package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.cjs.js +2 -2
- package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.es.js +2 -2
- package/dist/domains/traces/components/traces-explorer/use-traces-filter-bar.cjs.js +1 -1
- package/dist/domains/traces/components/traces-explorer/use-traces-filter-bar.es.js +1 -1
- package/dist/domains/workflows/runs/workflow-run-list.cjs.js +1 -1
- package/dist/domains/workflows/runs/workflow-run-list.es.js +1 -1
- package/dist/domains/workflows/workflow/input/workflow-processor-input.cjs.js +2 -2
- package/dist/domains/workflows/workflow/input/workflow-processor-input.es.js +2 -2
- package/dist/domains/workflows/workflow/use-workflow-trigger.cjs.js +3 -3
- package/dist/domains/workflows/workflow/use-workflow-trigger.es.js +3 -3
- package/dist/domains/workflows/workflow/workflow-input-data.cjs.js +1 -1
- package/dist/domains/workflows/workflow/workflow-input-data.es.js +1 -1
- package/dist/domains/workflows/workflow/workflow-suspended-steps.cjs.js +2 -2
- package/dist/domains/workflows/workflow/workflow-suspended-steps.es.js +2 -2
- package/dist/domains/workflows/workflow/workflow-time-travel-form.cjs.js +2 -2
- package/dist/domains/workflows/workflow/workflow-time-travel-form.es.js +2 -2
- package/dist/domains/workspace/components/workspace-add-skill-dialog.cjs.js +1 -1
- package/dist/domains/workspace/components/workspace-add-skill-dialog.es.js +1 -1
- package/dist/domains/workspace/components/workspace-markdown-preview.cjs.js +1 -1
- package/dist/domains/workspace/components/workspace-markdown-preview.es.js +1 -1
- package/dist/{filter-bar-time-range-mg9JeYue.js → filter-bar-time-range-qlV8p7hp.js} +2 -2
- package/dist/{filter-bar-time-range-mg9JeYue.js.map → filter-bar-time-range-qlV8p7hp.js.map} +1 -1
- package/dist/{filter-bar-time-range-BA-pXMlo.cjs → filter-bar-time-range-zdM024JD.cjs} +2 -2
- package/dist/{filter-bar-time-range-BA-pXMlo.cjs.map → filter-bar-time-range-zdM024JD.cjs.map} +1 -1
- package/dist/lib/form/dynamic-form.cjs.js +2 -2
- package/dist/lib/form/dynamic-form.es.js +2 -2
- package/dist/lib/form/json-draft.cjs.js +1 -1
- package/dist/lib/form/json-draft.es.js +1 -1
- package/dist/lib/form/zod-provider.cjs.js +1 -1
- package/dist/lib/form/zod-provider.es.js +1 -1
- package/dist/{span-payload-primitives-B3RdahsC.js → span-payload-primitives-CKKIAVPJ.js} +4 -4
- package/dist/{span-payload-primitives-B3RdahsC.js.map → span-payload-primitives-CKKIAVPJ.js.map} +1 -1
- package/dist/{span-payload-primitives-_2d-pAOD.cjs → span-payload-primitives-D4tHWN2W.cjs} +4 -4
- package/dist/{span-payload-primitives-_2d-pAOD.cjs.map → span-payload-primitives-D4tHWN2W.cjs.map} +1 -1
- package/dist/src/domains/chat/knowledge/knowledge-links.d.ts +32 -4
- package/dist/src/domains/chat/knowledge/pinned-knowledge-data.d.ts +2 -0
- package/dist/src/domains/chat/tools/badges/knowledge-body-range.d.ts +12 -0
- package/dist/src/domains/chat/tools/badges/knowledge-tool-badge.d.ts +5 -2
- package/dist/src/domains/chat/tools/badges/mcp-input-request-badge.d.ts +18 -0
- package/dist/src/domains/chat/tools/badges/tool-badge.d.ts +4 -1
- package/dist/src/domains/chat/tools/badges/use-deferred-input-request.d.ts +44 -0
- package/dist/src/domains/chat/tools/badges/use-mcp-task-progress.d.ts +6 -1
- package/dist/src/domains/chat/tools/connect-prompt-tool.d.ts +10 -1
- package/dist/src/domains/chat/tools/mcp-input-request-tool.d.ts +18 -0
- package/dist/src/domains/chat/tools/mcp-input-request.d.ts +40 -0
- package/dist/src/domains/chat/tools/tool-card-kind.d.ts +4 -2
- package/dist/src/domains/chat/tools/tool-card.d.ts +1 -1
- package/dist/src/domains/connect/types.d.ts +16 -0
- package/dist/src/domains/dashboards/components/dashboard-renderer.d.ts +4 -2
- package/dist/src/domains/dashboards/hooks/use-widget-views.d.ts +4 -3
- package/dist/src/domains/dashboards/index.d.ts +1 -1
- package/dist/src/domains/dashboards/kinds/scores/scores-widget.d.ts +1 -1
- package/dist/src/domains/dashboards/lib/chrome.d.ts +6 -4
- package/dist/src/domains/dashboards/widget-kind.d.ts +12 -0
- package/dist/src/domains/knowledge/components/KnowledgePageCard.d.ts +23 -0
- package/dist/src/domains/knowledge/components/KnowledgePageExplorer.d.ts +29 -0
- package/dist/src/domains/knowledge/components/KnowledgePageGraph.d.ts +27 -1
- package/dist/src/domains/knowledge/components/KnowledgePageTree.d.ts +2 -1
- package/dist/src/domains/knowledge/lib/circleText.d.ts +2 -0
- package/dist/src/domains/knowledge/lib/fitViewport.d.ts +67 -0
- package/dist/src/domains/knowledge/lib/graphShape.d.ts +131 -0
- package/dist/src/domains/knowledge/lib/linkCountsText.d.ts +5 -0
- package/dist/src/domains/knowledge/lib/pageAddress.d.ts +5 -0
- package/dist/src/domains/knowledge/lib/pageGraph.d.ts +4 -4
- package/dist/src/domains/knowledge/lib/pageRefs.d.ts +15 -0
- package/dist/src/domains/knowledge/lib/pageTree.d.ts +2 -0
- package/dist/src/domains/knowledge/lib/remarkKnowledgeLinks.d.ts +13 -0
- package/dist/src/domains/knowledge/lib/tooltipSide.d.ts +40 -0
- package/dist/src/domains/knowledge/lib/useLeavingNodes.d.ts +14 -0
- package/dist/src/domains/knowledge/lib/useStableWhile.d.ts +5 -0
- package/dist/src/domains/knowledge/pageTypes.d.ts +6 -1
- package/dist/src/ds/components/DateTimeRangePicker/date-time-range-picker.d.ts +12 -1
- package/dist/src/ds/components/MarkdownRenderer/markdown-renderer.d.ts +8 -1
- package/dist/src/ds/components/MetricsCard/metrics-card-headline.d.ts +1 -1
- package/dist/src/ds/components/MetricsLineChart/metrics-line-chart.d.ts +8 -0
- package/dist/src/ds/components/ai/tool-call/tool-phrases.d.ts +6 -0
- package/dist/style.css +73 -2
- package/dist/{tool-approval-1qiB4hhG.cjs → tool-approval-CJvPDL7D.cjs} +4 -4
- package/dist/{tool-approval-1qiB4hhG.cjs.map → tool-approval-CJvPDL7D.cjs.map} +1 -1
- package/dist/{tool-approval-B6MFcaKV.js → tool-approval-DyN11vFA.js} +4 -4
- package/dist/{tool-approval-B6MFcaKV.js.map → tool-approval-DyN11vFA.js.map} +1 -1
- package/dist/{tool-call-Bu66PkD-.cjs → tool-call-DBn14X-3.cjs} +9 -3
- package/dist/{tool-call-Bu66PkD-.cjs.map → tool-call-DBn14X-3.cjs.map} +1 -1
- package/dist/{tool-call-Ch9-jjXU.js → tool-call-Dsj43lvJ.js} +9 -3
- package/dist/{tool-call-Ch9-jjXU.js.map → tool-call-Dsj43lvJ.js.map} +1 -1
- package/dist/{tool-card-DrqPZfPQ.cjs → tool-card-BOLXeKIp.cjs} +167 -126
- package/dist/tool-card-BOLXeKIp.cjs.map +1 -0
- package/dist/{tool-card-sO6P2Qj4.js → tool-card-HZ5bm7ue.js} +168 -127
- package/dist/tool-card-HZ5bm7ue.js.map +1 -0
- package/dist/{tool-presentation-DvCsb_kz.js → tool-presentation-CvibOP1J.js} +6 -1
- package/dist/tool-presentation-CvibOP1J.js.map +1 -0
- package/dist/{tool-presentation-CQlDEwgS.cjs → tool-presentation-D6nzVruN.cjs} +6 -1
- package/dist/tool-presentation-D6nzVruN.cjs.map +1 -0
- package/package.json +11 -11
- package/dist/MarkdownRenderer-2GOXQJEv.js.map +0 -1
- package/dist/MarkdownRenderer-CB8Z_CHc.cjs.map +0 -1
- package/dist/MetricsCard-CEB-f2sv.cjs.map +0 -1
- package/dist/MetricsCard-M8awJ2B_.js.map +0 -1
- package/dist/MetricsLineChart-BhHoduO0.js.map +0 -1
- package/dist/MetricsLineChart-CjBm4IXu.cjs.map +0 -1
- package/dist/date-time-range-picker-CTt7Od0P.cjs.map +0 -1
- package/dist/date-time-range-picker-DKh1K9Iy.js.map +0 -1
- package/dist/domains/knowledge/lib/pageLayout.cjs.js +0 -49
- package/dist/domains/knowledge/lib/pageLayout.cjs.js.map +0 -1
- package/dist/domains/knowledge/lib/pageLayout.d.ts +0 -1
- package/dist/domains/knowledge/lib/pageLayout.es.js +0 -48
- package/dist/domains/knowledge/lib/pageLayout.es.js.map +0 -1
- package/dist/src/domains/knowledge/lib/pageLayout.d.ts +0 -24
- package/dist/tool-card-DrqPZfPQ.cjs.map +0 -1
- package/dist/tool-card-sO6P2Qj4.js.map +0 -1
- package/dist/tool-presentation-CQlDEwgS.cjs.map +0 -1
- package/dist/tool-presentation-DvCsb_kz.js.map +0 -1
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require('../../../KnowledgePageGraph.css');const require_Txt = require("../../../Txt-BnoSqxKE.cjs");
|
|
3
|
+
const require_domains_knowledge_lib_linkCountsText = require("../lib/linkCountsText.cjs.js");
|
|
4
|
+
const require_domains_knowledge_components_KnowledgePageCard = require("./KnowledgePageCard.cjs.js");
|
|
5
|
+
const require_domains_knowledge_lib_pageTree = require("../lib/pageTree.cjs.js");
|
|
6
|
+
const require_domains_knowledge_lib_graphShape = require("../lib/graphShape.cjs.js");
|
|
7
|
+
const require_domains_knowledge_lib_circleText = require("../lib/circleText.cjs.js");
|
|
8
|
+
const require_domains_knowledge_lib_useLeavingNodes = require("../lib/useLeavingNodes.cjs.js");
|
|
9
|
+
const require_domains_knowledge_lib_fitViewport = require("../lib/fitViewport.cjs.js");
|
|
10
|
+
const require_domains_knowledge_lib_layout = require("../lib/layout.cjs.js");
|
|
11
|
+
const require_domains_knowledge_lib_pageAddress = require("../lib/pageAddress.cjs.js");
|
|
3
12
|
const require_domains_knowledge_lib_pageGraph = require("../lib/pageGraph.cjs.js");
|
|
4
|
-
const
|
|
13
|
+
const require_domains_knowledge_lib_tooltipSide = require("../lib/tooltipSide.cjs.js");
|
|
5
14
|
let react = require("react");
|
|
6
15
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
16
|
let lucide_react = require("lucide-react");
|
|
@@ -13,12 +22,29 @@ var SCOPE_STYLE = {
|
|
|
13
22
|
background: "color-mix(in oklab, var(--chart-blue) 16%, var(--card))"
|
|
14
23
|
};
|
|
15
24
|
var PAGE_STYLE = { "--knowledge-color": "var(--border-strong)" };
|
|
25
|
+
/** A farther page drawn as a named circle: the legend's "Page in another branch" dot grown, same solid grey fill, name in the page background colour to read on it. */
|
|
26
|
+
var FAR_FILL = "var(--muted-foreground)";
|
|
27
|
+
var FAR_STYLE = {
|
|
28
|
+
"--knowledge-color": FAR_FILL,
|
|
29
|
+
background: FAR_FILL
|
|
30
|
+
};
|
|
16
31
|
var PARENT_EDGE_STYLE = {
|
|
17
32
|
stroke: "var(--foreground)",
|
|
18
33
|
strokeOpacity: .45,
|
|
19
34
|
strokeDasharray: "4 4",
|
|
20
35
|
strokeWidth: 1.25
|
|
21
36
|
};
|
|
37
|
+
var UP_EDGE_COLOR = "var(--chart-cyan)";
|
|
38
|
+
var UP_EDGE_STYLE = {
|
|
39
|
+
stroke: UP_EDGE_COLOR,
|
|
40
|
+
strokeWidth: 2.25
|
|
41
|
+
};
|
|
42
|
+
var UP_ARROW = {
|
|
43
|
+
type: _xyflow_react.MarkerType.ArrowClosed,
|
|
44
|
+
color: UP_EDGE_COLOR,
|
|
45
|
+
width: 14,
|
|
46
|
+
height: 14
|
|
47
|
+
};
|
|
22
48
|
var MENTION_EDGE_COLOR = "var(--chart-blue)";
|
|
23
49
|
var PARENT_ARROW_COLOR = "var(--muted-foreground)";
|
|
24
50
|
var PARENT_ARROW = {
|
|
@@ -40,6 +66,38 @@ var GRANT_ARROW = {
|
|
|
40
66
|
width: 13,
|
|
41
67
|
height: 13
|
|
42
68
|
};
|
|
69
|
+
var LINK_EDGE_COLOR = "var(--chart-green)";
|
|
70
|
+
var LINK_EDGE_STYLE = {
|
|
71
|
+
stroke: LINK_EDGE_COLOR,
|
|
72
|
+
strokeWidth: 1.25
|
|
73
|
+
};
|
|
74
|
+
var LINK_ARROW = {
|
|
75
|
+
type: _xyflow_react.MarkerType.ArrowClosed,
|
|
76
|
+
color: LINK_EDGE_COLOR,
|
|
77
|
+
width: 12,
|
|
78
|
+
height: 12
|
|
79
|
+
};
|
|
80
|
+
var DIRECTION_EDGE_STYLE = {
|
|
81
|
+
out: { stroke: LINK_EDGE_COLOR },
|
|
82
|
+
in: {
|
|
83
|
+
stroke: "var(--chart-orange)",
|
|
84
|
+
strokeDasharray: "6 3"
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var DIRECTION_ARROW = {
|
|
88
|
+
out: LINK_ARROW,
|
|
89
|
+
in: {
|
|
90
|
+
type: _xyflow_react.MarkerType.ArrowClosed,
|
|
91
|
+
color: "var(--chart-orange)",
|
|
92
|
+
width: 12,
|
|
93
|
+
height: 12
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var DOT_PARENT_EDGE_STYLE = {
|
|
97
|
+
stroke: "var(--foreground)",
|
|
98
|
+
strokeOpacity: .2,
|
|
99
|
+
strokeWidth: 1
|
|
100
|
+
};
|
|
43
101
|
var PLACEHOLDER_STYLE = {
|
|
44
102
|
background: "var(--card)",
|
|
45
103
|
borderColor: "var(--chart-purple)",
|
|
@@ -62,44 +120,291 @@ function pinBadgeStyle(size) {
|
|
|
62
120
|
}
|
|
63
121
|
};
|
|
64
122
|
}
|
|
65
|
-
/**
|
|
123
|
+
/** How long a focus change loads before the graph says so. */
|
|
124
|
+
var LOADING_HINT_DELAY_MS = 150;
|
|
125
|
+
/** How long it holds the old layout for pages that never arrive before drawing what it has. */
|
|
126
|
+
var LOADING_RELEASE_MS = 4e3;
|
|
127
|
+
/** Most a tooltip is enlarged to offset a zoomed-out graph. */
|
|
128
|
+
var TOOLTIP_MAX_SCALE = 3;
|
|
129
|
+
/** Screen-space box of an element. */
|
|
130
|
+
function boxOf(el) {
|
|
131
|
+
const { left, top, right, bottom } = el.getBoundingClientRect();
|
|
132
|
+
return {
|
|
133
|
+
left,
|
|
134
|
+
top,
|
|
135
|
+
right,
|
|
136
|
+
bottom
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/** The highlighted lines of the graph as screen-space segments, where the browser can measure them. */
|
|
140
|
+
function drawnLines(root) {
|
|
141
|
+
const lines = [];
|
|
142
|
+
for (const path of root.querySelectorAll(".react-flow__edge-path")) {
|
|
143
|
+
if (typeof path.getTotalLength !== "function" || typeof path.getScreenCTM !== "function") continue;
|
|
144
|
+
const matrix = path.getScreenCTM();
|
|
145
|
+
if (!matrix) continue;
|
|
146
|
+
const length = path.getTotalLength();
|
|
147
|
+
const start = path.getPointAtLength(0);
|
|
148
|
+
const end = path.getPointAtLength(length);
|
|
149
|
+
lines.push({
|
|
150
|
+
from: {
|
|
151
|
+
x: matrix.a * start.x + matrix.c * start.y + matrix.e,
|
|
152
|
+
y: matrix.b * start.x + matrix.d * start.y + matrix.f
|
|
153
|
+
},
|
|
154
|
+
to: {
|
|
155
|
+
x: matrix.a * end.x + matrix.c * end.y + matrix.e,
|
|
156
|
+
y: matrix.b * end.x + matrix.d * end.y + matrix.f
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return lines;
|
|
161
|
+
}
|
|
162
|
+
/** Where a tooltip sits against its dot, and which way it grows from it. */
|
|
163
|
+
var TOOLTIP_PLACEMENT = {
|
|
164
|
+
top: {
|
|
165
|
+
tip: "bottom-full left-1/2 mb-2",
|
|
166
|
+
transform: "translateX(-50%)",
|
|
167
|
+
origin: "bottom center",
|
|
168
|
+
tail: "top-full left-1/2 -translate-x-1/2 -translate-y-1/2 border-r border-b"
|
|
169
|
+
},
|
|
170
|
+
bottom: {
|
|
171
|
+
tip: "top-full left-1/2 mt-2",
|
|
172
|
+
transform: "translateX(-50%)",
|
|
173
|
+
origin: "top center",
|
|
174
|
+
tail: "bottom-full left-1/2 -translate-x-1/2 translate-y-1/2 border-l border-t"
|
|
175
|
+
},
|
|
176
|
+
right: {
|
|
177
|
+
tip: "left-full top-1/2 ml-2",
|
|
178
|
+
transform: "translateY(-50%)",
|
|
179
|
+
origin: "center left",
|
|
180
|
+
tail: "right-full top-1/2 translate-x-1/2 -translate-y-1/2 border-l border-b"
|
|
181
|
+
},
|
|
182
|
+
left: {
|
|
183
|
+
tip: "right-full top-1/2 mr-2",
|
|
184
|
+
transform: "translateY(-50%)",
|
|
185
|
+
origin: "center right",
|
|
186
|
+
tail: "left-full top-1/2 -translate-x-1/2 -translate-y-1/2 border-r border-t"
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
/** The mark on a circle for a page that sits above others: layers for a scope, an up arrow for an ancestor page. */
|
|
190
|
+
function LevelIcon({ level }) {
|
|
191
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(level === "scope" ? lucide_react.Layers : lucide_react.ArrowUpToLine, {
|
|
192
|
+
"aria-hidden": true,
|
|
193
|
+
"data-testid": `knowledge-level-icon-${level}`,
|
|
194
|
+
className: "mr-1 inline-block size-3 align-text-bottom"
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/** A page far from the focus: a small coloured dot that names itself on hover. */
|
|
198
|
+
function DotNode({ data }) {
|
|
199
|
+
const { page, size, color, path, ref, links, notShown } = data;
|
|
200
|
+
const [hover, setHover] = (0, react.useState)(false);
|
|
201
|
+
const dotRef = (0, react.useRef)(null);
|
|
202
|
+
const tipRef = (0, react.useRef)(null);
|
|
203
|
+
const [side, setSide] = (0, react.useState)("top");
|
|
204
|
+
const zoom = (0, _xyflow_react.useStore)((state) => state.transform[2]);
|
|
205
|
+
const tipScale = Math.min(Math.max(1 / zoom, 1), TOOLTIP_MAX_SCALE);
|
|
206
|
+
const standIn = require_domains_knowledge_lib_graphShape.isChildPlaceholder(page);
|
|
207
|
+
const group = require_domains_knowledge_lib_graphShape.isScopeGroup(page);
|
|
208
|
+
const hint = standIn ? "Hover or click to load them" : group ? "Click to show them" : null;
|
|
209
|
+
const children = !hint && page.childCount ? `${require_domains_knowledge_lib_pageTree.childCountLabel(page)} ${page.childCount === 1 ? "child" : "children"}` : null;
|
|
210
|
+
const kind = page.isScope ? page.displayLabel ?? "Scope" : "Page";
|
|
211
|
+
const linkText = links && (links.in > 0 || links.out > 0) ? require_domains_knowledge_lib_linkCountsText.linkCountsText(links, notShown) : null;
|
|
212
|
+
const label = [
|
|
213
|
+
page.name,
|
|
214
|
+
hint ?? path,
|
|
215
|
+
children,
|
|
216
|
+
linkText
|
|
217
|
+
].filter(Boolean).join(" · ");
|
|
218
|
+
(0, react.useLayoutEffect)(() => {
|
|
219
|
+
const dot = dotRef.current;
|
|
220
|
+
const tip = tipRef.current;
|
|
221
|
+
const graph = dot?.closest(".knowledge-graph");
|
|
222
|
+
if (!hover || !dot || !tip || !graph) return;
|
|
223
|
+
const dotBox = boxOf(dot);
|
|
224
|
+
const tipBox = boxOf(tip);
|
|
225
|
+
const scaledWidth = tip.offsetWidth * tipScale;
|
|
226
|
+
const scaledHeight = tip.offsetHeight * tipScale;
|
|
227
|
+
if (!scaledWidth || !scaledHeight) return;
|
|
228
|
+
const obstacles = [...graph.querySelectorAll("[data-testid=\"knowledge-page-node\"], [data-testid=\"knowledge-page-dot\"]"), ...(graph.parentElement ?? graph).querySelectorAll("[aria-label=\"Legend\"], [data-testid=\"knowledge-graph-back\"], .react-flow__controls")].map(boxOf).filter((box) => box.right > box.left && !(box.left === tipBox.left && box.top === tipBox.top) && !(box.left === dotBox.left && box.top === dotBox.top));
|
|
229
|
+
setSide(require_domains_knowledge_lib_tooltipSide.chooseTooltipSide({
|
|
230
|
+
dot: dotBox,
|
|
231
|
+
tip: {
|
|
232
|
+
width: scaledWidth,
|
|
233
|
+
height: scaledHeight
|
|
234
|
+
},
|
|
235
|
+
gap: 8,
|
|
236
|
+
bounds: boxOf(graph),
|
|
237
|
+
obstacles,
|
|
238
|
+
lines: drawnLines(graph)
|
|
239
|
+
}));
|
|
240
|
+
}, [hover, tipScale]);
|
|
241
|
+
const placement = TOOLTIP_PLACEMENT[side];
|
|
242
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
243
|
+
ref: dotRef,
|
|
244
|
+
"data-testid": "knowledge-page-dot",
|
|
245
|
+
"data-page-id": page.id,
|
|
246
|
+
"data-page-type": standIn ? "stand-in" : group ? "group" : page.isScope ? "scope" : "page",
|
|
247
|
+
"aria-label": label,
|
|
248
|
+
className: "relative cursor-pointer transition-opacity",
|
|
249
|
+
style: {
|
|
250
|
+
width: size,
|
|
251
|
+
height: size,
|
|
252
|
+
opacity: standIn ? .5 : void 0
|
|
253
|
+
},
|
|
254
|
+
onPointerEnter: () => setHover(true),
|
|
255
|
+
onPointerLeave: () => setHover(false),
|
|
256
|
+
children: [
|
|
257
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
258
|
+
"aria-hidden": true,
|
|
259
|
+
"data-testid": "knowledge-dot-hit-area",
|
|
260
|
+
className: "absolute rounded-full",
|
|
261
|
+
style: { inset: -8 }
|
|
262
|
+
}),
|
|
263
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
264
|
+
className: "size-full rounded-full border",
|
|
265
|
+
style: {
|
|
266
|
+
background: standIn ? "transparent" : color ?? "var(--muted-foreground)",
|
|
267
|
+
borderColor: color ?? "var(--muted-foreground)",
|
|
268
|
+
borderStyle: standIn ? "dashed" : "solid"
|
|
269
|
+
},
|
|
270
|
+
children: data.showCount && !standIn && !group && links && links.in + links.out > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
271
|
+
as: "span",
|
|
272
|
+
variant: "meta",
|
|
273
|
+
"data-testid": "knowledge-dot-count",
|
|
274
|
+
className: "flex size-full items-center justify-center",
|
|
275
|
+
style: { color: "var(--background)" },
|
|
276
|
+
children: links.in + links.out
|
|
277
|
+
}) : null
|
|
278
|
+
}),
|
|
279
|
+
hover ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
280
|
+
role: "tooltip",
|
|
281
|
+
ref: tipRef,
|
|
282
|
+
"data-side": side,
|
|
283
|
+
className: `pointer-events-none absolute ${placement.tip} flex w-max max-w-72 flex-col rounded-md border border-border bg-card px-2 py-1 shadow-overlay`,
|
|
284
|
+
style: {
|
|
285
|
+
transform: `${placement.transform} scale(${tipScale})`,
|
|
286
|
+
transformOrigin: placement.origin
|
|
287
|
+
},
|
|
288
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
289
|
+
"data-testid": "knowledge-tooltip-tail",
|
|
290
|
+
"aria-hidden": true,
|
|
291
|
+
className: `absolute size-2 rotate-45 border-border bg-card ${placement.tail}`
|
|
292
|
+
}), hint ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
293
|
+
as: "span",
|
|
294
|
+
variant: "label",
|
|
295
|
+
tone: "ink",
|
|
296
|
+
children: page.name
|
|
297
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
298
|
+
as: "span",
|
|
299
|
+
variant: "meta",
|
|
300
|
+
tone: "muted",
|
|
301
|
+
children: group ? `${path} · ${hint}` : hint
|
|
302
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_domains_knowledge_components_KnowledgePageCard.KnowledgePageCard, {
|
|
303
|
+
name: page.name,
|
|
304
|
+
kind,
|
|
305
|
+
pageRef: ref,
|
|
306
|
+
path,
|
|
307
|
+
childCount: page.childCount ? require_domains_knowledge_lib_pageTree.childCountLabel(page) : void 0,
|
|
308
|
+
links,
|
|
309
|
+
notShown
|
|
310
|
+
})]
|
|
311
|
+
}) : null,
|
|
312
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Handle, {
|
|
313
|
+
type: "target",
|
|
314
|
+
position: _xyflow_react.Position.Top,
|
|
315
|
+
className: "!invisible"
|
|
316
|
+
}),
|
|
317
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Handle, {
|
|
318
|
+
type: "source",
|
|
319
|
+
position: _xyflow_react.Position.Bottom,
|
|
320
|
+
className: "!invisible"
|
|
321
|
+
})
|
|
322
|
+
]
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/** Below this a circle uses the small type and two lines of name. */
|
|
326
|
+
var COMPACT_CIRCLE_SIZE = 96;
|
|
327
|
+
/** The share of a circle's width its text may use; a circle is narrower toward the top and bottom. */
|
|
328
|
+
var CIRCLE_TEXT_SHARE = .74;
|
|
329
|
+
/** A scope or page: its kind on top, its name below, both inside the circle; far pages draw as dots. */
|
|
66
330
|
function PageNodeComponent({ data }) {
|
|
67
|
-
|
|
331
|
+
if (data.form === "dot") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DotNode, { data });
|
|
332
|
+
const { page, size, selected, pinned, badge } = data;
|
|
333
|
+
const group = require_domains_knowledge_lib_graphShape.isScopeGroup(page);
|
|
68
334
|
const kind = page.isScope ? page.displayLabel ?? "Scope" : "Page";
|
|
69
335
|
const placeholder = isPlaceholder(page);
|
|
336
|
+
const rest = require_domains_knowledge_lib_graphShape.isRestCircle(page);
|
|
337
|
+
const compact = size < COMPACT_CIRCLE_SIZE;
|
|
338
|
+
const fit = Math.max(4, Math.floor(size * CIRCLE_TEXT_SHARE / (compact ? 6.5 : 7.5)));
|
|
70
339
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
71
340
|
"data-testid": "knowledge-page-node",
|
|
72
341
|
"data-page-id": page.id,
|
|
73
|
-
"data-page-type": placeholder ? "placeholder" : page.isScope ? "scope" : "page",
|
|
342
|
+
"data-page-type": placeholder ? "placeholder" : rest ? "rest" : group ? "group" : page.isScope ? "scope" : "page",
|
|
74
343
|
className: `relative transition-opacity ${placeholder ? "cursor-default" : "cursor-pointer"}`,
|
|
75
344
|
style: {
|
|
76
345
|
width: size,
|
|
77
|
-
height: size
|
|
78
|
-
opacity: dimmed ? .35 : 1
|
|
346
|
+
height: size
|
|
79
347
|
},
|
|
80
|
-
title: placeholder ? `${kind} · ${page.address} · nothing written to it yet` : page.isScope && page.address ? `${kind} · ${page.address}` : page.name,
|
|
348
|
+
title: placeholder ? `${kind} · ${page.address} · nothing written to it yet` : rest ? `Show ${Math.min(12, page.childCount ?? 12)} more of ${page.childCount ?? "the rest"}` : group ? `${page.name}: click to show them` : page.isScope && page.address ? `${kind} · ${page.address}` : data.links && data.links.in + data.links.out > 0 ? `${page.name} · ${require_domains_knowledge_lib_linkCountsText.linkCountsText(data.links, data.notShown)}` : page.name,
|
|
81
349
|
children: [
|
|
82
350
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
83
|
-
className:
|
|
351
|
+
className: `knowledge-circle flex size-full flex-col items-center justify-center gap-0.5 overflow-hidden rounded-full border-2 text-center shadow-raised ${rest ? "hover:border-foreground" : ""}`,
|
|
84
352
|
"data-selected": selected || void 0,
|
|
85
|
-
|
|
86
|
-
|
|
353
|
+
"data-far": data.far || void 0,
|
|
354
|
+
style: {
|
|
355
|
+
...placeholder || rest ? PLACEHOLDER_STYLE : data.far ? FAR_STYLE : page.isScope ? SCOPE_STYLE : PAGE_STYLE,
|
|
356
|
+
paddingInline: size * (.26 / 2)
|
|
357
|
+
},
|
|
358
|
+
children: [data.far ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
|
|
87
359
|
as: "span",
|
|
88
360
|
variant: "meta",
|
|
89
361
|
tone: page.isScope ? void 0 : "muted",
|
|
90
|
-
className: "pointer-events-none
|
|
362
|
+
className: "pointer-events-none inline-flex max-w-full items-center justify-center gap-1 whitespace-nowrap uppercase",
|
|
91
363
|
style: page.isScope ? { color: "var(--chart-blue)" } : void 0,
|
|
92
364
|
"data-testid": page.isScope ? "knowledge-scope-caption" : "knowledge-page-caption",
|
|
93
|
-
children:
|
|
365
|
+
children: [data.level ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LevelIcon, { level: data.level }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
366
|
+
className: "truncate",
|
|
367
|
+
children: rest ? "More" : data.isParent ? "Parent" : kind
|
|
368
|
+
})]
|
|
94
369
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
95
370
|
as: "span",
|
|
96
|
-
variant: "label",
|
|
371
|
+
variant: compact ? "meta" : "label",
|
|
97
372
|
tone: "ink",
|
|
98
|
-
className:
|
|
99
|
-
|
|
373
|
+
className: `pointer-events-none max-w-full overflow-hidden [overflow-wrap:normal] ${compact ? "line-clamp-2" : "line-clamp-3"}`,
|
|
374
|
+
style: data.far ? { color: "var(--background)" } : void 0,
|
|
375
|
+
"data-testid": "knowledge-circle-name",
|
|
376
|
+
children: page.isScope && page.address && !group ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BreakAtColons, { text: require_domains_knowledge_lib_circleText.fitWords(page.address, fit) }) : require_domains_knowledge_lib_circleText.fitWords(page.name, fit)
|
|
100
377
|
})]
|
|
101
378
|
}),
|
|
102
379
|
pinned ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinBadge, { size }) : null,
|
|
380
|
+
data.hiddenLinks && (data.hiddenLinks.in > 0 || data.hiddenLinks.out > 0) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
381
|
+
"data-testid": "knowledge-hidden-links",
|
|
382
|
+
title: require_domains_knowledge_lib_linkCountsText.linkCountsText(data.hiddenLinks),
|
|
383
|
+
"aria-label": require_domains_knowledge_lib_linkCountsText.linkCountsText(data.hiddenLinks),
|
|
384
|
+
className: "absolute bottom-full left-1/2 -mb-1 flex -translate-x-1/2 gap-1 rounded-full border border-border bg-card px-1.5 shadow-raised",
|
|
385
|
+
children: [data.hiddenLinks.in > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
|
|
386
|
+
as: "span",
|
|
387
|
+
variant: "meta",
|
|
388
|
+
style: { color: "var(--chart-orange)" },
|
|
389
|
+
children: ["→", data.hiddenLinks.in]
|
|
390
|
+
}) : null, data.hiddenLinks.out > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
|
|
391
|
+
as: "span",
|
|
392
|
+
variant: "meta",
|
|
393
|
+
style: { color: LINK_EDGE_COLOR },
|
|
394
|
+
children: [data.hiddenLinks.out, "→"]
|
|
395
|
+
}) : null]
|
|
396
|
+
}) : null,
|
|
397
|
+
badge ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
398
|
+
"data-testid": "knowledge-child-count-badge",
|
|
399
|
+
"aria-label": `${badge} children, not all drawn`,
|
|
400
|
+
className: "absolute top-full left-1/2 -mt-1 -translate-x-1/2 rounded-full border border-border bg-card px-1.5 shadow-raised",
|
|
401
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
402
|
+
as: "span",
|
|
403
|
+
variant: "meta",
|
|
404
|
+
tone: "ink",
|
|
405
|
+
children: badge
|
|
406
|
+
})
|
|
407
|
+
}) : null,
|
|
103
408
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Handle, {
|
|
104
409
|
type: "target",
|
|
105
410
|
position: _xyflow_react.Position.Top,
|
|
@@ -156,10 +461,7 @@ function RimEdgeComponent({ id, data, style, markerEnd }) {
|
|
|
156
461
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.BaseEdge, {
|
|
157
462
|
id,
|
|
158
463
|
path,
|
|
159
|
-
style
|
|
160
|
-
...style,
|
|
161
|
-
opacity: data.dimmed ? .2 : 1
|
|
162
|
-
},
|
|
464
|
+
style,
|
|
163
465
|
markerEnd,
|
|
164
466
|
interactionWidth: mention ? 20 : 0
|
|
165
467
|
}), data.kind === "grant" && data.role ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
@@ -173,7 +475,7 @@ function RimEdgeComponent({ id, data, style, markerEnd }) {
|
|
|
173
475
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("title", { children: `Grants ${data.role}` })
|
|
174
476
|
}) : null] });
|
|
175
477
|
}
|
|
176
|
-
var edgeTypes = { rim: RimEdgeComponent };
|
|
478
|
+
var edgeTypes = { rim: (0, react.memo)(RimEdgeComponent) };
|
|
177
479
|
var nodeTypes = { page: (0, react.memo)(PageNodeComponent) };
|
|
178
480
|
/** The box around laid-out circles, in graph coordinates; `null` when there are none. */
|
|
179
481
|
function graphBounds(nodes) {
|
|
@@ -197,7 +499,7 @@ function graphBounds(nodes) {
|
|
|
197
499
|
}
|
|
198
500
|
var LEGEND_SWATCH = "knowledge-circle inline-block size-3 shrink-0 rounded-full border-2";
|
|
199
501
|
/** What the circles, lines and badge mean. */
|
|
200
|
-
function GraphLegend({
|
|
502
|
+
function GraphLegend({ drawn, counts, dots, linkEnds, focused, levels, branches }) {
|
|
201
503
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
|
|
202
504
|
"aria-label": "Legend",
|
|
203
505
|
className: "pointer-events-none absolute top-2 left-2 z-10 flex flex-col gap-1 rounded-md border border-border bg-card/90 px-2 py-1.5 shadow-raised",
|
|
@@ -215,6 +517,32 @@ function GraphLegend({ grants }) {
|
|
|
215
517
|
children: "Scope"
|
|
216
518
|
})]
|
|
217
519
|
}),
|
|
520
|
+
levels.includes("scope") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
521
|
+
className: "flex items-center gap-2",
|
|
522
|
+
"data-testid": "knowledge-legend-level-scope",
|
|
523
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Layers, {
|
|
524
|
+
"aria-hidden": true,
|
|
525
|
+
className: "size-3 shrink-0 text-muted-foreground"
|
|
526
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
527
|
+
as: "span",
|
|
528
|
+
variant: "meta",
|
|
529
|
+
tone: "muted",
|
|
530
|
+
children: "Scope, above its pages"
|
|
531
|
+
})]
|
|
532
|
+
}) : null,
|
|
533
|
+
levels.includes("ancestor") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
534
|
+
className: "flex items-center gap-2",
|
|
535
|
+
"data-testid": "knowledge-legend-level-ancestor",
|
|
536
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUpToLine, {
|
|
537
|
+
"aria-hidden": true,
|
|
538
|
+
className: "size-3 shrink-0 text-muted-foreground"
|
|
539
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
540
|
+
as: "span",
|
|
541
|
+
variant: "meta",
|
|
542
|
+
tone: "muted",
|
|
543
|
+
children: "Page above the focus"
|
|
544
|
+
})]
|
|
545
|
+
}) : null,
|
|
218
546
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
219
547
|
className: "flex items-center gap-2",
|
|
220
548
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -228,8 +556,122 @@ function GraphLegend({ grants }) {
|
|
|
228
556
|
children: "Page"
|
|
229
557
|
})]
|
|
230
558
|
}),
|
|
231
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
559
|
+
focused ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
560
|
+
className: "flex items-center gap-2",
|
|
561
|
+
"data-testid": "knowledge-legend-focused",
|
|
562
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
563
|
+
className: LEGEND_SWATCH,
|
|
564
|
+
style: {
|
|
565
|
+
...PAGE_STYLE,
|
|
566
|
+
outline: "2px solid var(--knowledge-color)",
|
|
567
|
+
outlineOffset: 2,
|
|
568
|
+
borderWidth: 3
|
|
569
|
+
},
|
|
570
|
+
"aria-hidden": true
|
|
571
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
572
|
+
as: "span",
|
|
573
|
+
variant: "meta",
|
|
574
|
+
tone: "muted",
|
|
575
|
+
children: "Focused page"
|
|
576
|
+
})]
|
|
577
|
+
}) : null,
|
|
578
|
+
dots || linkEnds ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
579
|
+
className: "flex items-center gap-2",
|
|
580
|
+
"data-testid": "knowledge-legend-dot",
|
|
581
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
582
|
+
className: "inline-block size-2 shrink-0 rounded-full bg-muted-foreground",
|
|
583
|
+
"aria-hidden": true
|
|
584
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
585
|
+
as: "span",
|
|
586
|
+
variant: "meta",
|
|
587
|
+
tone: "muted",
|
|
588
|
+
children: "Page in another branch"
|
|
589
|
+
})]
|
|
590
|
+
}) : null,
|
|
591
|
+
branches.slice(0, LEGEND_BRANCH_CAP).map((branch) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
592
|
+
className: "flex items-center gap-2 pl-0.5",
|
|
593
|
+
"data-testid": "knowledge-legend-branch",
|
|
594
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
595
|
+
className: "inline-block size-2 shrink-0 rounded-full",
|
|
596
|
+
style: { background: branch.color },
|
|
597
|
+
"aria-hidden": true
|
|
598
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
599
|
+
as: "span",
|
|
600
|
+
variant: "meta",
|
|
601
|
+
tone: "muted",
|
|
602
|
+
className: "max-w-40 truncate",
|
|
603
|
+
title: branch.name,
|
|
604
|
+
children: branches.length > 1 ? `Under ${branch.name}` : branch.scope ? "Under parent scope" : "Under parent page"
|
|
605
|
+
})]
|
|
606
|
+
}, branch.id)),
|
|
607
|
+
branches.length > LEGEND_BRANCH_CAP ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
|
|
608
|
+
className: "pl-0.5",
|
|
609
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Txt.Txt, {
|
|
610
|
+
as: "span",
|
|
611
|
+
variant: "meta",
|
|
612
|
+
tone: "muted",
|
|
613
|
+
children: [
|
|
614
|
+
"+",
|
|
615
|
+
branches.length - LEGEND_BRANCH_CAP,
|
|
616
|
+
" more branches"
|
|
617
|
+
]
|
|
618
|
+
})
|
|
619
|
+
}) : null,
|
|
620
|
+
drawn.has("out") || drawn.has("in") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [drawn.has("out") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
232
621
|
className: "flex items-center gap-2",
|
|
622
|
+
"data-testid": "knowledge-legend-out",
|
|
623
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
624
|
+
width: "16",
|
|
625
|
+
height: "8",
|
|
626
|
+
"aria-hidden": true,
|
|
627
|
+
className: "shrink-0",
|
|
628
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
629
|
+
x1: "0",
|
|
630
|
+
y1: "4",
|
|
631
|
+
x2: "12",
|
|
632
|
+
y2: "4",
|
|
633
|
+
stroke: LINK_EDGE_COLOR,
|
|
634
|
+
strokeWidth: "1.5"
|
|
635
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
|
|
636
|
+
points: "11,1 16,4 11,7",
|
|
637
|
+
fill: LINK_EDGE_COLOR
|
|
638
|
+
})]
|
|
639
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
640
|
+
as: "span",
|
|
641
|
+
variant: "meta",
|
|
642
|
+
tone: "muted",
|
|
643
|
+
children: "Links out of the selected page"
|
|
644
|
+
})]
|
|
645
|
+
}) : null, drawn.has("in") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
646
|
+
className: "flex items-center gap-2",
|
|
647
|
+
"data-testid": "knowledge-legend-in",
|
|
648
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
649
|
+
width: "16",
|
|
650
|
+
height: "8",
|
|
651
|
+
"aria-hidden": true,
|
|
652
|
+
className: "shrink-0",
|
|
653
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
654
|
+
x1: "0",
|
|
655
|
+
y1: "4",
|
|
656
|
+
x2: "12",
|
|
657
|
+
y2: "4",
|
|
658
|
+
stroke: "var(--chart-orange)",
|
|
659
|
+
strokeWidth: "1.5",
|
|
660
|
+
strokeDasharray: "3 2"
|
|
661
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
|
|
662
|
+
points: "11,1 16,4 11,7",
|
|
663
|
+
fill: "var(--chart-orange)"
|
|
664
|
+
})]
|
|
665
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
666
|
+
as: "span",
|
|
667
|
+
variant: "meta",
|
|
668
|
+
tone: "muted",
|
|
669
|
+
children: "Links into it"
|
|
670
|
+
})]
|
|
671
|
+
}) : null] }) : null,
|
|
672
|
+
drawn.has("mention") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
673
|
+
className: "flex items-center gap-2",
|
|
674
|
+
"data-testid": "knowledge-legend-mention",
|
|
233
675
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
234
676
|
width: "12",
|
|
235
677
|
height: "4",
|
|
@@ -249,8 +691,81 @@ function GraphLegend({ grants }) {
|
|
|
249
691
|
tone: "muted",
|
|
250
692
|
children: "Mentioned in notes"
|
|
251
693
|
})]
|
|
252
|
-
}),
|
|
253
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
694
|
+
}) : null,
|
|
695
|
+
drawn.has("link") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
696
|
+
className: "flex items-center gap-2",
|
|
697
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
698
|
+
width: "16",
|
|
699
|
+
height: "8",
|
|
700
|
+
"aria-hidden": true,
|
|
701
|
+
className: "shrink-0",
|
|
702
|
+
"data-testid": "knowledge-legend-link",
|
|
703
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
704
|
+
x1: "0",
|
|
705
|
+
y1: "4",
|
|
706
|
+
x2: "12",
|
|
707
|
+
y2: "4",
|
|
708
|
+
...LINK_EDGE_STYLE
|
|
709
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
|
|
710
|
+
points: "11,1 16,4 11,7",
|
|
711
|
+
fill: LINK_EDGE_COLOR
|
|
712
|
+
})]
|
|
713
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
714
|
+
as: "span",
|
|
715
|
+
variant: "meta",
|
|
716
|
+
tone: "muted",
|
|
717
|
+
children: "Linked in page body"
|
|
718
|
+
})]
|
|
719
|
+
}) : null,
|
|
720
|
+
drawn.has("dot-parent") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
721
|
+
className: "flex items-center gap-2",
|
|
722
|
+
"data-testid": "knowledge-legend-dot-parent",
|
|
723
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
724
|
+
width: "16",
|
|
725
|
+
height: "4",
|
|
726
|
+
"aria-hidden": true,
|
|
727
|
+
className: "shrink-0",
|
|
728
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
729
|
+
x1: "0",
|
|
730
|
+
y1: "2",
|
|
731
|
+
x2: "16",
|
|
732
|
+
y2: "2",
|
|
733
|
+
...DOT_PARENT_EDGE_STYLE,
|
|
734
|
+
strokeOpacity: .5
|
|
735
|
+
})
|
|
736
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
737
|
+
as: "span",
|
|
738
|
+
variant: "meta",
|
|
739
|
+
tone: "muted",
|
|
740
|
+
children: "Child page (dot)"
|
|
741
|
+
})]
|
|
742
|
+
}) : null,
|
|
743
|
+
drawn.has("up") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
744
|
+
className: "flex items-center gap-2",
|
|
745
|
+
"data-testid": "knowledge-legend-up",
|
|
746
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
747
|
+
width: "16",
|
|
748
|
+
height: "8",
|
|
749
|
+
"aria-hidden": true,
|
|
750
|
+
className: "shrink-0",
|
|
751
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("line", {
|
|
752
|
+
x1: "0",
|
|
753
|
+
y1: "4",
|
|
754
|
+
x2: "12",
|
|
755
|
+
y2: "4",
|
|
756
|
+
...UP_EDGE_STYLE
|
|
757
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polygon", {
|
|
758
|
+
points: "9,1 15,4 9,7",
|
|
759
|
+
fill: UP_EDGE_COLOR
|
|
760
|
+
})]
|
|
761
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
762
|
+
as: "span",
|
|
763
|
+
variant: "meta",
|
|
764
|
+
tone: "muted",
|
|
765
|
+
children: "Parent of the focused page"
|
|
766
|
+
})]
|
|
767
|
+
}) : null,
|
|
768
|
+
drawn.has("parent") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
254
769
|
className: "flex items-center gap-2",
|
|
255
770
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
256
771
|
width: "16",
|
|
@@ -279,8 +794,32 @@ function GraphLegend({ grants }) {
|
|
|
279
794
|
tone: "muted",
|
|
280
795
|
children: "Parent → child"
|
|
281
796
|
})]
|
|
282
|
-
}),
|
|
283
|
-
|
|
797
|
+
}) : null,
|
|
798
|
+
counts ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
799
|
+
className: "flex items-center gap-2",
|
|
800
|
+
"data-testid": "knowledge-legend-link-counts",
|
|
801
|
+
children: [
|
|
802
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
803
|
+
as: "span",
|
|
804
|
+
variant: "meta",
|
|
805
|
+
style: { color: "var(--chart-orange)" },
|
|
806
|
+
children: "→4"
|
|
807
|
+
}),
|
|
808
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
809
|
+
as: "span",
|
|
810
|
+
variant: "meta",
|
|
811
|
+
style: { color: LINK_EDGE_COLOR },
|
|
812
|
+
children: "14→"
|
|
813
|
+
}),
|
|
814
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
815
|
+
as: "span",
|
|
816
|
+
variant: "meta",
|
|
817
|
+
tone: "muted",
|
|
818
|
+
children: "Links in, links out (not drawn)"
|
|
819
|
+
})
|
|
820
|
+
]
|
|
821
|
+
}) : null,
|
|
822
|
+
drawn.has("grant") ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
284
823
|
className: "flex items-center gap-2",
|
|
285
824
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
286
825
|
width: "16",
|
|
@@ -325,14 +864,82 @@ function GraphLegend({ grants }) {
|
|
|
325
864
|
}
|
|
326
865
|
/** How far the pointer may move between press and release and still count as a click, not a pan. */
|
|
327
866
|
var CLICK_SLOP_PX = 4;
|
|
867
|
+
/** Marks the nodes and lines that stay lit while the rest of the graph fades (see knowledge.css). */
|
|
868
|
+
var NEIGHBOUR_CLASS = "knowledge-neighbour";
|
|
869
|
+
/**
|
|
870
|
+
* The same edge objects while their content is unchanged. Pointing at a page changes the style of the
|
|
871
|
+
* few lines touching it; handing React Flow fresh objects for every line would redraw them all.
|
|
872
|
+
*/
|
|
873
|
+
function useStableEdges(edges) {
|
|
874
|
+
const seen = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
875
|
+
return (0, react.useMemo)(() => {
|
|
876
|
+
const next = /* @__PURE__ */ new Map();
|
|
877
|
+
const result = edges.map((edge) => {
|
|
878
|
+
const sig = JSON.stringify(edge);
|
|
879
|
+
const before = seen.current.get(edge.id);
|
|
880
|
+
const entry = before && before.sig === sig ? before : {
|
|
881
|
+
sig,
|
|
882
|
+
edge
|
|
883
|
+
};
|
|
884
|
+
next.set(edge.id, entry);
|
|
885
|
+
return entry.edge;
|
|
886
|
+
});
|
|
887
|
+
seen.current = next;
|
|
888
|
+
return result;
|
|
889
|
+
}, [edges]);
|
|
890
|
+
}
|
|
891
|
+
/** The focused page's circle is this much larger than its neighbours'. */
|
|
892
|
+
var FOCUSED_SCALE = 1.2;
|
|
893
|
+
/** Pages in other branches that the focus links to draw a little smaller than its own neighbours. */
|
|
894
|
+
var LINK_END_SCALE = .8;
|
|
895
|
+
/** Most branch colours the legend names; the rest are counted. */
|
|
896
|
+
var LEGEND_BRANCH_CAP = 4;
|
|
897
|
+
/** Most links a hovered page draws that aren't drawn already. */
|
|
898
|
+
var HOVER_LINK_CAP = 40;
|
|
328
899
|
/**
|
|
329
900
|
* The schema-4 Knowledge page graph: scopes and pages as circles sized by how often they are mentioned,
|
|
330
901
|
* parent links as faint edges and mentions as solid ones. The first layout is deterministic for the same pages; later updates start from where pages already sit.
|
|
331
902
|
*/
|
|
332
903
|
function KnowledgePageGraph(props) {
|
|
333
|
-
|
|
904
|
+
const { settled = true } = props;
|
|
905
|
+
const held = (0, react.useRef)(props);
|
|
906
|
+
const [released, setReleased] = (0, react.useState)(false);
|
|
907
|
+
const holding = !settled && !released;
|
|
908
|
+
if (!holding) held.current = props;
|
|
909
|
+
const shown = !holding ? props : {
|
|
910
|
+
...props,
|
|
911
|
+
pages: held.current.pages,
|
|
912
|
+
edges: held.current.edges,
|
|
913
|
+
pinnedIds: held.current.pinnedIds,
|
|
914
|
+
grants: held.current.grants,
|
|
915
|
+
selectedPageId: held.current.selectedPageId,
|
|
916
|
+
centerId: held.current.centerId,
|
|
917
|
+
hiddenLinks: held.current.hiddenLinks,
|
|
918
|
+
knownLinks: held.current.knownLinks,
|
|
919
|
+
nearIds: held.current.nearIds
|
|
920
|
+
};
|
|
921
|
+
const [slow, setSlow] = (0, react.useState)(false);
|
|
922
|
+
(0, react.useEffect)(() => {
|
|
923
|
+
if (settled) {
|
|
924
|
+
setSlow(false);
|
|
925
|
+
setReleased(false);
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const hint = setTimeout(() => setSlow(true), LOADING_HINT_DELAY_MS);
|
|
929
|
+
const deadline = setTimeout(() => setReleased(true), LOADING_RELEASE_MS);
|
|
930
|
+
return () => {
|
|
931
|
+
clearTimeout(hint);
|
|
932
|
+
clearTimeout(deadline);
|
|
933
|
+
};
|
|
934
|
+
}, [settled, props.selectedPageId]);
|
|
935
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_xyflow_react.ReactFlowProvider, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(KnowledgePageGraphInner, { ...shown }), slow && holding ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
936
|
+
role: "status",
|
|
937
|
+
"data-testid": "knowledge-graph-loading",
|
|
938
|
+
className: "text-ui-sm pointer-events-none absolute bottom-3 left-1/2 z-10 -translate-x-1/2 rounded border border-border bg-card px-3 py-1 text-muted-foreground shadow-overlay",
|
|
939
|
+
children: "Loading pages…"
|
|
940
|
+
}) : null] });
|
|
334
941
|
}
|
|
335
|
-
function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selectedPageId, onSelect, onOpen, onClearSelection, onMentionSelect }) {
|
|
942
|
+
function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selectedPageId, centerId, hiddenLinks, knownLinks, nearIds, exactLinkCounts, fetchedLinks, onHover, showCounts, onPreview, onSelect, onOpen, onClearSelection, onMentionSelect }) {
|
|
336
943
|
const { graphPages, allEdges } = (0, react.useMemo)(() => {
|
|
337
944
|
const granted = require_domains_knowledge_lib_pageGraph.grantGraph(pages, grants);
|
|
338
945
|
return {
|
|
@@ -344,28 +951,167 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
344
951
|
edges,
|
|
345
952
|
grants
|
|
346
953
|
]);
|
|
347
|
-
const
|
|
954
|
+
const linkSource = knownLinks ?? edges;
|
|
955
|
+
const linkCounts = (0, react.useMemo)(() => {
|
|
956
|
+
const counts = /* @__PURE__ */ new Map();
|
|
957
|
+
const pairs = /* @__PURE__ */ new Set();
|
|
958
|
+
for (const edge of linkSource) {
|
|
959
|
+
if (edge.kind !== "mention" && edge.kind !== "link") continue;
|
|
960
|
+
if (edge.source === edge.target || pairs.has(`${edge.source}\u0000${edge.target}`)) continue;
|
|
961
|
+
pairs.add(`${edge.source}\u0000${edge.target}`);
|
|
962
|
+
const out = counts.get(edge.source) ?? {
|
|
963
|
+
in: 0,
|
|
964
|
+
out: 0
|
|
965
|
+
};
|
|
966
|
+
out.out++;
|
|
967
|
+
counts.set(edge.source, out);
|
|
968
|
+
const into = counts.get(edge.target) ?? {
|
|
969
|
+
in: 0,
|
|
970
|
+
out: 0
|
|
971
|
+
};
|
|
972
|
+
into.in++;
|
|
973
|
+
counts.set(edge.target, into);
|
|
974
|
+
}
|
|
975
|
+
for (const [id, exact] of exactLinkCounts ?? []) counts.set(id, exact);
|
|
976
|
+
return counts;
|
|
977
|
+
}, [linkSource, exactLinkCounts]);
|
|
978
|
+
const hoverLinks = (0, react.useMemo)(() => {
|
|
979
|
+
const touching = /* @__PURE__ */ new Map();
|
|
980
|
+
const add = (id, edge) => {
|
|
981
|
+
const list = touching.get(id);
|
|
982
|
+
if (list) list.push(edge);
|
|
983
|
+
else touching.set(id, [edge]);
|
|
984
|
+
};
|
|
985
|
+
for (const edge of [...linkSource, ...fetchedLinks ?? []]) {
|
|
986
|
+
if (edge.kind !== "mention" && edge.kind !== "link") continue;
|
|
987
|
+
add(edge.source, edge);
|
|
988
|
+
if (edge.target !== edge.source) add(edge.target, edge);
|
|
989
|
+
}
|
|
990
|
+
return touching;
|
|
991
|
+
}, [linkSource, fetchedLinks]);
|
|
348
992
|
const laidOut = (0, react.useMemo)(() => {
|
|
993
|
+
const shape = require_domains_knowledge_lib_graphShape.graphShape(graphPages, selectedPageId ?? centerId ?? null, nearIds);
|
|
994
|
+
const colors = require_domains_knowledge_lib_graphShape.branchColors(graphPages, shape);
|
|
349
995
|
const flow = require_domains_knowledge_lib_pageGraph.toPageFlow(graphPages, allEdges);
|
|
350
|
-
const
|
|
996
|
+
for (const node of flow.nodes) if (shape.form.get(node.id) === "dot") {
|
|
997
|
+
const links = linkCounts.get(node.id);
|
|
998
|
+
const counted = showCounts && !require_domains_knowledge_lib_graphShape.isChildPlaceholder(node.data.page) && !!links && links.in + links.out > 0;
|
|
999
|
+
node.data.size = counted ? 28 : 20;
|
|
1000
|
+
} else if (node.id === shape.center) node.data.size = Math.round(node.data.size * FOCUSED_SCALE);
|
|
1001
|
+
else node.data.size = Math.round(108 * (shape.linked.has(node.id) ? LINK_END_SCALE : 1));
|
|
1002
|
+
const ring = flow.nodes.filter((node) => shape.depth.get(node.id) === 1 && shape.form.get(node.id) === "full");
|
|
1003
|
+
const crowd = require_domains_knowledge_lib_graphShape.crowdScale(ring.length);
|
|
1004
|
+
if (crowd < 1) for (const node of ring) node.data.size = Math.round(node.data.size * crowd);
|
|
1005
|
+
const sizes = new Map(flow.nodes.map((node) => [node.id, node.data.size]));
|
|
1006
|
+
const radial = require_domains_knowledge_lib_graphShape.radialLayout(graphPages, shape, (page) => sizes.get(page.id) ?? 20, nearIds);
|
|
1007
|
+
const positions = require_domains_knowledge_lib_layout.runLayout(flow.nodes.map((node) => ({
|
|
351
1008
|
id: node.id,
|
|
352
|
-
size: node.data.size
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
})));
|
|
357
|
-
lastLayout.current = layout;
|
|
1009
|
+
size: node.data.size,
|
|
1010
|
+
padding: shape.form.get(node.id) === "dot" ? 4 : 24,
|
|
1011
|
+
initial: radial.get(node.id)
|
|
1012
|
+
})), [], { ticks: 0 });
|
|
358
1013
|
return {
|
|
359
1014
|
nodes: flow.nodes,
|
|
360
1015
|
edges: flow.edges,
|
|
361
|
-
positions
|
|
1016
|
+
positions,
|
|
1017
|
+
shape,
|
|
1018
|
+
colors
|
|
362
1019
|
};
|
|
363
|
-
}, [
|
|
364
|
-
|
|
365
|
-
|
|
1020
|
+
}, [
|
|
1021
|
+
graphPages,
|
|
1022
|
+
allEdges,
|
|
366
1023
|
selectedPageId,
|
|
1024
|
+
centerId,
|
|
1025
|
+
linkCounts,
|
|
1026
|
+
showCounts,
|
|
1027
|
+
nearIds
|
|
1028
|
+
]);
|
|
1029
|
+
const pageById = (0, react.useMemo)(() => new Map(graphPages.map((page) => [page.id, page])), [graphPages]);
|
|
1030
|
+
const focusParentId = (0, react.useMemo)(() => {
|
|
1031
|
+
const parentId = laidOut.shape.center ? pageById.get(laidOut.shape.center)?.parentId : void 0;
|
|
1032
|
+
return parentId && laidOut.positions.has(parentId) ? parentId : null;
|
|
1033
|
+
}, [laidOut, pageById]);
|
|
1034
|
+
const drawnLevels = (0, react.useMemo)(() => {
|
|
1035
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
1036
|
+
for (const [id, level] of laidOut.shape.level) if (laidOut.shape.form.get(id) === "full") kinds.add(level);
|
|
1037
|
+
return [...kinds];
|
|
1038
|
+
}, [laidOut]);
|
|
1039
|
+
const dotBranches = (0, react.useMemo)(() => {
|
|
1040
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1041
|
+
for (const node of laidOut.nodes) {
|
|
1042
|
+
if (laidOut.shape.form.get(node.id) !== "dot" || require_domains_knowledge_lib_graphShape.isChildPlaceholder(node.data.page)) continue;
|
|
1043
|
+
const branch = laidOut.shape.branch.get(node.id);
|
|
1044
|
+
const color = branch ? laidOut.colors.get(branch) : void 0;
|
|
1045
|
+
const owner = branch ? pageById.get(branch) : void 0;
|
|
1046
|
+
if (branch && color && owner && !seen.has(branch)) seen.set(branch, {
|
|
1047
|
+
id: branch,
|
|
1048
|
+
name: owner.displayLabel ?? owner.name,
|
|
1049
|
+
color,
|
|
1050
|
+
scope: !!owner.isScope
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
return [...seen.values()];
|
|
1054
|
+
}, [laidOut, pageById]);
|
|
1055
|
+
const pinned = (0, react.useMemo)(() => new Set(pinnedIds), [pinnedIds]);
|
|
1056
|
+
const childrenUndrawn = (0, react.useMemo)(() => {
|
|
1057
|
+
const drawn = /* @__PURE__ */ new Map();
|
|
1058
|
+
for (const page of graphPages) if (page.parentId && !require_domains_knowledge_lib_graphShape.isChildPlaceholder(page) && !require_domains_knowledge_lib_graphShape.isRestCircle(page)) drawn.set(page.parentId, (drawn.get(page.parentId) ?? 0) + 1);
|
|
1059
|
+
return new Set(graphPages.filter((page) => !require_domains_knowledge_lib_graphShape.isScopeGroup(page) && !require_domains_knowledge_lib_graphShape.isRestCircle(page) && (page.childCountCapped || (page.childCount ?? 0) > (drawn.get(page.id) ?? 0))).map((page) => page.id));
|
|
1060
|
+
}, [graphPages]);
|
|
1061
|
+
const [hoveredId, setHoveredId] = (0, react.useState)(null);
|
|
1062
|
+
(0, react.useEffect)(() => onHover?.(hoveredId), [hoveredId, onHover]);
|
|
1063
|
+
const hoverExtra = (0, react.useMemo)(() => {
|
|
1064
|
+
if (!hoveredId) return [];
|
|
1065
|
+
const drawnIds = new Set(laidOut.nodes.map((node) => node.id));
|
|
1066
|
+
const have = new Set(laidOut.edges.map((edge) => edge.id));
|
|
1067
|
+
const extra = [];
|
|
1068
|
+
for (const edge of hoverLinks.get(hoveredId) ?? []) {
|
|
1069
|
+
const id = `${edge.kind}:${edge.source}->${edge.target}`;
|
|
1070
|
+
if (have.has(id) || !drawnIds.has(edge.source) || !drawnIds.has(edge.target)) continue;
|
|
1071
|
+
have.add(id);
|
|
1072
|
+
extra.push({
|
|
1073
|
+
id,
|
|
1074
|
+
source: edge.source,
|
|
1075
|
+
target: edge.target,
|
|
1076
|
+
data: {
|
|
1077
|
+
kind: edge.kind,
|
|
1078
|
+
count: edge.count ?? 1
|
|
1079
|
+
}
|
|
1080
|
+
});
|
|
1081
|
+
if (extra.length >= HOVER_LINK_CAP) break;
|
|
1082
|
+
}
|
|
1083
|
+
return extra;
|
|
1084
|
+
}, [
|
|
1085
|
+
hoveredId,
|
|
1086
|
+
hoverLinks,
|
|
1087
|
+
laidOut
|
|
1088
|
+
]);
|
|
1089
|
+
const hoveredNotShown = (0, react.useMemo)(() => {
|
|
1090
|
+
const total = hoveredId ? linkCounts.get(hoveredId) : void 0;
|
|
1091
|
+
if (!hoveredId || !total) return 0;
|
|
1092
|
+
const pairs = /* @__PURE__ */ new Set();
|
|
1093
|
+
for (const edge of [...laidOut.edges, ...hoverExtra]) {
|
|
1094
|
+
const kind = edge.data?.kind;
|
|
1095
|
+
if (kind !== "mention" && kind !== "link" || edge.source !== hoveredId && edge.target !== hoveredId) continue;
|
|
1096
|
+
pairs.add(`${edge.source}\u0000${edge.target}`);
|
|
1097
|
+
}
|
|
1098
|
+
return Math.max(0, total.in + total.out - pairs.size);
|
|
1099
|
+
}, [
|
|
1100
|
+
hoveredId,
|
|
1101
|
+
linkCounts,
|
|
367
1102
|
laidOut,
|
|
368
|
-
|
|
1103
|
+
hoverExtra
|
|
1104
|
+
]);
|
|
1105
|
+
const emphasisId = hoveredId && laidOut.positions.has(hoveredId) ? hoveredId : selectedPageId ?? null;
|
|
1106
|
+
const neighbours = (0, react.useMemo)(() => emphasisId && laidOut.positions.has(emphasisId) ? require_domains_knowledge_lib_pageGraph.pageNeighbourIds(emphasisId, [...allEdges, ...hoverExtra.map((edge) => ({
|
|
1107
|
+
kind: edge.data?.kind ?? "link",
|
|
1108
|
+
source: edge.source,
|
|
1109
|
+
target: edge.target
|
|
1110
|
+
}))]) : null, [
|
|
1111
|
+
emphasisId,
|
|
1112
|
+
laidOut,
|
|
1113
|
+
allEdges,
|
|
1114
|
+
hoverExtra
|
|
369
1115
|
]);
|
|
370
1116
|
const nodes = (0, react.useMemo)(() => laidOut.nodes.map((node) => {
|
|
371
1117
|
const center = laidOut.positions.get(node.id) ?? {
|
|
@@ -399,16 +1145,32 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
399
1145
|
...node.data,
|
|
400
1146
|
selected: node.id === selectedPageId,
|
|
401
1147
|
pinned: pinned.has(node.id),
|
|
402
|
-
|
|
1148
|
+
form: laidOut.shape.form.get(node.id) ?? "full",
|
|
1149
|
+
color: laidOut.colors.get(laidOut.shape.branch.get(node.id) ?? ""),
|
|
1150
|
+
badge: childrenUndrawn.has(node.id) ? require_domains_knowledge_lib_pageTree.childCountLabel(node.data.page) : void 0,
|
|
1151
|
+
path: require_domains_knowledge_lib_pageAddress.pagePath(node.data.page, pageById),
|
|
1152
|
+
hiddenLinks: laidOut.shape.form.get(node.id) === "full" ? hiddenLinks?.get(node.id) : void 0,
|
|
1153
|
+
ref: require_domains_knowledge_lib_pageAddress.pageRef(node.data.page, pageById),
|
|
1154
|
+
links: linkCounts.get(node.id),
|
|
1155
|
+
showCount: showCounts,
|
|
1156
|
+
level: laidOut.shape.form.get(node.id) === "full" ? laidOut.shape.level.get(node.id) : void 0,
|
|
1157
|
+
isParent: node.id === focusParentId,
|
|
1158
|
+
far: laidOut.shape.linked.has(node.id) || void 0
|
|
403
1159
|
}
|
|
404
1160
|
};
|
|
405
1161
|
}), [
|
|
406
1162
|
laidOut,
|
|
407
1163
|
selectedPageId,
|
|
408
1164
|
pinned,
|
|
409
|
-
|
|
1165
|
+
childrenUndrawn,
|
|
1166
|
+
pageById,
|
|
1167
|
+
hiddenLinks,
|
|
1168
|
+
linkCounts,
|
|
1169
|
+
showCounts,
|
|
1170
|
+
focusParentId
|
|
410
1171
|
]);
|
|
411
|
-
const flowEdges = (0, react.useMemo)(() => {
|
|
1172
|
+
const { flowEdges: builtEdges, drawnEdgeStyles } = (0, react.useMemo)(() => {
|
|
1173
|
+
const drawn = /* @__PURE__ */ new Set();
|
|
412
1174
|
const sizes = new Map(laidOut.nodes.map((node) => [node.id, node.data.size]));
|
|
413
1175
|
const circle = (id) => {
|
|
414
1176
|
return {
|
|
@@ -419,71 +1181,168 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
419
1181
|
r: (sizes.get(id) ?? 0) / 2
|
|
420
1182
|
};
|
|
421
1183
|
};
|
|
422
|
-
return
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
...edge
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
1184
|
+
return {
|
|
1185
|
+
flowEdges: [...laidOut.edges, ...hoverExtra].map((edge) => {
|
|
1186
|
+
const mention = edge.data?.kind === "mention";
|
|
1187
|
+
const grant = edge.data?.kind === "grant";
|
|
1188
|
+
const link = edge.data?.kind === "link";
|
|
1189
|
+
const toDot = laidOut.shape.form.get(edge.target) === "dot";
|
|
1190
|
+
const direction = (mention || link) && emphasisId ? edge.source === emphasisId ? "out" : edge.target === emphasisId ? "in" : void 0 : void 0;
|
|
1191
|
+
const up = !mention && !grant && !link && edge.source === focusParentId && edge.target === laidOut.shape.center;
|
|
1192
|
+
drawn.add(direction ?? (up ? "up" : mention ? "mention" : grant ? "grant" : link ? "link" : toDot ? "dot-parent" : "parent"));
|
|
1193
|
+
return {
|
|
1194
|
+
...edge,
|
|
1195
|
+
type: "rim",
|
|
1196
|
+
data: {
|
|
1197
|
+
kind: edge.data?.kind ?? "parent",
|
|
1198
|
+
count: edge.data?.count ?? 1,
|
|
1199
|
+
...edge.data?.role ? { role: edge.data.role } : {},
|
|
1200
|
+
from: circle(edge.source),
|
|
1201
|
+
to: circle(edge.target)
|
|
1202
|
+
},
|
|
1203
|
+
...direction === "in" ? { zIndex: 1 } : {},
|
|
1204
|
+
...mention && onMentionSelect ? { className: "cursor-pointer" } : {},
|
|
1205
|
+
style: direction ? {
|
|
1206
|
+
...DIRECTION_EDGE_STYLE[direction],
|
|
1207
|
+
strokeWidth: mention ? 2 : 1.5
|
|
1208
|
+
} : mention ? {
|
|
1209
|
+
stroke: MENTION_EDGE_COLOR,
|
|
1210
|
+
strokeWidth: Math.min(1.5 + (edge.data?.count ?? 1) * .5, 4)
|
|
1211
|
+
} : up ? UP_EDGE_STYLE : grant ? GRANT_EDGE_STYLE : link ? LINK_EDGE_STYLE : toDot ? DOT_PARENT_EDGE_STYLE : PARENT_EDGE_STYLE,
|
|
1212
|
+
markerEnd: direction ? DIRECTION_ARROW[direction] : up ? UP_ARROW : mention ? {
|
|
1213
|
+
type: _xyflow_react.MarkerType.ArrowClosed,
|
|
1214
|
+
color: MENTION_EDGE_COLOR,
|
|
1215
|
+
width: 14,
|
|
1216
|
+
height: 14
|
|
1217
|
+
} : grant ? GRANT_ARROW : link ? LINK_ARROW : toDot ? void 0 : PARENT_ARROW
|
|
1218
|
+
};
|
|
1219
|
+
}),
|
|
1220
|
+
drawnEdgeStyles: drawn
|
|
1221
|
+
};
|
|
450
1222
|
}, [
|
|
451
1223
|
laidOut,
|
|
1224
|
+
hoverExtra,
|
|
452
1225
|
onMentionSelect,
|
|
453
|
-
|
|
1226
|
+
emphasisId,
|
|
1227
|
+
focusParentId
|
|
1228
|
+
]);
|
|
1229
|
+
const flowEdges = useStableEdges(builtEdges);
|
|
1230
|
+
const emphasisedNodes = (0, react.useMemo)(() => nodes.map((node) => {
|
|
1231
|
+
const near = neighbours?.has(node.id);
|
|
1232
|
+
const hovered = node.id === hoveredId && hoveredNotShown > 0;
|
|
1233
|
+
if (!near && !hovered) return node;
|
|
1234
|
+
return {
|
|
1235
|
+
...node,
|
|
1236
|
+
...near ? { className: NEIGHBOUR_CLASS } : {},
|
|
1237
|
+
...hovered ? { data: {
|
|
1238
|
+
...node.data,
|
|
1239
|
+
notShown: hoveredNotShown
|
|
1240
|
+
} } : {}
|
|
1241
|
+
};
|
|
1242
|
+
}), [
|
|
1243
|
+
nodes,
|
|
1244
|
+
neighbours,
|
|
1245
|
+
hoveredId,
|
|
1246
|
+
hoveredNotShown
|
|
454
1247
|
]);
|
|
1248
|
+
const emphasisedEdges = (0, react.useMemo)(() => neighbours ? flowEdges.map((edge) => neighbours.has(edge.source) && neighbours.has(edge.target) ? {
|
|
1249
|
+
...edge,
|
|
1250
|
+
className: [edge.className, NEIGHBOUR_CLASS].filter(Boolean).join(" ")
|
|
1251
|
+
} : edge) : flowEdges, [flowEdges, neighbours]);
|
|
455
1252
|
const pagesById = (0, react.useMemo)(() => new Map(pages.map((page) => [page.id, page])), [pages]);
|
|
456
1253
|
const reactFlow = (0, _xyflow_react.useReactFlow)();
|
|
457
1254
|
const containerRef = (0, react.useRef)(null);
|
|
458
1255
|
const hasNodes = nodes.length > 0;
|
|
1256
|
+
const drawnNodes = require_domains_knowledge_lib_useLeavingNodes.useLeavingNodes(emphasisedNodes, require_domains_knowledge_lib_useLeavingNodes.prefersMotion());
|
|
1257
|
+
const linkedIds = laidOut.shape.linked;
|
|
459
1258
|
const fitState = (0, react.useRef)({
|
|
460
1259
|
nodes,
|
|
461
|
-
allEdges,
|
|
462
1260
|
selectedPageId,
|
|
463
|
-
|
|
1261
|
+
centerId,
|
|
1262
|
+
reactFlow,
|
|
1263
|
+
linkedIds
|
|
464
1264
|
});
|
|
465
1265
|
fitState.current = {
|
|
466
1266
|
nodes,
|
|
467
|
-
allEdges,
|
|
468
1267
|
selectedPageId,
|
|
469
|
-
|
|
1268
|
+
centerId,
|
|
1269
|
+
reactFlow,
|
|
1270
|
+
linkedIds
|
|
470
1271
|
};
|
|
471
1272
|
const fitPending = (0, react.useRef)(false);
|
|
472
|
-
const
|
|
1273
|
+
const paneAndNodes = () => {
|
|
473
1274
|
const container = containerRef.current;
|
|
474
1275
|
const width = container?.clientWidth ?? 0;
|
|
475
1276
|
const height = container?.clientHeight ?? 0;
|
|
476
1277
|
if (width === 0 || height === 0) {
|
|
477
1278
|
fitPending.current = true;
|
|
478
|
-
return;
|
|
1279
|
+
return null;
|
|
479
1280
|
}
|
|
480
1281
|
fitPending.current = false;
|
|
481
|
-
const { nodes: current,
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
1282
|
+
const { nodes: current, reactFlow: flow } = fitState.current;
|
|
1283
|
+
const bounds = graphBounds(current);
|
|
1284
|
+
return bounds ? {
|
|
1285
|
+
container,
|
|
1286
|
+
width,
|
|
1287
|
+
height,
|
|
1288
|
+
current,
|
|
1289
|
+
flow,
|
|
1290
|
+
bounds
|
|
1291
|
+
} : null;
|
|
1292
|
+
};
|
|
1293
|
+
const fit = (0, react.useCallback)((duration) => {
|
|
1294
|
+
const view = paneAndNodes();
|
|
1295
|
+
if (!view) return;
|
|
1296
|
+
const { selectedPageId: selected, centerId: centre, linkedIds: linked } = fitState.current;
|
|
1297
|
+
const anchor = view.current.find((node) => node.id === (selected ?? centre));
|
|
1298
|
+
const ring = !!selected && view.current.some((node) => linked.has(node.id));
|
|
1299
|
+
const viewport = require_domains_knowledge_lib_fitViewport.fitViewport({
|
|
1300
|
+
bounds: view.bounds,
|
|
1301
|
+
width: view.width,
|
|
1302
|
+
height: view.height,
|
|
1303
|
+
ring,
|
|
1304
|
+
anchor
|
|
1305
|
+
});
|
|
1306
|
+
view.flow.setViewport(viewport, duration ? { duration } : void 0);
|
|
1307
|
+
}, []);
|
|
1308
|
+
const fitInitial = (0, react.useCallback)(() => {
|
|
1309
|
+
const view = paneAndNodes();
|
|
1310
|
+
if (!view) return;
|
|
1311
|
+
const box = view.container?.getBoundingClientRect();
|
|
1312
|
+
const legend = view.container?.querySelector("[aria-label=\"Legend\"]")?.getBoundingClientRect();
|
|
1313
|
+
const viewport = require_domains_knowledge_lib_fitViewport.fitAllViewport({
|
|
1314
|
+
bounds: view.bounds,
|
|
1315
|
+
nodes: view.current.map((node) => ({
|
|
1316
|
+
x: node.position.x,
|
|
1317
|
+
y: node.position.y,
|
|
1318
|
+
width: node.width ?? 0,
|
|
1319
|
+
height: node.height ?? 0
|
|
1320
|
+
})),
|
|
1321
|
+
width: view.width,
|
|
1322
|
+
height: view.height,
|
|
1323
|
+
legend: box && legend ? {
|
|
1324
|
+
right: legend.right - box.left + 8,
|
|
1325
|
+
bottom: legend.bottom - box.top + 8
|
|
1326
|
+
} : void 0
|
|
1327
|
+
});
|
|
1328
|
+
view.flow.setViewport(viewport);
|
|
1329
|
+
}, []);
|
|
1330
|
+
const nudgeToSelection = (0, react.useCallback)((duration) => {
|
|
1331
|
+
const container = containerRef.current;
|
|
1332
|
+
const width = container?.clientWidth ?? 0;
|
|
1333
|
+
const height = container?.clientHeight ?? 0;
|
|
1334
|
+
const { nodes: current, selectedPageId: selected, centerId: centre, reactFlow: flow } = fitState.current;
|
|
1335
|
+
const anchor = current.find((node) => node.id === (selected ?? centre));
|
|
1336
|
+
if (!anchor || width === 0 || height === 0) return;
|
|
1337
|
+
const view = flow.getViewport();
|
|
1338
|
+
const dx = require_domains_knowledge_lib_fitViewport.nudgeAxis(anchor.position.x * view.zoom + view.x, (anchor.width ?? 0) * view.zoom, width);
|
|
1339
|
+
const dy = require_domains_knowledge_lib_fitViewport.nudgeAxis(anchor.position.y * view.zoom + view.y, (anchor.height ?? 0) * view.zoom, height);
|
|
1340
|
+
if (dx === 0 && dy === 0) return;
|
|
1341
|
+
flow.setViewport({
|
|
1342
|
+
zoom: view.zoom,
|
|
1343
|
+
x: view.x + dx,
|
|
1344
|
+
y: view.y + dy
|
|
1345
|
+
}, duration ? { duration } : void 0);
|
|
487
1346
|
}, []);
|
|
488
1347
|
(0, react.useEffect)(() => {
|
|
489
1348
|
const container = containerRef.current;
|
|
@@ -493,10 +1352,12 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
493
1352
|
height: container.clientHeight
|
|
494
1353
|
};
|
|
495
1354
|
let frame;
|
|
1355
|
+
let needsFit = false;
|
|
496
1356
|
const observer = new ResizeObserver(([entry]) => {
|
|
497
1357
|
if (!entry) return;
|
|
498
1358
|
const { width, height } = entry.contentRect;
|
|
499
1359
|
const changed = width !== last.width || height !== last.height;
|
|
1360
|
+
if (last.width === 0 || last.height === 0) needsFit = true;
|
|
500
1361
|
last = {
|
|
501
1362
|
width,
|
|
502
1363
|
height
|
|
@@ -505,7 +1366,10 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
505
1366
|
if (frame !== void 0) cancelAnimationFrame(frame);
|
|
506
1367
|
frame = requestAnimationFrame(() => {
|
|
507
1368
|
frame = void 0;
|
|
508
|
-
|
|
1369
|
+
if (needsFit || fitPending.current) {
|
|
1370
|
+
needsFit = false;
|
|
1371
|
+
fitInitial();
|
|
1372
|
+
} else nudgeToSelection();
|
|
509
1373
|
});
|
|
510
1374
|
});
|
|
511
1375
|
observer.observe(container);
|
|
@@ -513,33 +1377,51 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
513
1377
|
observer.disconnect();
|
|
514
1378
|
if (frame !== void 0) cancelAnimationFrame(frame);
|
|
515
1379
|
};
|
|
516
|
-
}, [
|
|
1380
|
+
}, [
|
|
1381
|
+
hasNodes,
|
|
1382
|
+
fitInitial,
|
|
1383
|
+
nudgeToSelection
|
|
1384
|
+
]);
|
|
517
1385
|
const selectedHere = (0, react.useRef)(null);
|
|
518
1386
|
const selectedIsLoaded = !!selectedPageId && pagesById.has(selectedPageId);
|
|
519
1387
|
const initialized = (0, react.useRef)(false);
|
|
1388
|
+
const settleUntil = (0, react.useRef)(0);
|
|
1389
|
+
const settledOn = (0, react.useRef)(null);
|
|
1390
|
+
const fittedLayout = (0, react.useRef)("");
|
|
1391
|
+
const stopSettling = (0, react.useCallback)(() => {
|
|
1392
|
+
settleUntil.current = 0;
|
|
1393
|
+
}, []);
|
|
1394
|
+
(0, react.useEffect)(() => {
|
|
1395
|
+
if (!initialized.current) return;
|
|
1396
|
+
if ((selectedPageId ?? null) !== settledOn.current) settleUntil.current = 0;
|
|
1397
|
+
if (Date.now() >= settleUntil.current) return;
|
|
1398
|
+
const layout = nodes.map((node) => `${node.id}@${node.position.x},${node.position.y}`).join("|");
|
|
1399
|
+
if (layout === fittedLayout.current) return;
|
|
1400
|
+
fittedLayout.current = layout;
|
|
1401
|
+
fitInitial();
|
|
1402
|
+
}, [
|
|
1403
|
+
nodes,
|
|
1404
|
+
selectedPageId,
|
|
1405
|
+
fitInitial
|
|
1406
|
+
]);
|
|
520
1407
|
(0, react.useEffect)(() => {
|
|
521
1408
|
if (!initialized.current || !selectedIsLoaded || !selectedPageId) return;
|
|
522
1409
|
const fromGraph = selectedHere.current === selectedPageId;
|
|
523
1410
|
selectedHere.current = null;
|
|
524
1411
|
if (fromGraph) return;
|
|
525
|
-
|
|
1412
|
+
nudgeToSelection(require_domains_knowledge_lib_fitViewport.fitDuration(require_domains_knowledge_lib_useLeavingNodes.prefersMotion()));
|
|
526
1413
|
}, [
|
|
527
1414
|
selectedPageId,
|
|
528
1415
|
selectedIsLoaded,
|
|
529
|
-
|
|
1416
|
+
nudgeToSelection
|
|
530
1417
|
]);
|
|
531
1418
|
const activate = (page) => {
|
|
1419
|
+
if (require_domains_knowledge_lib_graphShape.isChildPlaceholder(page) || require_domains_knowledge_lib_graphShape.isScopeGroup(page) || require_domains_knowledge_lib_graphShape.isRestCircle(page)) return onSelect(page);
|
|
532
1420
|
if (page.id === selectedPageId && onOpen) return onOpen(page);
|
|
533
1421
|
selectedHere.current = page.id;
|
|
534
1422
|
onSelect(page);
|
|
535
1423
|
};
|
|
536
1424
|
const pressedAt = (0, react.useRef)(null);
|
|
537
|
-
const onPaneClick = (event) => {
|
|
538
|
-
const start = pressedAt.current;
|
|
539
|
-
pressedAt.current = null;
|
|
540
|
-
if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > CLICK_SLOP_PX) return;
|
|
541
|
-
onClearSelection?.();
|
|
542
|
-
};
|
|
543
1425
|
const onKeyDown = (event) => {
|
|
544
1426
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
545
1427
|
const id = event.target.closest(".react-flow__node")?.dataset.id;
|
|
@@ -548,6 +1430,56 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
548
1430
|
event.preventDefault();
|
|
549
1431
|
activate(page);
|
|
550
1432
|
};
|
|
1433
|
+
const latest = (0, react.useRef)({
|
|
1434
|
+
activate,
|
|
1435
|
+
onPreview,
|
|
1436
|
+
onMentionSelect,
|
|
1437
|
+
onClearSelection,
|
|
1438
|
+
laidOut,
|
|
1439
|
+
pagesById
|
|
1440
|
+
});
|
|
1441
|
+
latest.current = {
|
|
1442
|
+
activate,
|
|
1443
|
+
onPreview,
|
|
1444
|
+
onMentionSelect,
|
|
1445
|
+
onClearSelection,
|
|
1446
|
+
laidOut,
|
|
1447
|
+
pagesById
|
|
1448
|
+
};
|
|
1449
|
+
const onNodeMouseEnter = (0, react.useCallback)((_, node) => {
|
|
1450
|
+
setHoveredId(node.id);
|
|
1451
|
+
if (latest.current.laidOut.shape.form.get(node.id) === "dot") latest.current.onPreview?.(node.data.page);
|
|
1452
|
+
}, []);
|
|
1453
|
+
const onNodeMouseLeave = (0, react.useCallback)(() => setHoveredId(null), []);
|
|
1454
|
+
const onNodeClick = (0, react.useCallback)((_, node) => {
|
|
1455
|
+
if (!isPlaceholder(node.data.page)) latest.current.activate(node.data.page);
|
|
1456
|
+
}, []);
|
|
1457
|
+
const onEdgeClick = (0, react.useCallback)((event, edge) => {
|
|
1458
|
+
const { onMentionSelect, pagesById } = latest.current;
|
|
1459
|
+
if (edge.data?.kind !== "mention" || !onMentionSelect) return;
|
|
1460
|
+
const source = pagesById.get(edge.source);
|
|
1461
|
+
const target = pagesById.get(edge.target);
|
|
1462
|
+
if (!source || !target) return;
|
|
1463
|
+
const box = containerRef.current?.getBoundingClientRect();
|
|
1464
|
+
onMentionSelect({
|
|
1465
|
+
source,
|
|
1466
|
+
target,
|
|
1467
|
+
point: {
|
|
1468
|
+
x: event.clientX - (box?.left ?? 0),
|
|
1469
|
+
y: event.clientY - (box?.top ?? 0)
|
|
1470
|
+
},
|
|
1471
|
+
pane: {
|
|
1472
|
+
width: box?.width ?? 0,
|
|
1473
|
+
height: box?.height ?? 0
|
|
1474
|
+
}
|
|
1475
|
+
});
|
|
1476
|
+
}, []);
|
|
1477
|
+
const onPaneClick = (0, react.useCallback)((event) => {
|
|
1478
|
+
const start = pressedAt.current;
|
|
1479
|
+
pressedAt.current = null;
|
|
1480
|
+
if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > CLICK_SLOP_PX) return;
|
|
1481
|
+
latest.current.onClearSelection?.();
|
|
1482
|
+
}, []);
|
|
551
1483
|
if (!hasNodes) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
552
1484
|
className: "flex h-full items-center justify-center p-6",
|
|
553
1485
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Txt.Txt, {
|
|
@@ -558,51 +1490,47 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
558
1490
|
});
|
|
559
1491
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
560
1492
|
ref: containerRef,
|
|
561
|
-
className: "relative size-full",
|
|
1493
|
+
className: "knowledge-graph relative size-full",
|
|
1494
|
+
"data-emphasis": neighbours ? "on" : void 0,
|
|
562
1495
|
"data-testid": "knowledge-page-graph",
|
|
563
1496
|
onKeyDown,
|
|
1497
|
+
onWheelCapture: stopSettling,
|
|
564
1498
|
onPointerDownCapture: (event) => {
|
|
1499
|
+
stopSettling();
|
|
565
1500
|
pressedAt.current = {
|
|
566
1501
|
x: event.clientX,
|
|
567
1502
|
y: event.clientY
|
|
568
1503
|
};
|
|
569
1504
|
},
|
|
570
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GraphLegend, {
|
|
571
|
-
|
|
572
|
-
|
|
1505
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GraphLegend, {
|
|
1506
|
+
branches: dotBranches,
|
|
1507
|
+
levels: drawnLevels,
|
|
1508
|
+
focused: !!selectedPageId && laidOut.positions.has(selectedPageId),
|
|
1509
|
+
dots: [...laidOut.shape.form.values()].includes("dot"),
|
|
1510
|
+
linkEnds: laidOut.shape.linked.size > 0,
|
|
1511
|
+
drawn: drawnEdgeStyles,
|
|
1512
|
+
counts: [...hiddenLinks ?? []].some(([id, hidden]) => laidOut.shape.form.get(id) === "full" && (hidden.in > 0 || hidden.out > 0))
|
|
1513
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_xyflow_react.ReactFlow, {
|
|
1514
|
+
nodes: drawnNodes,
|
|
1515
|
+
edges: emphasisedEdges,
|
|
573
1516
|
nodeTypes,
|
|
574
1517
|
edgeTypes,
|
|
575
1518
|
onInit: () => {
|
|
576
1519
|
initialized.current = true;
|
|
577
|
-
|
|
1520
|
+
settleUntil.current = Date.now() + require_domains_knowledge_lib_fitViewport.INITIAL_SETTLE_MS;
|
|
1521
|
+
settledOn.current = fitState.current.selectedPageId ?? null;
|
|
1522
|
+
fittedLayout.current = fitState.current.nodes.map((node) => `${node.id}@${node.position.x},${node.position.y}`).join("|");
|
|
1523
|
+
fitInitial();
|
|
578
1524
|
},
|
|
579
1525
|
minZoom: .1,
|
|
580
1526
|
proOptions: { hideAttribution: true },
|
|
581
1527
|
nodesConnectable: false,
|
|
582
1528
|
nodesDraggable: false,
|
|
583
1529
|
onPaneClick,
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
onEdgeClick
|
|
588
|
-
if (edge.data?.kind !== "mention" || !onMentionSelect) return;
|
|
589
|
-
const source = pagesById.get(edge.source);
|
|
590
|
-
const target = pagesById.get(edge.target);
|
|
591
|
-
if (!source || !target) return;
|
|
592
|
-
const box = containerRef.current?.getBoundingClientRect();
|
|
593
|
-
onMentionSelect({
|
|
594
|
-
source,
|
|
595
|
-
target,
|
|
596
|
-
point: {
|
|
597
|
-
x: event.clientX - (box?.left ?? 0),
|
|
598
|
-
y: event.clientY - (box?.top ?? 0)
|
|
599
|
-
},
|
|
600
|
-
pane: {
|
|
601
|
-
width: box?.width ?? 0,
|
|
602
|
-
height: box?.height ?? 0
|
|
603
|
-
}
|
|
604
|
-
});
|
|
605
|
-
},
|
|
1530
|
+
onNodeMouseEnter,
|
|
1531
|
+
onNodeMouseLeave,
|
|
1532
|
+
onNodeClick,
|
|
1533
|
+
onEdgeClick,
|
|
606
1534
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.Background, {
|
|
607
1535
|
variant: _xyflow_react.BackgroundVariant.Dots,
|
|
608
1536
|
gap: 26,
|
|
@@ -612,7 +1540,7 @@ function KnowledgePageGraphInner({ pages, edges, pinnedIds = [], grants, selecte
|
|
|
612
1540
|
showInteractive: false,
|
|
613
1541
|
showFitView: false,
|
|
614
1542
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_xyflow_react.ControlButton, {
|
|
615
|
-
onClick: () => fit(
|
|
1543
|
+
onClick: () => fit(require_domains_knowledge_lib_fitViewport.fitDuration(require_domains_knowledge_lib_useLeavingNodes.prefersMotion())),
|
|
616
1544
|
title: "Fit view",
|
|
617
1545
|
"aria-label": "Fit view",
|
|
618
1546
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Maximize, { "aria-hidden": true })
|