@datalayer/agent-runtimes 1.3.89 → 1.3.91
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/lib/Agent.js +2 -18
- package/lib/AgentDocument.js +5 -55
- package/lib/AgentNode.js +31 -208
- package/lib/AgentNotebook.js +5 -59
- package/lib/agent-node/AgentNodeGallery.js +23 -111
- package/lib/agents/AgentDetails.js +36 -274
- package/lib/agents/AgentRuntimeChat.js +1 -8
- package/lib/chat/Chat.js +7 -46
- package/lib/chat/ChatFloating.js +15 -100
- package/lib/chat/ChatInline.js +5 -47
- package/lib/chat/ChatPopupStandalone.js +5 -53
- package/lib/chat/ChatSidebar.js +4 -51
- package/lib/chat/ChatStandalone.js +4 -45
- package/lib/chat/EphemeralSurfaceControl.js +5 -25
- package/lib/chat/assistant/AssistantContextMenu.d.ts +8 -0
- package/lib/chat/assistant/AssistantContextMenu.js +17 -1
- package/lib/chat/assistant/AssistantStage.js +6 -25
- package/lib/chat/assistant/BalloonParts.js +8 -40
- package/lib/chat/assistant/BalloonVisual.js +2 -2
- package/lib/chat/assistant/ConversationBalloon.js +2 -11
- package/lib/chat/assistant/DecisionAsk.js +3 -3
- package/lib/chat/assistant/SandboxDetailsDialog.js +3 -17
- package/lib/chat/assistant/SpeechBalloon.js +14 -78
- package/lib/chat/base/ChatBase.js +37 -172
- package/lib/chat/display/EmptyState.js +7 -35
- package/lib/chat/display/FloatingBrandButton.js +4 -34
- package/lib/chat/display/PoweredByTag.js +3 -14
- package/lib/chat/document/EphemeralDocument.js +3 -18
- package/lib/chat/header/ChatHeader.js +1 -17
- package/lib/chat/header/ChatHeaderBase.js +2 -24
- package/lib/chat/header/ChatViewModeToggle.js +7 -29
- package/lib/chat/indicators/McpStatusIndicator.js +3 -12
- package/lib/chat/indicators/SandboxStatusIndicator.js +6 -34
- package/lib/chat/indicators/SkillsStatusIndicator.js +3 -12
- package/lib/chat/indicators/TypingDots.js +1 -11
- package/lib/chat/messages/ChatMessageList.js +58 -185
- package/lib/chat/messages/ChatMessages.js +15 -79
- package/lib/chat/messages/FormSubmissionMessage.js +2 -33
- package/lib/chat/messages/NotebookToolSurfaces.js +12 -41
- package/lib/chat/messages/TurnFooter.js +4 -10
- package/lib/chat/notebook/EphemeralNotebook.js +2 -10
- package/lib/chat/parts/ReasoningPart.js +2 -16
- package/lib/chat/parts/TextPart.js +2 -12
- package/lib/chat/parts/ToolPart.js +16 -90
- package/lib/chat/presence/Presence.js +5 -33
- package/lib/chat/prompt/FloatingCard.js +1 -13
- package/lib/chat/prompt/InputPrompt.js +1 -6
- package/lib/chat/prompt/InputPromptBase.js +4 -17
- package/lib/chat/prompt/InputPromptLexical.js +44 -45
- package/lib/chat/prompt/InputPromptText.js +1 -1
- package/lib/chat/prompt/footer/InPromptFooter.js +1 -8
- package/lib/chat/prompt/menus/AgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/InlineAgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/ModelSelector.js +1 -5
- package/lib/chat/prompt/menus/SkillsMenu.js +3 -30
- package/lib/chat/prompt/menus/SuggestionsMenu.js +1 -1
- package/lib/chat/prompt/menus/ToolsMenu.js +4 -48
- package/lib/chat/prompt/plugins/AgentMentionPlugin.js +2 -9
- package/lib/chat/prompt/plugins/CommandPlugin.js +2 -9
- package/lib/chat/prompt/plugins/MentionChip.js +1 -15
- package/lib/chat/prompt/stack.js +1 -19
- package/lib/chat/tools/A2AAgentDialog.js +9 -42
- package/lib/chat/tools/SubagentActivity.js +5 -22
- package/lib/chat/tools/ToolApprovalBanner.js +4 -34
- package/lib/chat/tools/ToolApprovalDialog.js +4 -19
- package/lib/chat/tools/ToolCallDisplay.js +12 -97
- package/lib/chat/usage/ContextPie.js +4 -45
- package/lib/chat/words.d.ts +7 -0
- package/lib/chat/words.js +12 -0
- package/lib/components/a2ui/datalayer/Chart.js +4 -10
- package/lib/components/a2ui/datalayer/Chat.js +2 -10
- package/lib/components/a2ui/datalayer/Download.js +1 -1
- package/lib/components/a2ui/datalayer/Evidence.js +1 -15
- package/lib/components/a2ui/datalayer/FileUpload.js +1 -12
- package/lib/components/a2ui/datalayer/Table.js +9 -17
- package/lib/components/a2ui/datalayer/formWidgets.js +3 -2
- package/lib/components/a2ui/datalayer/parts.js +1 -16
- package/lib/components/a2ui/styles.js +16 -5
- package/lib/components/agents/AgentSummary.js +1 -51
- package/lib/components/cards/NotificationEventCard.js +6 -72
- package/lib/components/cards/OutputCard.js +4 -48
- package/lib/components/cards/ToolApprovalCard.js +2 -35
- package/lib/components/code-sandboxes/CodeSandboxCellVariables.js +1 -1
- package/lib/components/code-sandboxes/CodeSandboxEnvironmentSelect.js +4 -14
- package/lib/components/code-sandboxes/CodeSandboxPicker.js +16 -21
- package/lib/components/code-sandboxes/CodeSandboxVariables.js +2 -2
- package/lib/components/scheduler/ScheduleMenu.js +5 -10
- package/lib/components/specs/SpecPayloadPreview.js +1 -26
- package/lib/components/teams/A2ATeamGraph.d.ts +4 -3
- package/lib/components/teams/A2ATeamGraph.js +25 -71
- package/lib/components/teams/AnswerSurfacesView.js +2 -2
- package/lib/components/teams/NotebookPreview.js +1 -10
- package/lib/components/teams/NotebookPreviewView.js +2 -3
- package/lib/components/teams/SceneTranscript.js +3 -17
- package/lib/components/teams/SceneView.js +1 -8
- package/lib/components/teams/TeamNotebook.js +5 -13
- package/lib/components/teams/TeamNotebookView.js +2 -12
- package/lib/components/teams/index.d.ts +1 -0
- package/lib/components/teams/index.js +1 -0
- package/lib/components/teams/useBalloonRoom.d.ts +39 -0
- package/lib/components/teams/useBalloonRoom.js +89 -0
- package/lib/config/AgentConfiguration.js +22 -225
- package/lib/context/ContextDistribution.js +7 -41
- package/lib/context/ContextInspector.js +9 -107
- package/lib/context/ContextPanel.js +11 -86
- package/lib/context/ContextUsage.js +6 -34
- package/lib/context/CostTracker.js +7 -42
- package/lib/context/MessageHistory.js +3 -37
- package/lib/context/TurnGraphChart.js +9 -41
- package/lib/examples/A2UiAgentExample.js +6 -108
- package/lib/examples/A2UiComponentsGalleryExample.js +1 -1
- package/lib/examples/A2UiContactCardExample.js +1 -1
- package/lib/examples/A2UiJupyterOutputExample.js +25 -125
- package/lib/examples/A2UiRestaurantExample.js +1 -1
- package/lib/examples/A2UiViewerExample.js +1 -1
- package/lib/examples/AgUiAgenticExample.js +3 -35
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -25
- package/lib/examples/AgUiHaikuGenUiExample.js +2 -32
- package/lib/examples/AgUiHumanInTheLoopExample.js +5 -59
- package/lib/examples/AgUiSharedStateExample.js +6 -56
- package/lib/examples/AgUiToolsBasedGenUiExample.js +25 -120
- package/lib/examples/AgentA2AExample.js +1 -15
- package/lib/examples/AgentA2ATeamExample.js +6 -30
- package/lib/examples/AgentCheckpointsExample.js +11 -145
- package/lib/examples/AgentCodeSandboxExample.js +5 -108
- package/lib/examples/AgentCodeSandboxesExample.js +3 -30
- package/lib/examples/AgentCodemodeExample.js +9 -85
- package/lib/examples/AgentCompactionExample.js +3 -64
- package/lib/examples/AgentDecideExample.js +1 -13
- package/lib/examples/AgentEvalsExample.js +5 -60
- package/lib/examples/AgentGuardrailsExample.js +4 -28
- package/lib/examples/AgentHooksExample.js +1 -1
- package/lib/examples/AgentInferenceProviderExample.js +5 -96
- package/lib/examples/AgentMCPExample.js +7 -105
- package/lib/examples/AgentMemoryExample.js +5 -74
- package/lib/examples/AgentMonitoringExample.js +7 -53
- package/lib/examples/AgentNotificationsExample.js +3 -61
- package/lib/examples/AgentOtelExample.js +3 -72
- package/lib/examples/AgentOutputsExample.js +6 -81
- package/lib/examples/AgentParametersExample.js +2 -37
- package/lib/examples/AgentSkillsExample.js +3 -45
- package/lib/examples/AgentSubagentsExample.js +6 -56
- package/lib/examples/AgentToolApprovalsExample.js +1 -11
- package/lib/examples/AgentTriggersExample.js +29 -239
- package/lib/examples/AgentspecsExample.js +6 -60
- package/lib/examples/AssistantExample.js +5 -5
- package/lib/examples/AssistantGalleryExample.js +8 -65
- package/lib/examples/CellExample.js +1 -6
- package/lib/examples/ChatCustomExample.js +2 -31
- package/lib/examples/ChatExample.js +1 -9
- package/lib/examples/ChatStandaloneExample.js +3 -37
- package/lib/examples/CopilotKitLexicalExample.js +1 -24
- package/lib/examples/DecksAgent.js +1 -1
- package/lib/examples/DocumentPageAgent.js +1 -1
- package/lib/examples/HomeExample.js +14 -62
- package/lib/examples/Lexical2Example.js +3 -32
- package/lib/examples/LexicalAgentExample.js +2 -34
- package/lib/examples/LexicalAgentSidebarExample.js +3 -34
- package/lib/examples/LoopAppComputerExample.js +1 -1
- package/lib/examples/LoopShellExample.js +2 -2
- package/lib/examples/LoopStrategyExample.js +15 -87
- package/lib/examples/LoopWorkspaceEmbed.js +2 -18
- package/lib/examples/LoopWorkspaceExample.js +2 -2
- package/lib/examples/NotebookAgentExample.js +2 -33
- package/lib/examples/NotebookAgentSidebarExample.js +3 -46
- package/lib/examples/NotebookCollaborationExample.js +1 -31
- package/lib/examples/NotebookExample.js +1 -18
- package/lib/examples/NotebookPageAgent.js +1 -1
- package/lib/examples/ScenesExample.js +5 -24
- package/lib/examples/VoiceChatExample.js +1 -1
- package/lib/examples/components/AuthRequiredView.js +1 -7
- package/lib/examples/components/ErrorView.js +1 -8
- package/lib/examples/components/ExampleErrorBoundary.js +1 -14
- package/lib/examples/components/FooterMetrics.js +1 -7
- package/lib/examples/components/Header.js +12 -51
- package/lib/examples/components/HeaderControls.js +1 -9
- package/lib/examples/components/LexicalEditor.js +1 -8
- package/lib/examples/components/MainContent.js +1 -13
- package/lib/examples/components/MockFileBrowser.js +4 -40
- package/lib/examples/components/SessionTabs.js +1 -1
- package/lib/examples/components/TimeTravel.js +1 -13
- package/lib/examples/main.js +13 -81
- package/lib/examples/scenes/A2UiComponentsGalleryScene.js +3 -34
- package/lib/examples/scenes/A2UiContactCardScene.js +3 -35
- package/lib/examples/scenes/A2UiRestaurantScene.js +3 -53
- package/lib/examples/scenes/A2UiViewerScene.js +3 -34
- package/lib/examples/utils/AssistantGalleryGrid.js +6 -35
- package/lib/examples2/DatalayerNotebookExample.js +3 -33
- package/lib/examples2/NativeNavigationExample.js +4 -10
- package/lib/examples2/NotebookMutationsKernel.js +2 -1
- package/lib/examples2/NotebookMutationsServiceManager.js +2 -1
- package/lib/examples2/ReactRouterExample.js +14 -42
- package/lib/hooks/useToolApprovals.d.ts +2 -34
- package/lib/hooks/useToolApprovals.js +1 -64
- package/lib/identity/AgentIdentity.js +17 -62
- package/lib/identity/IdentityConnect.js +13 -59
- package/lib/identity/OAuthCallback.js +6 -44
- package/lib/lexical/ChatInlinePlugin.js +6 -14
- package/lib/loop/apps/AppFeedback.js +12 -3
- package/lib/loop/apps/AppRenderer.d.ts +4 -3
- package/lib/loop/apps/AppRenderer.js +11 -12
- package/lib/loop/apps/appspec.js +6 -3
- package/lib/loop/apps/feedback.d.ts +3 -2
- package/lib/loop/apps/feedback.js +4 -2
- package/lib/loop/core/index.d.ts +19 -0
- package/lib/loop/core/index.js +27 -0
- package/lib/loop/embed/AppEmbed.d.ts +1 -1
- package/lib/loop/embed/AppEmbed.js +2 -1
- package/lib/loop/embed/LoopEmbed.js +1 -7
- package/lib/loop/embed/embedConfig.d.ts +3 -3
- package/lib/loop/embed/embedConfig.js +2 -3
- package/lib/loop/embed/embedTheme.d.ts +4 -4
- package/lib/loop/embed/embedTheme.js +11 -7
- package/lib/loop/plugins/a2a-sidebar/A2ASidebar.js +7 -34
- package/lib/loop/plugins/a2ui/A2uiView.js +4 -12
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +1 -16
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +2 -12
- package/lib/loop/plugins/agents/AnonymousKeyBadge.js +3 -2
- package/lib/loop/plugins/agents/SandboxSelector.js +3 -7
- package/lib/loop/plugins/agents/SandboxView.js +4 -27
- package/lib/loop/plugins/agents/TeamMemberPicker.js +2 -2
- package/lib/loop/plugins/agentspecs/AgentspecPicker.js +3 -2
- package/lib/loop/plugins/app-activity/AppActivity.js +1 -1
- package/lib/loop/plugins/app-computer/AppComputer.js +32 -27
- package/lib/loop/plugins/app-elements/AppElements.js +2 -31
- package/lib/loop/plugins/app-page/AppPage.js +26 -8
- package/lib/loop/plugins/app-rules/AppRulesCard.js +4 -20
- package/lib/loop/plugins/assistant/index.js +1 -13
- package/lib/loop/plugins/chat/ChatView.js +89 -130
- package/lib/loop/plugins/checkpoints-sidebar/CheckpointsSidebar.js +2 -13
- package/lib/loop/plugins/decks/DeckSurface.js +2 -2
- package/lib/loop/plugins/document/DocumentView.js +4 -12
- package/lib/loop/plugins/document-toolbar/SandboxStatusItem.js +3 -8
- package/lib/loop/plugins/graph/GraphView.js +2 -2
- package/lib/loop/plugins/input-prompt/ComposerView.js +1 -1
- package/lib/loop/plugins/notebook/NotebookView.js +3 -11
- package/lib/loop/plugins/page-layout/SplitLayout.js +11 -34
- package/lib/loop/plugins/page-layout/TurnPanel.js +9 -35
- package/lib/loop/plugins/shell/useEditorPreviews.js +3 -2
- package/lib/loop/plugins/subagent-activity/SubagentPulse.js +1 -13
- package/lib/loop/plugins/window-frame/WindowFrame.js +10 -44
- package/lib/loop/plugins/window-frame/index.js +1 -1
- package/lib/loop/shell/LoopWorkspace.js +34 -77
- package/lib/loop/shell/PluginToggles.js +4 -15
- package/lib/loop/shell/SidebarRail.js +8 -40
- package/lib/loop/shell/ViewSwitcher.js +4 -24
- package/lib/loop-main.js +2 -3
- package/lib/mcp/McpServerManager.js +6 -37
- package/lib/portable/index.d.ts +11 -0
- package/lib/portable/index.js +20 -0
- package/lib/protocols/AGUIAdapter.js +2 -2
- package/lib/protocols/BaseProtocolAdapter.d.ts +2 -0
- package/lib/protocols/BaseProtocolAdapter.js +4 -0
- package/lib/specs/apps.js +6 -0
- package/lib/specs/appspecSchema.js +11 -4
- package/lib/stories/loop/ReferenceScreens.js +17 -91
- package/lib/stories/loop/pictures-main.js +1 -1
- package/lib/types/agentspecs.d.ts +5 -2
- package/lib/types/protocol.d.ts +2 -0
- package/lib/utils/approvals.d.ts +59 -0
- package/lib/utils/approvals.js +101 -0
- package/lib/voice/VoiceInput.js +3 -39
- package/package.json +2 -2
- package/lib/shims/primerAddonsBox.d.ts +0 -1
- package/lib/shims/primerAddonsBox.js +0 -7
|
@@ -4,7 +4,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useState, useEffect } from 'react';
|
|
7
|
-
import { Box
|
|
7
|
+
import { Box } from '@datalayer/primer-addons';
|
|
8
|
+
import { Button, Heading, Text, Link as PrimerLink } from '@primer/react';
|
|
8
9
|
import { useNavigate, useLocation, useParams, useHistory } from '../hooks';
|
|
9
10
|
/**
|
|
10
11
|
* Native Navigation Example
|
|
@@ -83,15 +84,8 @@ export const NativeNavigationExample = () => {
|
|
|
83
84
|
return (_jsxs(_Fragment, { children: [_jsx(Heading, { as: "h1", sx: { mb: 3 }, children: "Home Page (Native)" }), _jsx(Text, { as: "p", children: "This is the home page of the Native navigation example." })] }));
|
|
84
85
|
}
|
|
85
86
|
};
|
|
86
|
-
return (_jsxs(Box, {
|
|
87
|
-
mb: 4,
|
|
88
|
-
p: 3,
|
|
89
|
-
borderWidth: 1,
|
|
90
|
-
borderStyle: 'solid',
|
|
91
|
-
borderColor: 'border.default',
|
|
92
|
-
borderRadius: 2,
|
|
93
|
-
}, children: [_jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Navigation Type Detected:" }), ' ', _jsx(Text, { as: "span", sx: {
|
|
87
|
+
return (_jsxs(Box, { minHeight: "100vh", p: 4, children: [_jsxs(Box, { mb: 4, p: 3, bg: "canvas.subtle", borderRadius: 2, children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Native Browser Navigation Example" }), _jsx(Text, { as: "p", sx: { mb: 2 }, children: "This example demonstrates the navigation hooks WITHOUT React Router context. The hooks automatically fall back to native browser navigation (history API)." }), _jsx(Text, { as: "p", sx: { color: 'attention.fg', fontWeight: 'bold' }, children: "\u26A0\uFE0F No React Router is loaded in this example - using native browser APIs only!" })] }), renderContent(), _jsxs(Box, { mt: 4, children: [_jsx(Heading, { as: "h2", sx: { mb: 3 }, children: "Navigation Information" }), _jsxs(Box, { mb: 4, p: 3, borderWidth: 1, borderStyle: "solid", borderColor: "border.default", borderRadius: 2, children: [_jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Navigation Type Detected:" }), ' ', _jsx(Text, { as: "span", sx: {
|
|
94
88
|
color: navigationType === 'native' ? 'success.fg' : 'danger.fg',
|
|
95
|
-
}, children: navigationType })] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Current Path:" }), " ", location.pathname] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Search Params:" }), " ", location.search || '(none)'] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Hash:" }), " ", location.hash || '(none)'] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Location Key:" }), " ", location.key] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "State:" }), " ", JSON.stringify(location.state) || '(none)'] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "URL Params (parsed from search):" }), ' ', JSON.stringify(params)] }), _jsxs(Text, { as: "p", children: [_jsx("strong", { children: "Navigation Count:" }), " ", navigationCount] })] }), _jsxs(Box, {
|
|
89
|
+
}, children: navigationType })] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Current Path:" }), " ", location.pathname] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Search Params:" }), " ", location.search || '(none)'] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Hash:" }), " ", location.hash || '(none)'] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "Location Key:" }), " ", location.key] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "State:" }), " ", JSON.stringify(location.state) || '(none)'] }), _jsxs(Text, { as: "p", sx: { mb: 2 }, children: [_jsx("strong", { children: "URL Params (parsed from search):" }), ' ', JSON.stringify(params)] }), _jsxs(Text, { as: "p", children: [_jsx("strong", { children: "Navigation Count:" }), " ", navigationCount] })] }), _jsxs(Box, { mb: 3, children: [_jsx(Heading, { as: "h3", sx: { mb: 2 }, children: "Test Programmatic Navigation" }), _jsxs(Box, { display: "flex", gap: 2, flexWrap: "wrap", children: [_jsx(Button, { onClick: handleProgrammaticNavigation, children: "Navigate to /page3" }), _jsx(Button, { onClick: handleNavigateWithQuery, variant: "default", children: "Navigate with Query Params" }), _jsx(Button, { onClick: handleNavigateWithHash, variant: "default", children: "Navigate with Hash" }), _jsx(Button, { onClick: handleReplaceNavigation, variant: "default", children: "Replace Current Entry" })] })] }), _jsxs(Box, { mb: 3, children: [_jsx(Heading, { as: "h3", sx: { mb: 2 }, children: "Test History API" }), _jsxs(Box, { display: "flex", gap: 2, flexWrap: "wrap", children: [_jsx(Button, { onClick: handleBackNavigation, variant: "default", children: "History Back" }), _jsx(Button, { onClick: handleForwardNavigation, variant: "default", children: "History Forward" })] })] }), _jsxs(Box, { mb: 3, children: [_jsx(Heading, { as: "h3", sx: { mb: 2 }, children: "Test Link Navigation" }), _jsxs(Box, { display: "flex", gap: 3, flexWrap: "wrap", children: [_jsx(PrimerLink, { href: "/", onClick: e => handleLinkClick(e, '/'), sx: { cursor: 'pointer' }, children: "Home" }), _jsx(PrimerLink, { href: "/page1", onClick: e => handleLinkClick(e, '/page1'), sx: { cursor: 'pointer' }, children: "Page 1" }), _jsx(PrimerLink, { href: "/page2?test=123", onClick: e => handleLinkClick(e, '/page2?test=123'), sx: { cursor: 'pointer' }, children: "Page 2 with Query" }), _jsx(PrimerLink, { href: "/page3#section", onClick: e => handleLinkClick(e, '/page3#section'), sx: { cursor: 'pointer' }, children: "Page 3 with Hash" }), _jsx(PrimerLink, { href: "/user/456", onClick: e => handleLinkClick(e, '/user/456'), sx: { cursor: 'pointer' }, children: "User 456" })] })] }), _jsxs(Box, { mt: 4, p: 3, bg: "attention.subtle", borderRadius: 2, children: [_jsx(Heading, { as: "h3", sx: { mb: 2 }, children: "How This Works" }), _jsx(Text, { as: "p", sx: { mb: 2 }, children: "This example does NOT include React Router. The navigation hooks automatically detect this and:" }), _jsxs(Box, { as: "ul", pl: 4, children: [_jsxs(Text, { as: "li", children: ["Use ", _jsx("code", { children: "window.history.pushState()" }), " for navigation"] }), _jsxs(Text, { as: "li", children: ["Listen to ", _jsx("code", { children: "popstate" }), " events for browser back/forward"] }), _jsxs(Text, { as: "li", children: ["Parse ", _jsx("code", { children: "window.location" }), " for current path and params"] }), _jsx(Text, { as: "li", children: "Provide the same API as when React Router is present" })] }), _jsx(Text, { as: "p", sx: { mt: 2 }, children: "The beauty is that the same hooks work in both scenarios without any code changes!" })] })] })] }));
|
|
96
90
|
};
|
|
97
91
|
export default NativeNavigationExample;
|
|
@@ -5,7 +5,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
5
5
|
*/
|
|
6
6
|
import { useState } from 'react';
|
|
7
7
|
import { createRoot } from 'react-dom/client';
|
|
8
|
-
import { Box
|
|
8
|
+
import { Box } from '@datalayer/primer-addons';
|
|
9
|
+
import { SegmentedControl, Label, Text } from '@primer/react';
|
|
9
10
|
import { ServiceManager } from '@jupyterlab/services';
|
|
10
11
|
import { createLiteServiceManager, createServerSettings, setJupyterServerUrl, getJupyterServerUrl, getJupyterServerToken, setJupyterServerToken, ServiceManagerLess, loadJupyterConfig, useNotebookStore, Notebook, SpinnerCentered, JupyterReactTheme, } from '@datalayer/jupyter-react';
|
|
11
12
|
import { useCoreStore } from '../state';
|
|
@@ -5,7 +5,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
5
5
|
*/
|
|
6
6
|
import { useState } from 'react';
|
|
7
7
|
import { createRoot } from 'react-dom/client';
|
|
8
|
-
import { Box
|
|
8
|
+
import { Box } from '@datalayer/primer-addons';
|
|
9
|
+
import { SegmentedControl, Label, Text } from '@primer/react';
|
|
9
10
|
import { ServiceManager } from '@jupyterlab/services';
|
|
10
11
|
import { createLiteServiceManager, createServerSettings, setJupyterServerUrl, getJupyterServerUrl, getJupyterServerToken, setJupyterServerToken, ServiceManagerLess, loadJupyterConfig, useNotebookStore, Notebook, SpinnerCentered, JupyterReactTheme, } from '@datalayer/jupyter-react';
|
|
11
12
|
import { useCoreStore } from '../state';
|
|
@@ -5,7 +5,8 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
5
5
|
*/
|
|
6
6
|
import { useState, useEffect } from 'react';
|
|
7
7
|
import { BrowserRouter, Routes, Route, Link as RouterLink, NavLink, Outlet, Navigate, } from 'react-router-dom';
|
|
8
|
-
import { Box
|
|
8
|
+
import { Box } from '@datalayer/primer-addons';
|
|
9
|
+
import { Button, Heading, Text, TextInput } from '@primer/react';
|
|
9
10
|
import { useNavigate, useLocation, useParams, useHistory } from '../hooks';
|
|
10
11
|
/**
|
|
11
12
|
* Navigation Logger Component - Shows all navigation events
|
|
@@ -18,16 +19,7 @@ const NavigationLogger = () => {
|
|
|
18
19
|
const log = `[${new Date().toLocaleTimeString()}] Navigated to ${location.pathname}${location.search}${location.hash} | Params: ${JSON.stringify(params)} | State: ${JSON.stringify(location.state)}`;
|
|
19
20
|
setLogs(prev => [...prev.slice(-9), log]);
|
|
20
21
|
}, [location, params]);
|
|
21
|
-
return (_jsxs(Box, { sx: {
|
|
22
|
-
p: 2,
|
|
23
|
-
mb: 3,
|
|
24
|
-
bg: 'canvas.subtle',
|
|
25
|
-
borderRadius: 2,
|
|
26
|
-
fontSize: 0,
|
|
27
|
-
fontFamily: 'mono',
|
|
28
|
-
maxHeight: 150,
|
|
29
|
-
overflowY: 'auto',
|
|
30
|
-
}, children: [_jsx(Text, { as: "div", sx: { fontWeight: 'bold', mb: 1 }, children: "Navigation Log:" }), logs.map((log, i) => (_jsx(Text, { as: "div", sx: { color: 'fg.muted' }, children: log }, i)))] }));
|
|
22
|
+
return (_jsxs(Box, { p: 2, mb: 3, bg: "canvas.subtle", borderRadius: 2, fontSize: 0, fontFamily: "mono", maxHeight: 150, overflowY: "auto", children: [_jsx(Text, { as: "div", sx: { fontWeight: 'bold', mb: 1 }, children: "Navigation Log:" }), logs.map((log, i) => (_jsx(Text, { as: "div", sx: { color: 'fg.muted' }, children: log }, i)))] }));
|
|
31
23
|
};
|
|
32
24
|
/**
|
|
33
25
|
* Navigation Controls - Test all navigation methods
|
|
@@ -55,26 +47,13 @@ const NavigationControls = () => {
|
|
|
55
47
|
const handleComplexNavigation = () => {
|
|
56
48
|
navigate('/products/123/reviews?sort=newest#review-42');
|
|
57
49
|
};
|
|
58
|
-
return (_jsxs(Box, { sx: {
|
|
59
|
-
p: 3,
|
|
60
|
-
borderWidth: 1,
|
|
61
|
-
borderStyle: 'solid',
|
|
62
|
-
borderColor: 'border.default',
|
|
63
|
-
borderRadius: 2,
|
|
64
|
-
mb: 3,
|
|
65
|
-
}, children: [_jsx(Heading, { as: "h3", sx: { mb: 3 }, children: "Navigation Controls" }), _jsxs(Box, { sx: { mb: 3 }, children: [_jsx(Text, { as: "label", sx: { display: 'block', mb: 1, fontSize: 1 }, children: "Custom Path:" }), _jsx(TextInput, { value: customPath, onChange: e => setCustomPath(e.target.value), sx: { mb: 2 } }), _jsx(Button, { onClick: () => navigate(customPath), sx: { mr: 2 }, children: "Navigate to Custom Path" })] }), _jsxs(Box, { sx: { mb: 3 }, children: [_jsx(Text, { as: "label", sx: { display: 'block', mb: 1, fontSize: 1 }, children: "State Value:" }), _jsx(TextInput, { value: stateValue, onChange: e => setStateValue(e.target.value), placeholder: "Enter state to pass", sx: { mb: 2 } }), _jsx(Button, { onClick: handleNavigateWithState, variant: "primary", children: "Navigate with State" })] }), _jsxs(Box, { sx: { display: 'flex', gap: 2, flexWrap: 'wrap', mb: 3 }, children: [_jsx(Button, { onClick: () => history.back(), variant: "default", children: "\u2190 Back" }), _jsx(Button, { onClick: () => history.forward(), variant: "default", children: "Forward \u2192" }), _jsx(Button, { onClick: handleReplaceWithState, variant: "default", children: "Replace Current" }), _jsx(Button, { onClick: handleNavigateWithQuery, variant: "default", children: "Nav with Query" }), _jsx(Button, { onClick: handleNavigateWithHash, variant: "default", children: "Nav with Hash" }), _jsx(Button, { onClick: handleComplexNavigation, variant: "default", children: "Complex Navigation" })] }), _jsx(Box, { sx: { p: 2, bg: 'canvas.inset', borderRadius: 1 }, children: _jsxs(Text, { as: "div", sx: { fontSize: 0, fontFamily: 'mono' }, children: [_jsx("strong", { children: "Current Location:" }), _jsx("br", {}), "Path: ", location.pathname, _jsx("br", {}), "Search: ", location.search || '(none)', _jsx("br", {}), "Hash: ", location.hash || '(none)', _jsx("br", {}), "State: ", JSON.stringify(location.state) || '(none)'] }) })] }));
|
|
50
|
+
return (_jsxs(Box, { p: 3, borderWidth: 1, borderStyle: "solid", borderColor: "border.default", borderRadius: 2, mb: 3, children: [_jsx(Heading, { as: "h3", sx: { mb: 3 }, children: "Navigation Controls" }), _jsxs(Box, { mb: 3, children: [_jsx(Text, { as: "label", sx: { display: 'block', mb: 1, fontSize: 1 }, children: "Custom Path:" }), _jsx(TextInput, { value: customPath, onChange: e => setCustomPath(e.target.value), sx: { mb: 2 } }), _jsx(Button, { onClick: () => navigate(customPath), sx: { mr: 2 }, children: "Navigate to Custom Path" })] }), _jsxs(Box, { mb: 3, children: [_jsx(Text, { as: "label", sx: { display: 'block', mb: 1, fontSize: 1 }, children: "State Value:" }), _jsx(TextInput, { value: stateValue, onChange: e => setStateValue(e.target.value), placeholder: "Enter state to pass", sx: { mb: 2 } }), _jsx(Button, { onClick: handleNavigateWithState, variant: "primary", children: "Navigate with State" })] }), _jsxs(Box, { display: "flex", gap: 2, flexWrap: "wrap", mb: 3, children: [_jsx(Button, { onClick: () => history.back(), variant: "default", children: "\u2190 Back" }), _jsx(Button, { onClick: () => history.forward(), variant: "default", children: "Forward \u2192" }), _jsx(Button, { onClick: handleReplaceWithState, variant: "default", children: "Replace Current" }), _jsx(Button, { onClick: handleNavigateWithQuery, variant: "default", children: "Nav with Query" }), _jsx(Button, { onClick: handleNavigateWithHash, variant: "default", children: "Nav with Hash" }), _jsx(Button, { onClick: handleComplexNavigation, variant: "default", children: "Complex Navigation" })] }), _jsx(Box, { p: 2, bg: "canvas.inset", borderRadius: 1, children: _jsxs(Text, { as: "div", sx: { fontSize: 0, fontFamily: 'mono' }, children: [_jsx("strong", { children: "Current Location:" }), _jsx("br", {}), "Path: ", location.pathname, _jsx("br", {}), "Search: ", location.search || '(none)', _jsx("br", {}), "Hash: ", location.hash || '(none)', _jsx("br", {}), "State: ", JSON.stringify(location.state) || '(none)'] }) })] }));
|
|
66
51
|
};
|
|
67
52
|
/**
|
|
68
53
|
* Layout Component with Navigation Menu
|
|
69
54
|
*/
|
|
70
55
|
const Layout = () => {
|
|
71
|
-
return (_jsxs(Box, { children: [_jsx(Box, { as: "nav",
|
|
72
|
-
p: 3,
|
|
73
|
-
bg: 'canvas.subtle',
|
|
74
|
-
borderBottom: '1px solid',
|
|
75
|
-
borderColor: 'border.default',
|
|
76
|
-
mb: 3,
|
|
77
|
-
}, children: _jsxs(Box, { sx: { display: 'flex', gap: 3, flexWrap: 'wrap' }, children: [_jsx(NavLink, { to: "/", style: ({ isActive }) => ({
|
|
56
|
+
return (_jsxs(Box, { children: [_jsx(Box, { as: "nav", p: 3, bg: "canvas.subtle", borderBottom: "1px solid", borderColor: "border.default", mb: 3, children: _jsxs(Box, { display: "flex", gap: 3, flexWrap: "wrap", children: [_jsx(NavLink, { to: "/", style: ({ isActive }) => ({
|
|
78
57
|
fontWeight: isActive ? 'bold' : 'normal',
|
|
79
58
|
color: isActive ? '#16A085' : 'inherit',
|
|
80
59
|
textDecoration: 'none',
|
|
@@ -94,27 +73,20 @@ const Layout = () => {
|
|
|
94
73
|
fontWeight: isActive ? 'bold' : 'normal',
|
|
95
74
|
color: isActive ? '#16A085' : 'inherit',
|
|
96
75
|
textDecoration: 'none',
|
|
97
|
-
}), children: "Settings" })] }) }), _jsx(NavigationLogger, {}), _jsx(NavigationControls, {}), _jsx(Box, {
|
|
98
|
-
p: 3,
|
|
99
|
-
borderWidth: 1,
|
|
100
|
-
borderStyle: 'solid',
|
|
101
|
-
borderColor: 'border.default',
|
|
102
|
-
borderRadius: 2,
|
|
103
|
-
minHeight: 200,
|
|
104
|
-
}, children: _jsx(Outlet, {}) })] }));
|
|
76
|
+
}), children: "Settings" })] }) }), _jsx(NavigationLogger, {}), _jsx(NavigationControls, {}), _jsx(Box, { p: 3, borderWidth: 1, borderStyle: "solid", borderColor: "border.default", borderRadius: 2, minHeight: 200, children: _jsx(Outlet, {}) })] }));
|
|
105
77
|
};
|
|
106
78
|
/**
|
|
107
79
|
* Page Components
|
|
108
80
|
*/
|
|
109
81
|
const HomePage = () => (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 3 }, children: "Home Page" }), _jsx(Text, { as: "p", children: "Welcome to the comprehensive React Router example. This demonstrates:" }), _jsxs("ul", { children: [_jsx("li", { children: "Programmatic navigation with useNavigate" }), _jsx("li", { children: "Route parameters with useParams" }), _jsx("li", { children: "Query parameters and hash navigation" }), _jsx("li", { children: "Navigation state passing" }), _jsx("li", { children: "Browser history (back/forward)" }), _jsx("li", { children: "Nested routes" }), _jsx("li", { children: "Protected routes" }), _jsx("li", { children: "Active link styling" })] })] }));
|
|
110
|
-
const DashboardLayout = () => (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Dashboard" }), _jsxs(Box, {
|
|
82
|
+
const DashboardLayout = () => (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Dashboard" }), _jsxs(Box, { display: "flex", gap: 2, mb: 3, children: [_jsx(RouterLink, { to: "/dashboard", children: "Overview" }), _jsx(RouterLink, { to: "/dashboard/analytics", children: "Analytics" }), _jsx(RouterLink, { to: "/dashboard/reports", children: "Reports" })] }), _jsx(Outlet, {})] }));
|
|
111
83
|
const DashboardOverview = () => {
|
|
112
84
|
const location = useLocation();
|
|
113
|
-
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { mb: 2 }, children: "Overview" }), location.state && (_jsx(Box, {
|
|
85
|
+
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { mb: 2 }, children: "Overview" }), location.state && (_jsx(Box, { p: 2, bg: "success.subtle", borderRadius: 1, mb: 2, children: _jsxs(Text, { children: ["State received: ", JSON.stringify(location.state)] }) })), _jsx(Text, { children: "Dashboard overview content here..." })] }));
|
|
114
86
|
};
|
|
115
87
|
const DashboardAnalytics = () => {
|
|
116
88
|
const location = useLocation();
|
|
117
|
-
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { mb: 2 }, children: "Analytics" }), location.state && (_jsx(Box, {
|
|
89
|
+
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { mb: 2 }, children: "Analytics" }), location.state && (_jsx(Box, { p: 2, bg: "success.subtle", borderRadius: 1, mb: 2, children: _jsxs(Text, { children: ["State received: ", JSON.stringify(location.state)] }) })), _jsx(Text, { children: "Analytics data visualization would go here..." })] }));
|
|
118
90
|
};
|
|
119
91
|
const DashboardReports = () => (_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { mb: 2 }, children: "Reports" }), _jsx(Text, { children: "Reports section content..." })] }));
|
|
120
92
|
const ProductList = () => {
|
|
@@ -124,12 +96,12 @@ const ProductList = () => {
|
|
|
124
96
|
{ id: 2, name: 'Product B' },
|
|
125
97
|
{ id: 3, name: 'Product C' },
|
|
126
98
|
];
|
|
127
|
-
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 3 }, children: "Products" }), _jsx(Box, {
|
|
99
|
+
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 3 }, children: "Products" }), _jsx(Box, { display: "grid", gap: 2, children: products.map(product => (_jsxs(Button, { onClick: () => navigate(`/products/${product.id}`), variant: "default", sx: { justifyContent: 'flex-start' }, children: [product.name, " \u2192"] }, product.id))) })] }));
|
|
128
100
|
};
|
|
129
101
|
const ProductDetail = () => {
|
|
130
102
|
const params = useParams();
|
|
131
103
|
const navigate = useNavigate();
|
|
132
|
-
return (_jsxs(Box, { children: [_jsx(Button, { onClick: () => navigate('/products'), variant: "default", sx: { mb: 3 }, children: "\u2190 Back to Products" }), _jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Product Details" }), _jsxs(Text, { as: "p", children: ["Product ID: ", params.id] }), _jsxs(Text, { as: "p", children: ["All params: ", JSON.stringify(params)] }), _jsx(Box, {
|
|
104
|
+
return (_jsxs(Box, { children: [_jsx(Button, { onClick: () => navigate('/products'), variant: "default", sx: { mb: 3 }, children: "\u2190 Back to Products" }), _jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Product Details" }), _jsxs(Text, { as: "p", children: ["Product ID: ", params.id] }), _jsxs(Text, { as: "p", children: ["All params: ", JSON.stringify(params)] }), _jsx(Box, { mt: 3, children: _jsx(Button, { onClick: () => navigate(`/products/${params.id}/reviews`), variant: "primary", children: "View Reviews" }) })] }));
|
|
133
105
|
};
|
|
134
106
|
const ProductReviews = () => {
|
|
135
107
|
const params = useParams();
|
|
@@ -149,11 +121,11 @@ const SearchPage = () => {
|
|
|
149
121
|
};
|
|
150
122
|
const DocsPage = () => {
|
|
151
123
|
const location = useLocation();
|
|
152
|
-
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Documentation" }), _jsxs(Text, { as: "p", children: ["Current hash: ", location.hash || '(none)'] }), location.hash === '#installation' && (_jsxs(Box, {
|
|
124
|
+
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Documentation" }), _jsxs(Text, { as: "p", children: ["Current hash: ", location.hash || '(none)'] }), location.hash === '#installation' && (_jsxs(Box, { p: 2, bg: "attention.subtle", borderRadius: 1, mt: 2, children: [_jsx(Heading, { as: "h2", sx: { mb: 1 }, children: "Installation" }), _jsx(Text, { children: "Installation instructions would be here..." })] }))] }));
|
|
153
125
|
};
|
|
154
126
|
const SettingsPage = () => {
|
|
155
127
|
const location = useLocation();
|
|
156
|
-
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Settings" }), location.state?.replaced && (_jsxs(Box, {
|
|
128
|
+
return (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Settings" }), location.state?.replaced && (_jsxs(Box, { p: 2, bg: "attention.subtle", borderRadius: 1, mb: 2, children: [_jsx(Text, { children: "This page replaced the previous history entry!" }), _jsxs(Text, { children: ["Time: ", new Date(location.state.time).toLocaleTimeString()] })] })), _jsx(Text, { children: "Settings configuration would go here..." })] }));
|
|
157
129
|
};
|
|
158
130
|
const NotFound = () => (_jsxs(Box, { children: [_jsx(Heading, { as: "h1", sx: { mb: 2, color: 'danger.fg' }, children: "404 - Not Found" }), _jsx(Text, { children: "The page you're looking for doesn't exist." })] }));
|
|
159
131
|
/**
|
|
@@ -170,6 +142,6 @@ const ProtectedRoute = ({ children, }) => {
|
|
|
170
142
|
* Main App Component - Advanced React Router Example
|
|
171
143
|
*/
|
|
172
144
|
export const ReactRouterAdvancedExample = () => {
|
|
173
|
-
return (_jsx(BrowserRouter, { children: _jsxs(Box, {
|
|
145
|
+
return (_jsx(BrowserRouter, { children: _jsxs(Box, { minHeight: "100vh", p: 4, children: [_jsxs(Box, { mb: 4, p: 3, bg: "canvas.subtle", borderRadius: 2, children: [_jsx(Heading, { as: "h1", sx: { mb: 2 }, children: "Advanced React Router Navigation Example" }), _jsx(Text, { as: "p", sx: { mb: 2 }, children: "This comprehensive example demonstrates all navigation features working with our custom hooks that detect and use React Router." }), _jsx(Text, { as: "p", sx: { color: 'success.fg', fontWeight: 'bold' }, children: "\u2713 React Router detected and integrated with Datalayer Client hooks" })] }), _jsx(Routes, { children: _jsxs(Route, { path: "/", element: _jsx(Layout, {}), children: [_jsx(Route, { index: true, element: _jsx(HomePage, {}) }), _jsxs(Route, { path: "dashboard", element: _jsx(DashboardLayout, {}), children: [_jsx(Route, { index: true, element: _jsx(DashboardOverview, {}) }), _jsx(Route, { path: "analytics", element: _jsx(DashboardAnalytics, {}) }), _jsx(Route, { path: "reports", element: _jsx(DashboardReports, {}) })] }), _jsx(Route, { path: "products/:id/reviews", element: _jsx(ProductReviews, {}) }), _jsx(Route, { path: "products/:id", element: _jsx(ProductDetail, {}) }), _jsx(Route, { path: "products", element: _jsx(ProductList, {}) }), _jsx(Route, { path: "users/:username", element: _jsx(UserProfile, {}) }), _jsx(Route, { path: "search", element: _jsx(SearchPage, {}) }), _jsx(Route, { path: "docs", element: _jsx(DocsPage, {}) }), _jsx(Route, { path: "settings", element: _jsx(ProtectedRoute, { children: _jsx(SettingsPage, {}) }) }), _jsx(Route, { path: "custom", element: _jsx(HomePage, {}) }), _jsx(Route, { path: "*", element: _jsx(NotFound, {}) })] }) })] }) }));
|
|
174
146
|
};
|
|
175
147
|
export default ReactRouterAdvancedExample;
|
|
@@ -1,37 +1,6 @@
|
|
|
1
1
|
import type { ToolApprovalFilters } from '../types/tool-approvals';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* camelCase (TypeScript-idiomatic) keys are present so existing UI
|
|
5
|
-
* consumers keep working regardless of which naming they read.
|
|
6
|
-
*/
|
|
7
|
-
export type ApprovalRecord = {
|
|
8
|
-
id: string;
|
|
9
|
-
agent_id: string;
|
|
10
|
-
agentId: string;
|
|
11
|
-
runtime_name: string;
|
|
12
|
-
runtimeName: string;
|
|
13
|
-
tool_name: string;
|
|
14
|
-
toolName: string;
|
|
15
|
-
tool_call_id?: string;
|
|
16
|
-
toolCallId?: string;
|
|
17
|
-
tool_args: Record<string, unknown>;
|
|
18
|
-
toolArgs: Record<string, unknown>;
|
|
19
|
-
status: string;
|
|
20
|
-
note?: string | null;
|
|
21
|
-
requester_uid?: string;
|
|
22
|
-
requesterUid?: string;
|
|
23
|
-
requested_by?: string;
|
|
24
|
-
requestedBy?: string;
|
|
25
|
-
resolved_by?: string;
|
|
26
|
-
resolvedBy?: string;
|
|
27
|
-
resolved_at?: string;
|
|
28
|
-
resolvedAt?: string;
|
|
29
|
-
created_at: string;
|
|
30
|
-
createdAt: string;
|
|
31
|
-
updated_at?: string;
|
|
32
|
-
updatedAt?: string;
|
|
33
|
-
read?: boolean;
|
|
34
|
-
};
|
|
2
|
+
import { type ApprovalRecord } from '../utils/approvals';
|
|
3
|
+
export type { ApprovalRecord };
|
|
35
4
|
interface ApprovalsQueryData {
|
|
36
5
|
approvals: ApprovalRecord[];
|
|
37
6
|
total: number;
|
|
@@ -80,4 +49,3 @@ export declare function useToolApprovals(filters?: ToolApprovalFilters): {
|
|
|
80
49
|
remove: MutationResult;
|
|
81
50
|
connectionState: WSConnectionState;
|
|
82
51
|
};
|
|
83
|
-
export {};
|
|
@@ -21,72 +21,9 @@
|
|
|
21
21
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
22
22
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
23
23
|
import { useAIAgentsWebSocket } from './useAIAgentsWebSocket';
|
|
24
|
+
import { normalizeApproval } from '../utils/approvals';
|
|
24
25
|
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
25
26
|
const APPROVALS_ROOT_KEY = ['tool-approvals'];
|
|
26
|
-
function str(value) {
|
|
27
|
-
return typeof value === 'string' ? value : value == null ? '' : String(value);
|
|
28
|
-
}
|
|
29
|
-
function normalizeApproval(raw) {
|
|
30
|
-
if (!raw || typeof raw !== 'object')
|
|
31
|
-
return null;
|
|
32
|
-
const rec = raw;
|
|
33
|
-
const idSource = rec.id ?? rec.approval_id ?? rec.approvalId;
|
|
34
|
-
const id = typeof idSource === 'string' ? idSource : undefined;
|
|
35
|
-
if (!id)
|
|
36
|
-
return null;
|
|
37
|
-
const agent = str(rec.agent_id ?? rec.agentId);
|
|
38
|
-
const pod = str(rec.runtime_name ?? rec.runtimeName);
|
|
39
|
-
const tool = str(rec.tool_name ?? rec.toolName ?? 'unknown');
|
|
40
|
-
const toolCall = rec.tool_call_id ?? rec.toolCallId;
|
|
41
|
-
const args = rec.tool_args ??
|
|
42
|
-
rec.toolArgs ??
|
|
43
|
-
{};
|
|
44
|
-
const created = str(rec.created_at ?? rec.createdAt);
|
|
45
|
-
const updated = str(rec.updated_at ?? rec.updatedAt);
|
|
46
|
-
const resolvedBy = str(rec.resolved_by ?? rec.resolvedBy);
|
|
47
|
-
const requesterUid = str(rec.requester_uid ?? rec.requesterUid);
|
|
48
|
-
const requestedBy = str(rec.requested_by ?? rec.requestedBy);
|
|
49
|
-
const resolvedAtRaw = str(rec.resolved_at ?? rec.resolvedAt);
|
|
50
|
-
const status = str(rec.status ?? 'pending');
|
|
51
|
-
// Keep reviewer metadata from WS payloads. If this is dropped during
|
|
52
|
-
// normalization, downstream pages receive status=approved/rejected but no
|
|
53
|
-
// reviewer/timestamp context and can incorrectly render "review pending".
|
|
54
|
-
// Some producers only set updated_at on decision; for non-pending statuses,
|
|
55
|
-
// fall back to updated_at so UI can still show a decision time.
|
|
56
|
-
const resolvedAt = resolvedAtRaw || (status !== 'pending' ? updated || undefined : undefined);
|
|
57
|
-
return {
|
|
58
|
-
id,
|
|
59
|
-
agent_id: agent,
|
|
60
|
-
agentId: agent,
|
|
61
|
-
runtime_name: pod,
|
|
62
|
-
runtimeName: pod,
|
|
63
|
-
tool_name: tool,
|
|
64
|
-
toolName: tool,
|
|
65
|
-
tool_call_id: typeof toolCall === 'string' ? toolCall : undefined,
|
|
66
|
-
toolCallId: typeof toolCall === 'string' ? toolCall : undefined,
|
|
67
|
-
tool_args: args,
|
|
68
|
-
toolArgs: args,
|
|
69
|
-
status,
|
|
70
|
-
note: typeof rec.note === 'string'
|
|
71
|
-
? rec.note
|
|
72
|
-
: rec.note === null
|
|
73
|
-
? null
|
|
74
|
-
: undefined,
|
|
75
|
-
requester_uid: requesterUid || undefined,
|
|
76
|
-
requesterUid: requesterUid || undefined,
|
|
77
|
-
requested_by: requestedBy || undefined,
|
|
78
|
-
requestedBy: requestedBy || undefined,
|
|
79
|
-
resolved_by: resolvedBy || undefined,
|
|
80
|
-
resolvedBy: resolvedBy || undefined,
|
|
81
|
-
resolved_at: resolvedAt,
|
|
82
|
-
resolvedAt: resolvedAt,
|
|
83
|
-
created_at: created,
|
|
84
|
-
createdAt: created,
|
|
85
|
-
updated_at: updated || undefined,
|
|
86
|
-
updatedAt: updated || undefined,
|
|
87
|
-
read: typeof rec.read === 'boolean' ? rec.read : undefined,
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
27
|
function matchesFilter(a, filters) {
|
|
91
28
|
if (!filters)
|
|
92
29
|
return true;
|
|
@@ -10,7 +10,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
* @module components/identity/AgentIdentity
|
|
11
11
|
*/
|
|
12
12
|
import React, { useCallback, useMemo } from 'react';
|
|
13
|
-
import { Box
|
|
13
|
+
import { Box } from '@datalayer/primer-addons';
|
|
14
|
+
import { Text, Button, Label, Avatar, Flash, Tooltip } from '@primer/react';
|
|
14
15
|
import { MarkGithubIcon, LinkIcon, UnlinkIcon, CheckCircleFillIcon, AlertIcon, ClockIcon, SyncIcon, KeyIcon, } from '@primer/octicons-react';
|
|
15
16
|
import { useIdentity } from './useIdentity';
|
|
16
17
|
import { IdentityButton } from './IdentityConnect';
|
|
@@ -175,38 +176,20 @@ export function IdentityCard({ identity, providerConfig, showExpirationDetails =
|
|
|
175
176
|
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
176
177
|
}
|
|
177
178
|
}, [provider, disconnect, onDisconnect, onError]);
|
|
178
|
-
return (_jsxs(Box, {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
? '
|
|
186
|
-
: tokenStatus.isExpiringSoon
|
|
187
|
-
? 'attention.muted'
|
|
188
|
-
: 'success.muted',
|
|
189
|
-
borderRadius: 2,
|
|
190
|
-
backgroundColor: tokenStatus.isExpired
|
|
191
|
-
? 'danger.subtle'
|
|
192
|
-
: tokenStatus.isExpiringSoon
|
|
193
|
-
? 'attention.subtle'
|
|
194
|
-
: 'success.subtle',
|
|
195
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Box, { sx: {
|
|
196
|
-
width: 32,
|
|
197
|
-
height: 32,
|
|
198
|
-
borderRadius: 2,
|
|
199
|
-
display: 'flex',
|
|
200
|
-
alignItems: 'center',
|
|
201
|
-
justifyContent: 'center',
|
|
202
|
-
backgroundColor: display.color,
|
|
203
|
-
color: 'white',
|
|
204
|
-
}, children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, { sx: { flex: 1, display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: display.name }), _jsx(Label, { size: "small", variant: "secondary", children: identity.authType === 'token' ? 'API Key' : 'OAuth' })] }), tokenStatus.isExpired ? (_jsx(Label, { variant: "danger", size: "small", children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(AlertIcon, { size: 12 }), " Expired"] }) })) : tokenStatus.isExpiringSoon ? (_jsx(Label, { variant: "attention", size: "small", children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(ClockIcon, { size: 12 }), " Expiring Soon"] }) })) : (_jsx(Label, { variant: "success", size: "small", children: _jsxs(Box, { sx: { display: 'inline-flex', alignItems: 'center', gap: 1 }, children: [_jsx(CheckCircleFillIcon, { size: 12 }), " Connected"] }) }))] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [identity.userInfo?.avatarUrl && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
179
|
+
return (_jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, p: 3, border: "1px solid", borderColor: tokenStatus.isExpired
|
|
180
|
+
? 'danger.muted'
|
|
181
|
+
: tokenStatus.isExpiringSoon
|
|
182
|
+
? 'attention.muted'
|
|
183
|
+
: 'success.muted', borderRadius: 2, backgroundColor: tokenStatus.isExpired
|
|
184
|
+
? 'danger.subtle'
|
|
185
|
+
: tokenStatus.isExpiringSoon
|
|
186
|
+
? 'attention.subtle'
|
|
187
|
+
: 'success.subtle', children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Box, { width: 32, height: 32, borderRadius: 2, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: display.color, color: "white", children: _jsx(display.icon, { size: 16 }) }), _jsxs(Box, { flex: 1, display: "flex", alignItems: "center", gap: 2, children: [_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: display.name }), _jsx(Label, { size: "small", variant: "secondary", children: identity.authType === 'token' ? 'API Key' : 'OAuth' })] }), tokenStatus.isExpired ? (_jsx(Label, { variant: "danger", size: "small", children: _jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 1, children: [_jsx(AlertIcon, { size: 12 }), " Expired"] }) })) : tokenStatus.isExpiringSoon ? (_jsx(Label, { variant: "attention", size: "small", children: _jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 1, children: [_jsx(ClockIcon, { size: 12 }), " Expiring Soon"] }) })) : (_jsx(Label, { variant: "success", size: "small", children: _jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 1, children: [_jsx(CheckCircleFillIcon, { size: 12 }), " Connected"] }) }))] }), _jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [identity.userInfo?.avatarUrl && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
205
188
|
(provider === 'github'
|
|
206
189
|
? `https://github.com/${identity.userInfo.username}`
|
|
207
190
|
: undefined), target: "_blank", rel: "noopener noreferrer", style: { display: 'block', lineHeight: 0 }, children: _jsx(Avatar, { src: identity.userInfo.avatarUrl, size: 32, alt: identity.userInfo.name ||
|
|
208
191
|
identity.userInfo.username ||
|
|
209
|
-
display.name, sx: { cursor: 'pointer' } }) })), _jsxs(Box, {
|
|
192
|
+
display.name, sx: { cursor: 'pointer' } }) })), _jsxs(Box, { flex: 1, minWidth: 0, children: [identity.userInfo?.name && (_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1, display: 'block' }, children: identity.userInfo.name })), (identity.userInfo?.username || identity.userInfo?.email) && (_jsx("a", { href: identity.userInfo.profileUrl ||
|
|
210
193
|
(provider === 'github'
|
|
211
194
|
? `https://github.com/${identity.userInfo.username}`
|
|
212
195
|
: undefined), target: "_blank", rel: "noopener noreferrer", style: { textDecoration: 'none' }, children: _jsx(Text, { sx: {
|
|
@@ -216,26 +199,14 @@ export function IdentityCard({ identity, providerConfig, showExpirationDetails =
|
|
|
216
199
|
':hover': { textDecoration: 'underline' },
|
|
217
200
|
}, children: identity.userInfo.username
|
|
218
201
|
? `@${identity.userInfo.username}`
|
|
219
|
-
: identity.userInfo.email }) }))] })] }), showExpirationDetails && (_jsxs(Box, { sx: {
|
|
220
|
-
display: 'flex',
|
|
221
|
-
alignItems: 'center',
|
|
222
|
-
gap: 1,
|
|
223
|
-
}, children: [_jsx(ClockIcon, { size: 12 }), _jsx(Text, { sx: {
|
|
202
|
+
: identity.userInfo.email }) }))] })] }), showExpirationDetails && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(ClockIcon, { size: 12 }), _jsx(Text, { sx: {
|
|
224
203
|
fontSize: 0,
|
|
225
204
|
color: tokenStatus.isExpired
|
|
226
205
|
? 'danger.fg'
|
|
227
206
|
: tokenStatus.isExpiringSoon
|
|
228
207
|
? 'attention.fg'
|
|
229
208
|
: 'fg.muted',
|
|
230
|
-
}, children: formatExpirationStatus(tokenStatus) })] })), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, {
|
|
231
|
-
display: 'flex',
|
|
232
|
-
flexWrap: 'wrap',
|
|
233
|
-
gap: 1,
|
|
234
|
-
}, children: identity.scopes.map(scope => (_jsx(Label, { size: "small", variant: "secondary", children: scope }, scope))) })), _jsxs(Box, { sx: {
|
|
235
|
-
display: 'flex',
|
|
236
|
-
gap: 2,
|
|
237
|
-
mt: 1,
|
|
238
|
-
}, children: [tokenStatus.isExpired &&
|
|
209
|
+
}, children: formatExpirationStatus(tokenStatus) })] })), identity.scopes && identity.scopes.length > 0 && (_jsx(Box, { display: "flex", flexWrap: "wrap", gap: 1, children: identity.scopes.map(scope => (_jsx(Label, { size: "small", variant: "secondary", children: scope }, scope))) })), _jsxs(Box, { display: "flex", gap: 2, mt: 1, children: [tokenStatus.isExpired &&
|
|
239
210
|
allowReconnect &&
|
|
240
211
|
providerConfig?.clientId && (_jsx(Tooltip, { text: "Reconnect to refresh token", children: _jsx(Button, { variant: "primary", size: "small", leadingVisual: SyncIcon, onClick: handleReconnect, disabled: isAuthorizing, children: isAuthorizing ? 'Connecting...' : 'Reconnect' }) })), _jsxs(Button, { variant: tokenStatus.isExpired ? 'invisible' : 'danger', size: "small", leadingVisual: UnlinkIcon, onClick: handleDisconnect, disabled: isAuthorizing, children: ["Disconnect from ", display.name] })] })] }));
|
|
241
212
|
}
|
|
@@ -284,33 +255,17 @@ export function AgentIdentity({ providers, title = 'Connected Accounts', showHea
|
|
|
284
255
|
if (displayIdentities.length === 0 && !providers) {
|
|
285
256
|
return null;
|
|
286
257
|
}
|
|
287
|
-
return (_jsxs(Box, { children: [showHeader && (_jsxs(Box, { sx: {
|
|
288
|
-
display: 'flex',
|
|
289
|
-
alignItems: 'center',
|
|
290
|
-
gap: 2,
|
|
291
|
-
mb: 2,
|
|
292
|
-
}, children: [_jsx(KeyIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', color: 'fg.muted' }, children: title })] })), _jsxs(Box, { sx: {
|
|
293
|
-
p: 3,
|
|
294
|
-
bg: 'canvas.subtle',
|
|
295
|
-
borderRadius: 2,
|
|
296
|
-
border: '1px solid',
|
|
297
|
-
borderColor: 'border.default',
|
|
298
|
-
}, children: [showDescription && (_jsx(Text, { sx: {
|
|
258
|
+
return (_jsxs(Box, { children: [showHeader && (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, mb: 2, children: [_jsx(KeyIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', color: 'fg.muted' }, children: title })] })), _jsxs(Box, { p: 3, bg: "canvas.subtle", borderRadius: 2, border: "1px solid", borderColor: "border.default", children: [showDescription && (_jsx(Text, { sx: {
|
|
299
259
|
fontSize: 0,
|
|
300
260
|
color: 'fg.muted',
|
|
301
261
|
display: 'block',
|
|
302
262
|
mb: displayIdentities.length > 0 ? 3 : 0,
|
|
303
|
-
}, children: description })), error && (_jsx(Flash, { variant: "danger", sx: { mb: 3 }, children: error instanceof Error ? error.message : String(error) })), displayIdentities.length > 0 ? (_jsx(Box, {
|
|
304
|
-
display: 'flex',
|
|
305
|
-
alignItems: 'center',
|
|
306
|
-
gap: 2,
|
|
307
|
-
color: 'fg.muted',
|
|
308
|
-
}, children: [_jsx(LinkIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1 }, children: "No connected accounts" })] })) : null, hasUnconnected && (_jsxs(Box, { sx: { mt: displayIdentities.length > 0 ? 3 : 0 }, children: [displayIdentities.length > 0 && (_jsx(Text, { sx: {
|
|
263
|
+
}, children: description })), error && (_jsx(Flash, { variant: "danger", sx: { mb: 3 }, children: error instanceof Error ? error.message : String(error) })), displayIdentities.length > 0 ? (_jsx(Box, { display: "flex", flexDirection: "column", gap: 2, children: displayIdentities.map(identity => (_jsx(IdentityCard, { identity: identity, providerConfig: providers?.[identity.provider], showExpirationDetails: showExpirationDetails, allowReconnect: allowReconnect, onConnect: onConnect, onDisconnect: onDisconnect, onError: handleError(identity.provider) }, identity.provider))) })) : !hasUnconnected ? (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, color: "fg.muted", children: [_jsx(LinkIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1 }, children: "No connected accounts" })] })) : null, hasUnconnected && (_jsxs(Box, { mt: displayIdentities.length > 0 ? 3 : 0, children: [displayIdentities.length > 0 && (_jsx(Text, { sx: {
|
|
309
264
|
fontSize: 0,
|
|
310
265
|
color: 'fg.muted',
|
|
311
266
|
display: 'block',
|
|
312
267
|
mb: 2,
|
|
313
|
-
}, children: "Connect additional accounts:" })), _jsx(Box, {
|
|
268
|
+
}, children: "Connect additional accounts:" })), _jsx(Box, { display: "flex", flexDirection: "column", gap: 2, children: Object.keys(unconnectedProviders).map(provider => {
|
|
314
269
|
const config = unconnectedProviders[provider];
|
|
315
270
|
return (_jsx(IdentityButton, { provider: provider, clientId: config.clientId, scopes: config.scopes, providerConfig: config.config, size: "medium", variant: "full", onConnect: onConnect, onDisconnect: onDisconnect, onError: handleError(provider) }, provider));
|
|
316
271
|
}) })] }))] })] }));
|