@flanksource/clicky-ui 0.3.25 → 0.3.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +1 -0
- package/dist/ai.cjs +4 -0
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +6 -2
- package/dist/ai.js.map +1 -1
- package/dist/chat.cjs +8 -0
- package/dist/chat.cjs.map +1 -1
- package/dist/chat.js +9 -1
- package/dist/chat.js.map +1 -1
- package/dist/comments/CommentCard.cjs +89 -14
- package/dist/comments/CommentCard.cjs.map +1 -1
- package/dist/comments/CommentCard.d.ts.map +1 -1
- package/dist/comments/CommentCard.js +90 -15
- package/dist/comments/CommentCard.js.map +1 -1
- package/dist/comments/CommentComposer.cjs +25 -2
- package/dist/comments/CommentComposer.cjs.map +1 -1
- package/dist/comments/CommentComposer.d.ts.map +1 -1
- package/dist/comments/CommentComposer.js +25 -2
- package/dist/comments/CommentComposer.js.map +1 -1
- package/dist/comments/CommentProvider.cjs +21 -14
- package/dist/comments/CommentProvider.cjs.map +1 -1
- package/dist/comments/CommentProvider.d.ts +1 -1
- package/dist/comments/CommentProvider.d.ts.map +1 -1
- package/dist/comments/CommentProvider.js +21 -14
- package/dist/comments/CommentProvider.js.map +1 -1
- package/dist/comments/CommentSidePanel.cjs +1 -1
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.js +1 -1
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/comment-types.cjs.map +1 -1
- package/dist/comments/comment-types.d.ts +6 -0
- package/dist/comments/comment-types.d.ts.map +1 -1
- package/dist/comments/comment-types.js.map +1 -1
- package/dist/components/DimensionField.cjs +56 -0
- package/dist/components/DimensionField.cjs.map +1 -0
- package/dist/components/DimensionField.d.ts +17 -0
- package/dist/components/DimensionField.d.ts.map +1 -0
- package/dist/components/DimensionField.js +56 -0
- package/dist/components/DimensionField.js.map +1 -0
- package/dist/components.cjs +4 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +2 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +4 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +4 -5
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +4 -5
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/TaskExecDetails.cjs +8 -3
- package/dist/data/TaskExecDetails.cjs.map +1 -1
- package/dist/data/TaskExecDetails.d.ts +4 -0
- package/dist/data/TaskExecDetails.d.ts.map +1 -1
- package/dist/data/TaskExecDetails.js +9 -4
- package/dist/data/TaskExecDetails.js.map +1 -1
- package/dist/data/TaskManagerButton.cjs +101 -7
- package/dist/data/TaskManagerButton.cjs.map +1 -1
- package/dist/data/TaskManagerButton.d.ts +6 -1
- package/dist/data/TaskManagerButton.d.ts.map +1 -1
- package/dist/data/TaskManagerButton.js +103 -9
- package/dist/data/TaskManagerButton.js.map +1 -1
- package/dist/data/TaskProcessDetails.cjs +2 -0
- package/dist/data/TaskProcessDetails.cjs.map +1 -1
- package/dist/data/TaskProcessDetails.d.ts.map +1 -1
- package/dist/data/TaskProcessDetails.js +2 -0
- package/dist/data/TaskProcessDetails.js.map +1 -1
- package/dist/data/TaskProgress.cjs +14 -4
- package/dist/data/TaskProgress.cjs.map +1 -1
- package/dist/data/TaskProgress.js +14 -4
- package/dist/data/TaskProgress.js.map +1 -1
- package/dist/data/TaskSnapshot.cjs.map +1 -1
- package/dist/data/TaskSnapshot.d.ts +1 -0
- package/dist/data/TaskSnapshot.d.ts.map +1 -1
- package/dist/data/TaskSnapshot.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +18 -23
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +1 -1
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +19 -24
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.preferences.cjs +12 -21
- package/dist/data/ai/ChatWindow.preferences.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.preferences.d.ts +3 -2
- package/dist/data/ai/ChatWindow.preferences.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.preferences.js +12 -21
- package/dist/data/ai/ChatWindow.preferences.js.map +1 -1
- package/dist/data/ai/ChatWindow.tool-catalog.cjs +21 -38
- package/dist/data/ai/ChatWindow.tool-catalog.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.tool-catalog.d.ts +5 -5
- package/dist/data/ai/ChatWindow.tool-catalog.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.tool-catalog.js +21 -38
- package/dist/data/ai/ChatWindow.tool-catalog.js.map +1 -1
- package/dist/data/ai/ChatWindow.types.d.ts +2 -2
- package/dist/data/ai/ChatWindow.types.d.ts.map +1 -1
- package/dist/data/ai/ChatWindowManager.cjs +2 -2
- package/dist/data/ai/ChatWindowManager.cjs.map +1 -1
- package/dist/data/ai/ChatWindowManager.js +2 -2
- package/dist/data/ai/ChatWindowManager.js.map +1 -1
- package/dist/data/ai/ChatWindowRequestBody.cjs +4 -2
- package/dist/data/ai/ChatWindowRequestBody.cjs.map +1 -1
- package/dist/data/ai/ChatWindowRequestBody.d.ts +15 -3
- package/dist/data/ai/ChatWindowRequestBody.d.ts.map +1 -1
- package/dist/data/ai/ChatWindowRequestBody.js +4 -2
- package/dist/data/ai/ChatWindowRequestBody.js.map +1 -1
- package/dist/data/ai/ToolPreferences.cjs +5 -5
- package/dist/data/ai/ToolPreferences.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.d.ts +6 -5
- package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.js +5 -5
- package/dist/data/ai/ToolPreferences.js.map +1 -1
- package/dist/data/ai/ToolPreferences.model.cjs +61 -37
- package/dist/data/ai/ToolPreferences.model.cjs.map +1 -1
- package/dist/data/ai/ToolPreferences.model.d.ts +32 -13
- package/dist/data/ai/ToolPreferences.model.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferences.model.js +62 -38
- package/dist/data/ai/ToolPreferences.model.js.map +1 -1
- package/dist/data/ai/ToolPreferencesList.cjs +17 -20
- package/dist/data/ai/ToolPreferencesList.cjs.map +1 -1
- package/dist/data/ai/ToolPreferencesList.d.ts +16 -7
- package/dist/data/ai/ToolPreferencesList.d.ts.map +1 -1
- package/dist/data/ai/ToolPreferencesList.js +18 -21
- package/dist/data/ai/ToolPreferencesList.js.map +1 -1
- package/dist/data/ai/chat-window-context.cjs +1 -1
- package/dist/data/ai/chat-window-context.cjs.map +1 -1
- package/dist/data/ai/chat-window-context.d.ts +7 -7
- package/dist/data/ai/chat-window-context.d.ts.map +1 -1
- package/dist/data/ai/chat-window-context.js +1 -1
- package/dist/data/ai/chat-window-context.js.map +1 -1
- package/dist/data/ai/index.d.ts +3 -1
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.cjs +2 -1
- package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
- package/dist/data/chat/clickyOperationsToTools.js +2 -1
- package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
- package/dist/data/chat/index.d.ts +2 -1
- package/dist/data/chat/index.d.ts.map +1 -1
- package/dist/data/chat/tool-policy.cjs +132 -0
- package/dist/data/chat/tool-policy.cjs.map +1 -0
- package/dist/data/chat/tool-policy.d.ts +81 -0
- package/dist/data/chat/tool-policy.d.ts.map +1 -0
- package/dist/data/chat/tool-policy.js +132 -0
- package/dist/data/chat/tool-policy.js.map +1 -0
- package/dist/data/chat/types.cjs +20 -0
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +22 -2
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js +20 -0
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/debugConsoleSignal.cjs +64 -0
- package/dist/data/debugConsoleSignal.cjs.map +1 -0
- package/dist/data/debugConsoleSignal.d.ts +83 -0
- package/dist/data/debugConsoleSignal.d.ts.map +1 -0
- package/dist/data/debugConsoleSignal.js +64 -0
- package/dist/data/debugConsoleSignal.js.map +1 -0
- package/dist/data/har/HarPanel.cjs +20 -14
- package/dist/data/har/HarPanel.cjs.map +1 -1
- package/dist/data/har/HarPanel.d.ts.map +1 -1
- package/dist/data/har/HarPanel.js +20 -14
- package/dist/data/har/HarPanel.js.map +1 -1
- package/dist/data/har/types.d.ts +18 -0
- package/dist/data/har/types.d.ts.map +1 -1
- package/dist/data/query-browser/QueryBrowser.cjs +4 -42
- package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
- package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
- package/dist/data/query-browser/QueryBrowser.js +5 -43
- package/dist/data/query-browser/QueryBrowser.js.map +1 -1
- package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -1
- package/dist/data/query-browser/QueryBrowser.types.d.ts +0 -1
- package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -1
- package/dist/data/query-browser/QueryBrowser.types.js.map +1 -1
- package/dist/data/useDebugAction.cjs +29 -0
- package/dist/data/useDebugAction.cjs.map +1 -0
- package/dist/data/useDebugAction.d.ts +16 -0
- package/dist/data/useDebugAction.d.ts.map +1 -0
- package/dist/data/useDebugAction.js +29 -0
- package/dist/data/useDebugAction.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +16 -8
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +3 -2
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +16 -8
- package/dist/devtools/DebugConsole.cjs +138 -0
- package/dist/devtools/DebugConsole.cjs.map +1 -0
- package/dist/devtools/DebugConsole.d.ts +23 -0
- package/dist/devtools/DebugConsole.d.ts.map +1 -0
- package/dist/devtools/DebugConsole.js +138 -0
- package/dist/devtools/DebugConsole.js.map +1 -0
- package/dist/devtools/DebugConsoleButton.cjs +59 -0
- package/dist/devtools/DebugConsoleButton.cjs.map +1 -0
- package/dist/devtools/DebugConsoleButton.d.ts +20 -0
- package/dist/devtools/DebugConsoleButton.d.ts.map +1 -0
- package/dist/devtools/DebugConsoleButton.js +59 -0
- package/dist/devtools/DebugConsoleButton.js.map +1 -0
- package/dist/devtools/DebugConsoleDock.cjs +112 -0
- package/dist/devtools/DebugConsoleDock.cjs.map +1 -0
- package/dist/devtools/DebugConsoleDock.d.ts +26 -0
- package/dist/devtools/DebugConsoleDock.d.ts.map +1 -0
- package/dist/devtools/DebugConsoleDock.js +112 -0
- package/dist/devtools/DebugConsoleDock.js.map +1 -0
- package/dist/devtools/ExecutionDetail.cjs +135 -0
- package/dist/devtools/ExecutionDetail.cjs.map +1 -0
- package/dist/devtools/ExecutionDetail.d.ts +19 -0
- package/dist/devtools/ExecutionDetail.d.ts.map +1 -0
- package/dist/devtools/ExecutionDetail.js +135 -0
- package/dist/devtools/ExecutionDetail.js.map +1 -0
- package/dist/devtools/debugClient.cjs +172 -0
- package/dist/devtools/debugClient.cjs.map +1 -0
- package/dist/devtools/debugClient.d.ts +98 -0
- package/dist/devtools/debugClient.d.ts.map +1 -0
- package/dist/devtools/debugClient.js +172 -0
- package/dist/devtools/debugClient.js.map +1 -0
- package/dist/devtools/debugStore.cjs +115 -0
- package/dist/devtools/debugStore.cjs.map +1 -0
- package/dist/devtools/debugStore.d.ts +83 -0
- package/dist/devtools/debugStore.d.ts.map +1 -0
- package/dist/devtools/debugStore.js +115 -0
- package/dist/devtools/debugStore.js.map +1 -0
- package/dist/devtools/dockState.cjs +51 -0
- package/dist/devtools/dockState.cjs.map +1 -0
- package/dist/devtools/dockState.d.ts +31 -0
- package/dist/devtools/dockState.d.ts.map +1 -0
- package/dist/devtools/dockState.js +51 -0
- package/dist/devtools/dockState.js.map +1 -0
- package/dist/devtools/tabs/ConsoleTab.cjs +36 -0
- package/dist/devtools/tabs/ConsoleTab.cjs.map +1 -0
- package/dist/devtools/tabs/ConsoleTab.d.ts +19 -0
- package/dist/devtools/tabs/ConsoleTab.d.ts.map +1 -0
- package/dist/devtools/tabs/ConsoleTab.js +36 -0
- package/dist/devtools/tabs/ConsoleTab.js.map +1 -0
- package/dist/devtools/tabs/InspectionCaches.cjs +150 -0
- package/dist/devtools/tabs/InspectionCaches.cjs.map +1 -0
- package/dist/devtools/tabs/InspectionCaches.d.ts +23 -0
- package/dist/devtools/tabs/InspectionCaches.d.ts.map +1 -0
- package/dist/devtools/tabs/InspectionCaches.js +150 -0
- package/dist/devtools/tabs/InspectionCaches.js.map +1 -0
- package/dist/devtools/tabs/InspectionTab.cjs +316 -0
- package/dist/devtools/tabs/InspectionTab.cjs.map +1 -0
- package/dist/devtools/tabs/InspectionTab.d.ts +27 -0
- package/dist/devtools/tabs/InspectionTab.d.ts.map +1 -0
- package/dist/devtools/tabs/InspectionTab.js +316 -0
- package/dist/devtools/tabs/InspectionTab.js.map +1 -0
- package/dist/devtools/tabs/NetworkTab.cjs +91 -0
- package/dist/devtools/tabs/NetworkTab.cjs.map +1 -0
- package/dist/devtools/tabs/NetworkTab.d.ts +20 -0
- package/dist/devtools/tabs/NetworkTab.d.ts.map +1 -0
- package/dist/devtools/tabs/NetworkTab.js +91 -0
- package/dist/devtools/tabs/NetworkTab.js.map +1 -0
- package/dist/devtools/tabs/QueriesTab.cjs +85 -0
- package/dist/devtools/tabs/QueriesTab.cjs.map +1 -0
- package/dist/devtools/tabs/QueriesTab.d.ts +24 -0
- package/dist/devtools/tabs/QueriesTab.d.ts.map +1 -0
- package/dist/devtools/tabs/QueriesTab.js +85 -0
- package/dist/devtools/tabs/QueriesTab.js.map +1 -0
- package/dist/devtools/types.cjs +26 -0
- package/dist/devtools/types.cjs.map +1 -0
- package/dist/devtools/types.d.ts +235 -0
- package/dist/devtools/types.d.ts.map +1 -0
- package/dist/devtools/types.js +26 -0
- package/dist/devtools/types.js.map +1 -0
- package/dist/devtools/useDebugStream.cjs +46 -0
- package/dist/devtools/useDebugStream.cjs.map +1 -0
- package/dist/devtools/useDebugStream.d.ts +23 -0
- package/dist/devtools/useDebugStream.d.ts.map +1 -0
- package/dist/devtools/useDebugStream.js +46 -0
- package/dist/devtools/useDebugStream.js.map +1 -0
- package/dist/devtools.cjs +51 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.ts +37 -0
- package/dist/devtools.d.ts.map +1 -0
- package/dist/devtools.js +51 -0
- package/dist/devtools.js.map +1 -0
- package/dist/icons/components/UiOpenScad.cjs +10 -0
- package/dist/icons/components/UiOpenScad.cjs.map +1 -0
- package/dist/icons/components/UiOpenScad.d.ts +9 -0
- package/dist/icons/components/UiOpenScad.d.ts.map +1 -0
- package/dist/icons/components/UiOpenScad.js +10 -0
- package/dist/icons/components/UiOpenScad.js.map +1 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +2 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +2 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +2 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +2 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +20 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +20 -8
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +15 -10
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts +11 -0
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.js +15 -10
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/layout/AppShell.nav.cjs +170 -49
- package/dist/layout/AppShell.nav.cjs.map +1 -1
- package/dist/layout/AppShell.nav.d.ts.map +1 -1
- package/dist/layout/AppShell.nav.js +170 -49
- package/dist/layout/AppShell.nav.js.map +1 -1
- package/dist/overlay/CellActions.cjs +18 -124
- package/dist/overlay/CellActions.cjs.map +1 -1
- package/dist/overlay/CellActions.d.ts +1 -1
- package/dist/overlay/CellActions.d.ts.map +1 -1
- package/dist/overlay/CellActions.js +18 -124
- package/dist/overlay/CellActions.js.map +1 -1
- package/dist/overlay/ContextMenu.cjs +144 -0
- package/dist/overlay/ContextMenu.cjs.map +1 -0
- package/dist/overlay/ContextMenu.d.ts +8 -0
- package/dist/overlay/ContextMenu.d.ts.map +1 -0
- package/dist/overlay/ContextMenu.js +144 -0
- package/dist/overlay/ContextMenu.js.map +1 -0
- package/dist/profiles/connections/connectionBrowserModel.cjs +14 -65
- package/dist/profiles/connections/connectionBrowserModel.cjs.map +1 -1
- package/dist/profiles/connections/connectionBrowserModel.d.ts +35 -35
- package/dist/profiles/connections/connectionBrowserModel.d.ts.map +1 -1
- package/dist/profiles/connections/connectionBrowserModel.js +14 -65
- package/dist/profiles/connections/connectionBrowserModel.js.map +1 -1
- package/dist/profiles/connections/connectionQueryWorkspace.cjs +29 -9
- package/dist/profiles/connections/connectionQueryWorkspace.cjs.map +1 -1
- package/dist/profiles/connections/connectionQueryWorkspace.d.ts +3 -2
- package/dist/profiles/connections/connectionQueryWorkspace.d.ts.map +1 -1
- package/dist/profiles/connections/connectionQueryWorkspace.js +30 -10
- package/dist/profiles/connections/connectionQueryWorkspace.js.map +1 -1
- package/dist/profiles/connections/connectionQueryWorkspaceModel.cjs +15 -0
- package/dist/profiles/connections/connectionQueryWorkspaceModel.cjs.map +1 -1
- package/dist/profiles/connections/connectionQueryWorkspaceModel.d.ts +22 -1
- package/dist/profiles/connections/connectionQueryWorkspaceModel.d.ts.map +1 -1
- package/dist/profiles/connections/connectionQueryWorkspaceModel.js +15 -0
- package/dist/profiles/connections/connectionQueryWorkspaceModel.js.map +1 -1
- package/dist/profiles/connections/index.d.ts +1 -0
- package/dist/profiles/connections/index.d.ts.map +1 -1
- package/dist/profiles/connections/inspectionStatus.cjs +44 -0
- package/dist/profiles/connections/inspectionStatus.cjs.map +1 -0
- package/dist/profiles/connections/inspectionStatus.d.ts +5 -0
- package/dist/profiles/connections/inspectionStatus.d.ts.map +1 -0
- package/dist/profiles/connections/inspectionStatus.js +44 -0
- package/dist/profiles/connections/inspectionStatus.js.map +1 -0
- package/dist/profiles/connections/useInspection.cjs +123 -0
- package/dist/profiles/connections/useInspection.cjs.map +1 -0
- package/dist/profiles/connections/useInspection.d.ts +35 -0
- package/dist/profiles/connections/useInspection.d.ts.map +1 -0
- package/dist/profiles/connections/useInspection.js +123 -0
- package/dist/profiles/connections/useInspection.js.map +1 -0
- package/dist/profiles/editor/profileBuilderWorkspace.cjs +55 -23
- package/dist/profiles/editor/profileBuilderWorkspace.cjs.map +1 -1
- package/dist/profiles/editor/profileBuilderWorkspace.d.ts.map +1 -1
- package/dist/profiles/editor/profileBuilderWorkspace.js +56 -24
- package/dist/profiles/editor/profileBuilderWorkspace.js.map +1 -1
- package/dist/profiles/elasticsearch/esQueryBuilder.cjs +12 -3
- package/dist/profiles/elasticsearch/esQueryBuilder.cjs.map +1 -1
- package/dist/profiles/elasticsearch/esQueryBuilder.d.ts +2 -2
- package/dist/profiles/elasticsearch/esQueryBuilder.d.ts.map +1 -1
- package/dist/profiles/elasticsearch/esQueryBuilder.js +12 -3
- package/dist/profiles/elasticsearch/esQueryBuilder.js.map +1 -1
- package/dist/profiles/fields/profileFieldEditor.cjs +137 -22
- package/dist/profiles/fields/profileFieldEditor.cjs.map +1 -1
- package/dist/profiles/fields/profileFieldEditor.d.ts.map +1 -1
- package/dist/profiles/fields/profileFieldEditor.js +137 -22
- package/dist/profiles/fields/profileFieldEditor.js.map +1 -1
- package/dist/profiles/fields/profileFieldFilterEditor.cjs +171 -82
- package/dist/profiles/fields/profileFieldFilterEditor.cjs.map +1 -1
- package/dist/profiles/fields/profileFieldFilterEditor.d.ts +0 -9
- package/dist/profiles/fields/profileFieldFilterEditor.d.ts.map +1 -1
- package/dist/profiles/fields/profileFieldFilterEditor.js +174 -85
- package/dist/profiles/fields/profileFieldFilterEditor.js.map +1 -1
- package/dist/profiles/fields/profileFieldIcons.cjs +6 -3
- package/dist/profiles/fields/profileFieldIcons.cjs.map +1 -1
- package/dist/profiles/fields/profileFieldIcons.js +6 -3
- package/dist/profiles/fields/profileFieldIcons.js.map +1 -1
- package/dist/profiles/query/profileSampleFilterLookup.cjs +34 -0
- package/dist/profiles/query/profileSampleFilterLookup.cjs.map +1 -0
- package/dist/profiles/query/profileSampleFilterLookup.d.ts +12 -0
- package/dist/profiles/query/profileSampleFilterLookup.d.ts.map +1 -0
- package/dist/profiles/query/profileSampleFilterLookup.js +34 -0
- package/dist/profiles/query/profileSampleFilterLookup.js.map +1 -0
- package/dist/profiles/query/profileSamplePayload.cjs +6 -4
- package/dist/profiles/query/profileSamplePayload.cjs.map +1 -1
- package/dist/profiles/query/profileSamplePayload.d.ts +11 -4
- package/dist/profiles/query/profileSamplePayload.d.ts.map +1 -1
- package/dist/profiles/query/profileSamplePayload.js +6 -4
- package/dist/profiles/query/profileSamplePayload.js.map +1 -1
- package/dist/profiles/query/profileSampleResult.cjs +26 -0
- package/dist/profiles/query/profileSampleResult.cjs.map +1 -0
- package/dist/profiles/query/profileSampleResult.d.ts +11 -0
- package/dist/profiles/query/profileSampleResult.d.ts.map +1 -0
- package/dist/profiles/query/profileSampleResult.js +26 -0
- package/dist/profiles/query/profileSampleResult.js.map +1 -0
- package/dist/profiles/query/queryTargetPicker.cjs +5 -3
- package/dist/profiles/query/queryTargetPicker.cjs.map +1 -1
- package/dist/profiles/query/queryTargetPicker.d.ts +3 -2
- package/dist/profiles/query/queryTargetPicker.d.ts.map +1 -1
- package/dist/profiles/query/queryTargetPicker.js +5 -3
- package/dist/profiles/query/queryTargetPicker.js.map +1 -1
- package/dist/profiles/wizard/profileWizard.cjs +14 -5
- package/dist/profiles/wizard/profileWizard.cjs.map +1 -1
- package/dist/profiles/wizard/profileWizard.d.ts.map +1 -1
- package/dist/profiles/wizard/profileWizard.js +15 -6
- package/dist/profiles/wizard/profileWizard.js.map +1 -1
- package/dist/profiles/wizard/profileWizardModel.cjs +35 -6
- package/dist/profiles/wizard/profileWizardModel.cjs.map +1 -1
- package/dist/profiles/wizard/profileWizardModel.d.ts +29 -4
- package/dist/profiles/wizard/profileWizardModel.d.ts.map +1 -1
- package/dist/profiles/wizard/profileWizardModel.js +35 -6
- package/dist/profiles/wizard/profileWizardModel.js.map +1 -1
- package/dist/profiles/wizard/profileWizardQueryStep.cjs +44 -11
- package/dist/profiles/wizard/profileWizardQueryStep.cjs.map +1 -1
- package/dist/profiles/wizard/profileWizardQueryStep.d.ts.map +1 -1
- package/dist/profiles/wizard/profileWizardQueryStep.js +46 -13
- package/dist/profiles/wizard/profileWizardQueryStep.js.map +1 -1
- package/dist/profiles/wizard/profileWizardSteps.cjs +33 -2
- package/dist/profiles/wizard/profileWizardSteps.cjs.map +1 -1
- package/dist/profiles/wizard/profileWizardSteps.d.ts +11 -2
- package/dist/profiles/wizard/profileWizardSteps.d.ts.map +1 -1
- package/dist/profiles/wizard/profileWizardSteps.js +33 -2
- package/dist/profiles/wizard/profileWizardSteps.js.map +1 -1
- package/dist/profiles.cjs +8 -2
- package/dist/profiles.cjs.map +1 -1
- package/dist/profiles.js +10 -4
- package/dist/profiles.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +21 -237
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.d.ts +3 -1
- package/dist/rpc/FilterForm.d.ts.map +1 -1
- package/dist/rpc/FilterForm.js +21 -237
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/FilterFormFields.cjs +240 -0
- package/dist/rpc/FilterFormFields.cjs.map +1 -0
- package/dist/rpc/FilterFormFields.d.ts +12 -0
- package/dist/rpc/FilterFormFields.d.ts.map +1 -0
- package/dist/rpc/FilterFormFields.js +240 -0
- package/dist/rpc/FilterFormFields.js.map +1 -0
- package/dist/rpc/router.cjs +3 -2
- package/dist/rpc/router.cjs.map +1 -1
- package/dist/rpc/router.d.ts.map +1 -1
- package/dist/rpc/router.js +3 -2
- package/dist/rpc/router.js.map +1 -1
- package/dist/rpc/types.cjs.map +1 -1
- package/dist/rpc/types.d.ts +3 -1
- package/dist/rpc/types.d.ts.map +1 -1
- package/dist/rpc/types.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -1
- package/dist/data/query-info/QueryInfoDialog.cjs +0 -106
- package/dist/data/query-info/QueryInfoDialog.cjs.map +0 -1
- package/dist/data/query-info/QueryInfoDialog.d.ts +0 -16
- package/dist/data/query-info/QueryInfoDialog.d.ts.map +0 -1
- package/dist/data/query-info/QueryInfoDialog.js +0 -106
- package/dist/data/query-info/QueryInfoDialog.js.map +0 -1
- package/dist/data/query-info/index.d.ts +0 -4
- package/dist/data/query-info/index.d.ts.map +0 -1
- package/dist/data/query-info/queryInfo.cjs +0 -42
- package/dist/data/query-info/queryInfo.cjs.map +0 -1
- package/dist/data/query-info/queryInfo.d.ts +0 -45
- package/dist/data/query-info/queryInfo.d.ts.map +0 -1
- package/dist/data/query-info/queryInfo.js +0 -42
- package/dist/data/query-info/queryInfo.js.map +0 -1
- package/dist/data/query-info/useQueryInfo.cjs +0 -48
- package/dist/data/query-info/useQueryInfo.cjs.map +0 -1
- package/dist/data/query-info/useQueryInfo.d.ts +0 -26
- package/dist/data/query-info/useQueryInfo.d.ts.map +0 -1
- package/dist/data/query-info/useQueryInfo.js +0 -48
- package/dist/data/query-info/useQueryInfo.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const profileApi = require("../profileApi.cjs");
|
|
3
4
|
function applyPatch(value, patch) {
|
|
4
5
|
const next = { ...value };
|
|
5
6
|
for (const [key, entry] of Object.entries(patch)) {
|
|
@@ -93,21 +94,23 @@ function applyVisibleFieldSelection(discovered, configured, visibleNames, select
|
|
|
93
94
|
);
|
|
94
95
|
}
|
|
95
96
|
const PROFILE_FILTER_KIND_OPTIONS = [
|
|
96
|
-
{ value: "terms", label: "Value
|
|
97
|
+
{ value: "terms", label: "Value list" },
|
|
97
98
|
{ value: "exact", label: "Exact match" },
|
|
98
|
-
{ value: "text", label: "
|
|
99
|
+
{ value: "text", label: "Text search" },
|
|
99
100
|
{ value: "range", label: "Numeric range" },
|
|
100
101
|
{ value: "duration", label: "Duration range" },
|
|
101
102
|
{ value: "date", label: "Date range" },
|
|
102
103
|
{ value: "time", label: "Date & time range" },
|
|
103
|
-
{ value: "boolean", label: "
|
|
104
|
+
{ value: "boolean", label: "Boolean" },
|
|
104
105
|
{ value: "none", label: "Not filterable" }
|
|
105
106
|
];
|
|
106
107
|
const PROFILE_FILTER_DEFAULT_LIMIT = 50;
|
|
107
108
|
const PROFILE_FILTER_MAX_LIMIT = 200;
|
|
108
109
|
function patchColumnFilter(filter, patch) {
|
|
109
110
|
const merged = Object.fromEntries(
|
|
110
|
-
Object.entries({ ...filter, ...patch }).filter(
|
|
111
|
+
Object.entries({ ...filter, ...patch }).filter(
|
|
112
|
+
([, value]) => value !== void 0
|
|
113
|
+
)
|
|
111
114
|
);
|
|
112
115
|
return Object.keys(merged).length ? merged : void 0;
|
|
113
116
|
}
|
|
@@ -146,11 +149,36 @@ function renameProfileField(field, name) {
|
|
|
146
149
|
source: source === name ? void 0 : source
|
|
147
150
|
});
|
|
148
151
|
}
|
|
149
|
-
function
|
|
152
|
+
function connectionTypeFromLabel(label) {
|
|
150
153
|
var _a;
|
|
151
154
|
const match = label.match(/\(([^()]+)\)\s*$/);
|
|
152
155
|
return ((_a = match == null ? void 0 : match[1]) == null ? void 0 : _a.trim()) || null;
|
|
153
156
|
}
|
|
157
|
+
function providerTypesForConnectionType(connectionType) {
|
|
158
|
+
const scope = providerConnectionScope();
|
|
159
|
+
const candidates = Object.keys(scope).filter((provider) => {
|
|
160
|
+
var _a;
|
|
161
|
+
return (_a = scope[provider]) == null ? void 0 : _a.includes(connectionType);
|
|
162
|
+
}).sort();
|
|
163
|
+
if (candidates.length <= 1) return candidates;
|
|
164
|
+
const exact = candidates.find((provider) => provider === connectionType);
|
|
165
|
+
if (exact) return [exact];
|
|
166
|
+
const specific = candidates.filter((provider) => provider !== "sql");
|
|
167
|
+
return specific.length === 1 ? specific : candidates;
|
|
168
|
+
}
|
|
169
|
+
function providerConnectionScope() {
|
|
170
|
+
var _a, _b, _c;
|
|
171
|
+
const provider = (_a = profileApi.profileSchema().properties) == null ? void 0 : _a.provider;
|
|
172
|
+
const connection = (_b = provider == null ? void 0 : provider.properties) == null ? void 0 : _b.connection;
|
|
173
|
+
const lookup = connection == null ? void 0 : connection["x-clicky-lookup"];
|
|
174
|
+
const map = (_c = lookup == null ? void 0 : lookup.scope) == null ? void 0 : _c.map;
|
|
175
|
+
if (!map || typeof map !== "object") {
|
|
176
|
+
throw new Error(
|
|
177
|
+
"profile schema is missing provider.connection x-clicky-lookup.scope.map — the wizard cannot resolve a provider for a connection without it"
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
return map;
|
|
181
|
+
}
|
|
154
182
|
function profileConnectionID(value) {
|
|
155
183
|
const prefix = "connection://";
|
|
156
184
|
if (!value.startsWith(prefix)) return null;
|
|
@@ -187,6 +215,7 @@ exports.PROFILE_FILTER_MAX_LIMIT = PROFILE_FILTER_MAX_LIMIT;
|
|
|
187
215
|
exports.applyPatch = applyPatch;
|
|
188
216
|
exports.applyVisibleFieldSelection = applyVisibleFieldSelection;
|
|
189
217
|
exports.availableProfileFields = availableProfileFields;
|
|
218
|
+
exports.connectionTypeFromLabel = connectionTypeFromLabel;
|
|
190
219
|
exports.filterProfileFields = filterProfileFields;
|
|
191
220
|
exports.inferredFilterKind = inferredFilterKind;
|
|
192
221
|
exports.paramHasOptions = paramHasOptions;
|
|
@@ -197,7 +226,7 @@ exports.profileWizardErrorMessage = profileWizardErrorMessage;
|
|
|
197
226
|
exports.profileWizardHasQuery = profileWizardHasQuery;
|
|
198
227
|
exports.profileWizardStepReady = profileWizardStepReady;
|
|
199
228
|
exports.profileWizardSteps = profileWizardSteps;
|
|
200
|
-
exports.
|
|
229
|
+
exports.providerTypesForConnectionType = providerTypesForConnectionType;
|
|
201
230
|
exports.renameProfileField = renameProfileField;
|
|
202
231
|
exports.reorderProfileColumns = reorderProfileColumns;
|
|
203
232
|
exports.withProfileLimits = withProfileLimits;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profileWizardModel.cjs","sources":["../../../src/profiles/wizard/profileWizardModel.ts"],"sourcesContent":["import type { ProfileRowLimits } from \"../connections/connectionBrowserModel\";\n\n/** How a column is filtered at the backend; every field overrides an inference\n * the server would otherwise make from the column itself. */\nexport type ProfileColumnFilter = {\n /** Backend field the selection applies to; blank infers it from the column. */\n field?: string;\n /** terms, range, time, boolean, text or none; blank infers it from the type. */\n kind?: string;\n /** Enumerated values, replacing the backend lookup. */\n options?: string[];\n /** Ask the backend for this field's distinct values. */\n lookup?: boolean;\n /** How many of those values the control offers before the rest are typed for. */\n limit?: number;\n /** Allow several values at once. */\n multi?: boolean;\n /** Offer no filter while keeping the column rendered. */\n disabled?: boolean;\n};\n\n/**\n * A patch of T: every key optional, and explicitly settable to `undefined` to\n * clear it.\n *\n * Not Partial<T>. Under `exactOptionalPropertyTypes` an optional key may be\n * absent but not present-and-undefined, and \"clear this field\" — which is what\n * every editor control sends when its input goes empty — is precisely a present\n * `undefined`. The patch appliers drop those keys; the type has to permit them.\n */\nexport type Patch<T> = { [K in keyof T]?: T[K] | undefined };\n\n/**\n * Applies a patch, removing the keys it clears instead of leaving them present\n * and undefined.\n *\n * Spreading a patch would keep them, and these objects are serialized to the\n * server, where a present `field: undefined` is a key to interpret rather than\n * an absent one.\n */\nexport function applyPatch<T extends object>(value: T, patch: Patch<T>): T {\n const next = { ...value };\n for (const [key, entry] of Object.entries(patch)) {\n if (entry === undefined) delete next[key as keyof T];\n else next[key as keyof T] = entry as T[keyof T];\n }\n return next;\n}\n\nexport type ProfileColumn = {\n name: string;\n source?: string;\n label?: string;\n type?: string;\n kind?: string;\n format?: string;\n unit?: string;\n width?: number;\n cel?: string;\n /** Path computing the value, rooted at the row or at `source` when set. */\n jsonpath?: string;\n hidden?: boolean;\n filter?: ProfileColumnFilter;\n [key: string]: unknown;\n};\n\nexport type ProfileProvider = {\n type?: string;\n connection?: string;\n options?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\n/** The parameter types the profile schema accepts. */\nexport type ParamDraftType = \"string\" | \"number\" | \"boolean\" | \"date\" | \"datetime\" | \"duration\" | \"enum\" | \"list\";\n\n/** filter, limit, offset, time-from or time-to; empty behaves as filter. */\nexport type ParamDraftRole = \"filter\" | \"limit\" | \"offset\" | \"time-from\" | \"time-to\";\n\nexport type ParamDraft = {\n name?: string | undefined;\n label?: string | undefined;\n type?: ParamDraftType | undefined;\n role?: ParamDraftRole | undefined;\n default?: unknown | undefined;\n options?: string[] | undefined;\n required?: boolean | undefined;\n description?: string | undefined;\n /** Value rewrite; {value} is the supplied value. */\n template?: string | undefined;\n /** Backend field a list parameter filters on. Setting it lets a value be\n * excluded as well as included; it requires an OpenSearch-backed provider. */\n field?: string | undefined;\n};\n\n/** PARAM_TYPES_WITH_OPTIONS are the types whose values come from a fixed set, so\n * the editor offers an options picker for them. */\nexport const PARAM_TYPES_WITH_OPTIONS: ParamDraftType[] = [\"enum\", \"list\"];\n\nexport function paramHasOptions(param: ParamDraft): boolean {\n return param.type !== undefined && PARAM_TYPES_WITH_OPTIONS.includes(param.type);\n}\n\nexport type ProfileWizardDraft = Record<string, unknown> & {\n namespace?: string | undefined;\n profile?: string | undefined;\n /** Overrides the sidebar/picker glyph the provider type would otherwise give. */\n icon?: string | undefined;\n provider?: ProfileProvider | undefined;\n query?: string | undefined;\n columns?: ProfileColumn[] | undefined;\n /** The inputs a run binds — by name in the query, the provider options or the\n * connection. The query workspace previews against their defaults. */\n params?: ParamDraft[] | undefined;\n /** The row caps this profile sets for itself; unset ones take their default. */\n limits?: ProfileRowLimits | undefined;\n};\n\n/**\n * A profile that caps nothing carries no block at all, so the defaults are what\n * it inherits rather than what it froze at the moment it was edited. Both draft\n * hosts write the caps through this, so neither can leave an empty map behind.\n */\nexport function withProfileLimits<T extends ProfileWizardDraft>(\n draft: T,\n limits: ProfileRowLimits | undefined,\n): T {\n const next = { ...draft };\n if (limits) next.limits = limits;\n else delete next.limits;\n return next;\n}\n\nexport type ProfileFieldFilter = {\n query: string;\n type: string;\n selection: \"all\" | \"selected\" | \"unselected\";\n};\n\nexport const PROFILE_COLUMN_FORMAT_OPTIONS = [\n { value: \"date\", label: \"Date/time\" },\n { value: \"float\", label: \"Number\" },\n { value: \"duration\", label: \"Duration\" },\n { value: \"bytes\", label: \"Bytes\" },\n { value: \"currency\", label: \"Currency\" },\n] as const;\n\nexport const PROFILE_COLUMN_UNIT_OPTIONS = [\n { value: \"none\", label: \"Compact count\" },\n { value: \"short\", label: \"Short number\" },\n { value: \"percent\", label: \"Percent (0-100)\" },\n { value: \"percentunit\", label: \"Percent (0-1)\" },\n { value: \"bytes\", label: \"Bytes (IEC)\" },\n { value: \"decbytes\", label: \"Bytes (SI)\" },\n { value: \"Bps\", label: \"Bytes/sec\" },\n { value: \"binBps\", label: \"Binary bytes/sec\" },\n { value: \"ms\", label: \"Milliseconds\" },\n { value: \"s\", label: \"Seconds\" },\n] as const;\n\nexport const profileWizardSteps = [\n { id: \"source\", label: \"Choose source\", description: \"Connection\" },\n { id: \"query\", label: \"Explore & sample\", description: \"Query\" },\n { id: \"fields\", label: \"Name & shape\", description: \"Fields\" },\n { id: \"review\", label: \"Review\", description: \"Save\" },\n] as const;\n\nexport function filterProfileFields(\n fields: ProfileColumn[],\n selectedNames: Set<string>,\n filter: ProfileFieldFilter,\n): ProfileColumn[] {\n const query = filter.query.trim().toLowerCase();\n return fields.filter((field) => {\n const selected = selectedNames.has(field.name);\n if (filter.selection === \"selected\" && !selected) return false;\n if (filter.selection === \"unselected\" && selected) return false;\n if (filter.type && field.type !== filter.type) return false;\n if (!query) return true;\n return `${field.name} ${field.label ?? \"\"}`.toLowerCase().includes(query);\n });\n}\n\n/**\n * Every field the editors can show, each in its configured form. A discovered\n * field is a snapshot of what the source reported — the configured one carries\n * the user's edits, so it is the only version safe to render into a control or\n * to patch on top of.\n *\n * The configuration owns the order, because it is the order the profile renders\n * its columns in and the one the user drags rows into. A discovered field that\n * was never configured (not selected, or dropped from the profile) has no place\n * of its own, so it keeps the one it had: it is anchored just after whichever\n * configured field preceded it in the sample.\n */\nexport function availableProfileFields(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n): ProfileColumn[] {\n const configuredByName = new Map(\n configured.map((field) => [field.name, field]),\n );\n const configuredBySource = new Map(\n configured\n .filter((field) => field.source)\n .map((field) => [field.source as string, field]),\n );\n const ordered = [...configured];\n let anchor = 0;\n for (const field of discovered) {\n const match =\n configuredByName.get(field.name) ?? configuredBySource.get(field.name);\n if (match) {\n anchor = ordered.indexOf(match) + 1;\n continue;\n }\n ordered.splice(anchor, 0, field);\n anchor += 1;\n }\n return ordered;\n}\n\n/**\n * Moves the named column onto the target's position, shifting the columns\n * between them — the drop semantics the field grid's row drag needs. Columns\n * are addressed by name because a drag only ever carries the row's identity.\n * A name that is not configured has no position, so the order is returned\n * unchanged rather than guessed at.\n */\nexport function reorderProfileColumns(\n columns: ProfileColumn[],\n sourceName: string,\n targetName: string,\n): ProfileColumn[] {\n const from = columns.findIndex((column) => column.name === sourceName);\n const to = columns.findIndex((column) => column.name === targetName);\n if (from < 0 || to < 0 || from === to) return columns;\n const next = [...columns];\n next.splice(to, 0, ...next.splice(from, 1));\n return next;\n}\n\n/**\n * Selects or deselects the named fields, keeping the configured order intact —\n * a re-selected field returns to where the grid already showed it rather than\n * to the back of the list or to its position in the sample.\n */\nexport function applyVisibleFieldSelection(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n visibleNames: Set<string>,\n selected: boolean,\n): ProfileColumn[] {\n const selectedNames = new Set(configured.map((field) => field.name));\n for (const name of visibleNames) {\n if (selected) selectedNames.add(name);\n else selectedNames.delete(name);\n }\n return availableProfileFields(discovered, configured).filter((field) =>\n selectedNames.has(field.name),\n );\n}\n\n/** The control kinds a column filter can render as, with the server's own\n * wording. Mirrors query.ColumnFilterKindValues() and the x-enum-labels the\n * profile schema carries for them. */\nexport const PROFILE_FILTER_KIND_OPTIONS = [\n { value: \"terms\", label: \"Value selection\" },\n { value: \"exact\", label: \"Exact match\" },\n { value: \"text\", label: \"Substring\" },\n { value: \"range\", label: \"Numeric range\" },\n { value: \"duration\", label: \"Duration range\" },\n { value: \"date\", label: \"Date range\" },\n { value: \"time\", label: \"Date & time range\" },\n { value: \"boolean\", label: \"Yes/no\" },\n { value: \"none\", label: \"Not filterable\" },\n] as const;\n\n/** The server's own default, so an unset limit can be shown for what it does.\n * Mirrors query.DefaultFilterLookupLimit. */\nexport const PROFILE_FILTER_DEFAULT_LIMIT = 50;\n\n/** Mirrors query.MaxFilterLookupLimit — the largest head a lookup will serve. */\nexport const PROFILE_FILTER_MAX_LIMIT = 200;\n\n/**\n * Merges one filter knob into a column's filter block, dropping the block once\n * nothing is left in it.\n *\n * The distinction matters on save: `filter: {}` is a declaration that declares\n * nothing, and the server reads a present-but-empty block differently from an\n * absent one — unchecking the last box has to mean \"infer this again\", not\n * \"override it with silence\".\n */\nexport function patchColumnFilter(\n filter: ProfileColumnFilter | undefined,\n patch: Patch<ProfileColumnFilter>,\n): ProfileColumnFilter | undefined {\n const merged = Object.fromEntries(\n Object.entries({ ...filter, ...patch }).filter(([, value]) => value !== undefined),\n ) as ProfileColumnFilter;\n return Object.keys(merged).length ? merged : undefined;\n}\n\n/** What the server picks for a column that declares no filter kind. Mirrors\n * columnFilterKindFor; text and date are absent there on purpose, so they are\n * here too. Bytes stays a plain range: a size literal has two bases, so \"5MB\"\n * would mean two different numbers. */\nexport function inferredFilterKind(column: ProfileColumn): string {\n switch (column.type) {\n case \"number\":\n case \"bytes\":\n return \"range\";\n case \"duration\":\n return \"duration\";\n case \"datetime\":\n return \"time\";\n case \"boolean\":\n return \"boolean\";\n case \"uuid\":\n return \"exact\";\n case \"key_value\":\n case \"key_values\":\n case \"json\":\n return \"none\";\n default:\n return \"terms\";\n }\n}\n\nexport function patchProfileField(\n field: ProfileColumn,\n patch: Patch<ProfileColumn>,\n): ProfileColumn {\n return Object.fromEntries(\n Object.entries({ ...field, ...patch }).filter(\n ([, value]) => value !== undefined,\n ),\n ) as ProfileColumn;\n}\n\nexport function renameProfileField(\n field: ProfileColumn,\n name: string,\n): ProfileColumn {\n const source = field.source ?? (field.cel ? undefined : field.name);\n return patchProfileField(field, {\n name,\n source: source === name ? undefined : source,\n });\n}\n\nexport function providerTypeFromConnectionLabel(label: string): string | null {\n const match = label.match(/\\(([^()]+)\\)\\s*$/);\n return match?.[1]?.trim() || null;\n}\n\nexport function profileConnectionID(value: string): string | null {\n const prefix = \"connection://\";\n if (!value.startsWith(prefix)) return null;\n return value.slice(prefix.length).trim() || null;\n}\n\nexport function profileWizardErrorMessage(\n error: unknown,\n fallback: string,\n): string {\n return error instanceof Error && error.message.trim()\n ? error.message.trim()\n : fallback;\n}\n\n/**\n * A profile says what to fetch either as a raw query or as a structured search\n * specification — never both, which is why this is an either/or rather than a\n * check on `query` alone.\n */\nexport function profileWizardHasQuery(draft: ProfileWizardDraft): boolean {\n return Boolean(\n draft.query?.trim() || draft.provider?.options?.search !== undefined,\n );\n}\n\nexport function profileWizardStepReady(\n step: (typeof profileWizardSteps)[number][\"id\"],\n draft: ProfileWizardDraft,\n discovered: ProfileColumn[],\n): boolean {\n if (step === \"source\") {\n return Boolean(draft.provider?.connection && draft.provider.type);\n }\n if (step === \"query\") {\n return Boolean(profileWizardHasQuery(draft) && discovered.length > 0);\n }\n if (step === \"fields\") {\n return Boolean(draft.profile?.trim() && draft.columns?.length);\n }\n return (\n Boolean(draft.profile?.trim() && draft.provider?.connection) &&\n discovered.length > 0\n );\n}\n"],"names":[],"mappings":";;AAwCO,SAAS,WAA6B,OAAU,OAAoB;AACzE,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,UAAU,OAAW,QAAO,KAAK,GAAc;AAAA,QAC9C,MAAK,GAAc,IAAI;AAAA,EAC9B;AACA,SAAO;AACT;AAkDO,MAAM,2BAA6C,CAAC,QAAQ,MAAM;AAElE,SAAS,gBAAgB,OAA4B;AAC1D,SAAO,MAAM,SAAS,UAAa,yBAAyB,SAAS,MAAM,IAAI;AACjF;AAsBO,SAAS,kBACd,OACA,QACG;AACH,QAAM,OAAO,EAAE,GAAG,MAAA;AAClB,MAAI,aAAa,SAAS;AAAA,cACd,KAAK;AACjB,SAAO;AACT;AAQO,MAAM,gCAAgC;AAAA,EAC3C,EAAE,OAAO,QAAQ,OAAO,YAAA;AAAA,EACxB,EAAE,OAAO,SAAS,OAAO,SAAA;AAAA,EACzB,EAAE,OAAO,YAAY,OAAO,WAAA;AAAA,EAC5B,EAAE,OAAO,SAAS,OAAO,QAAA;AAAA,EACzB,EAAE,OAAO,YAAY,OAAO,WAAA;AAC9B;AAEO,MAAM,8BAA8B;AAAA,EACzC,EAAE,OAAO,QAAQ,OAAO,gBAAA;AAAA,EACxB,EAAE,OAAO,SAAS,OAAO,eAAA;AAAA,EACzB,EAAE,OAAO,WAAW,OAAO,kBAAA;AAAA,EAC3B,EAAE,OAAO,eAAe,OAAO,gBAAA;AAAA,EAC/B,EAAE,OAAO,SAAS,OAAO,cAAA;AAAA,EACzB,EAAE,OAAO,YAAY,OAAO,aAAA;AAAA,EAC5B,EAAE,OAAO,OAAO,OAAO,YAAA;AAAA,EACvB,EAAE,OAAO,UAAU,OAAO,mBAAA;AAAA,EAC1B,EAAE,OAAO,MAAM,OAAO,eAAA;AAAA,EACtB,EAAE,OAAO,KAAK,OAAO,UAAA;AACvB;AAEO,MAAM,qBAAqB;AAAA,EAChC,EAAE,IAAI,UAAU,OAAO,iBAAiB,aAAa,aAAA;AAAA,EACrD,EAAE,IAAI,SAAS,OAAO,oBAAoB,aAAa,QAAA;AAAA,EACvD,EAAE,IAAI,UAAU,OAAO,gBAAgB,aAAa,SAAA;AAAA,EACpD,EAAE,IAAI,UAAU,OAAO,UAAU,aAAa,OAAA;AAChD;AAEO,SAAS,oBACd,QACA,eACA,QACiB;AACjB,QAAM,QAAQ,OAAO,MAAM,KAAA,EAAO,YAAA;AAClC,SAAO,OAAO,OAAO,CAAC,UAAU;AAC9B,UAAM,WAAW,cAAc,IAAI,MAAM,IAAI;AAC7C,QAAI,OAAO,cAAc,cAAc,CAAC,SAAU,QAAO;AACzD,QAAI,OAAO,cAAc,gBAAgB,SAAU,QAAO;AAC1D,QAAI,OAAO,QAAQ,MAAM,SAAS,OAAO,KAAM,QAAO;AACtD,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,GAAG,MAAM,IAAI,IAAI,MAAM,SAAS,EAAE,GAAG,cAAc,SAAS,KAAK;AAAA,EAC1E,CAAC;AACH;AAcO,SAAS,uBACd,YACA,YACiB;AACjB,QAAM,mBAAmB,IAAI;AAAA,IAC3B,WAAW,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,KAAK,CAAC;AAAA,EAAA;AAE/C,QAAM,qBAAqB,IAAI;AAAA,IAC7B,WACG,OAAO,CAAC,UAAU,MAAM,MAAM,EAC9B,IAAI,CAAC,UAAU,CAAC,MAAM,QAAkB,KAAK,CAAC;AAAA,EAAA;AAEnD,QAAM,UAAU,CAAC,GAAG,UAAU;AAC9B,MAAI,SAAS;AACb,aAAW,SAAS,YAAY;AAC9B,UAAM,QACJ,iBAAiB,IAAI,MAAM,IAAI,KAAK,mBAAmB,IAAI,MAAM,IAAI;AACvE,QAAI,OAAO;AACT,eAAS,QAAQ,QAAQ,KAAK,IAAI;AAClC;AAAA,IACF;AACA,YAAQ,OAAO,QAAQ,GAAG,KAAK;AAC/B,cAAU;AAAA,EACZ;AACA,SAAO;AACT;AASO,SAAS,sBACd,SACA,YACA,YACiB;AACjB,QAAM,OAAO,QAAQ,UAAU,CAAC,WAAW,OAAO,SAAS,UAAU;AACrE,QAAM,KAAK,QAAQ,UAAU,CAAC,WAAW,OAAO,SAAS,UAAU;AACnE,MAAI,OAAO,KAAK,KAAK,KAAK,SAAS,GAAI,QAAO;AAC9C,QAAM,OAAO,CAAC,GAAG,OAAO;AACxB,OAAK,OAAO,IAAI,GAAG,GAAG,KAAK,OAAO,MAAM,CAAC,CAAC;AAC1C,SAAO;AACT;AAOO,SAAS,2BACd,YACA,YACA,cACA,UACiB;AACjB,QAAM,gBAAgB,IAAI,IAAI,WAAW,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC;AACnE,aAAW,QAAQ,cAAc;AAC/B,QAAI,SAAU,eAAc,IAAI,IAAI;AAAA,QAC/B,eAAc,OAAO,IAAI;AAAA,EAChC;AACA,SAAO,uBAAuB,YAAY,UAAU,EAAE;AAAA,IAAO,CAAC,UAC5D,cAAc,IAAI,MAAM,IAAI;AAAA,EAAA;AAEhC;AAKO,MAAM,8BAA8B;AAAA,EACzC,EAAE,OAAO,SAAS,OAAO,kBAAA;AAAA,EACzB,EAAE,OAAO,SAAS,OAAO,cAAA;AAAA,EACzB,EAAE,OAAO,QAAQ,OAAO,YAAA;AAAA,EACxB,EAAE,OAAO,SAAS,OAAO,gBAAA;AAAA,EACzB,EAAE,OAAO,YAAY,OAAO,iBAAA;AAAA,EAC5B,EAAE,OAAO,QAAQ,OAAO,aAAA;AAAA,EACxB,EAAE,OAAO,QAAQ,OAAO,oBAAA;AAAA,EACxB,EAAE,OAAO,WAAW,OAAO,SAAA;AAAA,EAC3B,EAAE,OAAO,QAAQ,OAAO,iBAAA;AAC1B;AAIO,MAAM,+BAA+B;AAGrC,MAAM,2BAA2B;AAWjC,SAAS,kBACd,QACA,OACiC;AACjC,QAAM,SAAS,OAAO;AAAA,IACpB,OAAO,QAAQ,EAAE,GAAG,QAAQ,GAAG,MAAA,CAAO,EAAE,OAAO,CAAC,CAAA,EAAG,KAAK,MAAM,UAAU,MAAS;AAAA,EAAA;AAEnF,SAAO,OAAO,KAAK,MAAM,EAAE,SAAS,SAAS;AAC/C;AAMO,SAAS,mBAAmB,QAA+B;AAChE,UAAQ,OAAO,MAAA;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAEO,SAAS,kBACd,OACA,OACe;AACf,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,EAAE,GAAG,OAAO,GAAG,MAAA,CAAO,EAAE;AAAA,MACrC,CAAC,CAAA,EAAG,KAAK,MAAM,UAAU;AAAA,IAAA;AAAA,EAC3B;AAEJ;AAEO,SAAS,mBACd,OACA,MACe;AACf,QAAM,SAAS,MAAM,WAAW,MAAM,MAAM,SAAY,MAAM;AAC9D,SAAO,kBAAkB,OAAO;AAAA,IAC9B;AAAA,IACA,QAAQ,WAAW,OAAO,SAAY;AAAA,EAAA,CACvC;AACH;AAEO,SAAS,gCAAgC,OAA8B;;AAC5E,QAAM,QAAQ,MAAM,MAAM,kBAAkB;AAC5C,WAAO,oCAAQ,OAAR,mBAAY,WAAU;AAC/B;AAEO,SAAS,oBAAoB,OAA8B;AAChE,QAAM,SAAS;AACf,MAAI,CAAC,MAAM,WAAW,MAAM,EAAG,QAAO;AACtC,SAAO,MAAM,MAAM,OAAO,MAAM,EAAE,UAAU;AAC9C;AAEO,SAAS,0BACd,OACA,UACQ;AACR,SAAO,iBAAiB,SAAS,MAAM,QAAQ,SAC3C,MAAM,QAAQ,KAAA,IACd;AACN;AAOO,SAAS,sBAAsB,OAAoC;;AACxE,SAAO;AAAA,MACL,WAAM,UAAN,mBAAa,aAAU,iBAAM,aAAN,mBAAgB,YAAhB,mBAAyB,YAAW;AAAA,EAAA;AAE/D;AAEO,SAAS,uBACd,MACA,OACA,YACS;;AACT,MAAI,SAAS,UAAU;AACrB,WAAO,UAAQ,WAAM,aAAN,mBAAgB,eAAc,MAAM,SAAS,IAAI;AAAA,EAClE;AACA,MAAI,SAAS,SAAS;AACpB,WAAO,QAAQ,sBAAsB,KAAK,KAAK,WAAW,SAAS,CAAC;AAAA,EACtE;AACA,MAAI,SAAS,UAAU;AACrB,WAAO,UAAQ,WAAM,YAAN,mBAAe,aAAU,WAAM,YAAN,mBAAe,OAAM;AAAA,EAC/D;AACA,SACE,UAAQ,WAAM,YAAN,mBAAe,aAAU,WAAM,aAAN,mBAAgB,WAAU,KAC3D,WAAW,SAAS;AAExB;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"profileWizardModel.cjs","sources":["../../../src/profiles/wizard/profileWizardModel.ts"],"sourcesContent":["import type { JsonSchemaObject } from \"../../components/json-schema-form-types\";\nimport { profileSchema } from \"../profileApi\";\nimport type { ProfileRowLimits } from \"../connections/connectionBrowserModel\";\n\n/** How a column is filtered at the backend; every field overrides an inference\n * the server would otherwise make from the column itself. */\nexport type ProfileColumnFilter = {\n /** Backend field the selection applies to; blank infers it from the column. */\n field?: string;\n /** Nested mapping containing the backend field. */\n nested?: string;\n /** Constants that pin the matching nested entry. */\n where?: Record<string, string>;\n /** terms, range, time, boolean, text or none; blank infers it from the type. */\n kind?: string;\n /** Enumerated values, replacing the backend lookup. */\n options?: string[];\n /** Ask the backend for this field's distinct values. */\n lookup?: boolean;\n /** How many of those values the control offers before the rest are typed for. */\n limit?: number;\n /** Allow several values at once. */\n multi?: boolean;\n /** Offer no filter while keeping the column rendered. */\n disabled?: boolean;\n};\n\n/**\n * A patch of T: every key optional, and explicitly settable to `undefined` to\n * clear it.\n *\n * Not Partial<T>. Under `exactOptionalPropertyTypes` an optional key may be\n * absent but not present-and-undefined, and \"clear this field\" — which is what\n * every editor control sends when its input goes empty — is precisely a present\n * `undefined`. The patch appliers drop those keys; the type has to permit them.\n */\nexport type Patch<T> = { [K in keyof T]?: T[K] | undefined };\n\n/**\n * Applies a patch, removing the keys it clears instead of leaving them present\n * and undefined.\n *\n * Spreading a patch would keep them, and these objects are serialized to the\n * server, where a present `field: undefined` is a key to interpret rather than\n * an absent one.\n */\nexport function applyPatch<T extends object>(value: T, patch: Patch<T>): T {\n const next = { ...value };\n for (const [key, entry] of Object.entries(patch)) {\n if (entry === undefined) delete next[key as keyof T];\n else next[key as keyof T] = entry as T[keyof T];\n }\n return next;\n}\n\nexport type ProfileColumn = {\n name: string;\n source?: string;\n label?: string;\n type?: string;\n kind?: string;\n format?: string;\n unit?: string;\n width?: number;\n cel?: string;\n /** Path computing the value, rooted at the row or at `source` when set. */\n jsonpath?: string;\n hidden?: boolean;\n filter?: ProfileColumnFilter;\n [key: string]: unknown;\n};\n\nexport type ProfileProvider = {\n type?: string;\n connection?: string;\n options?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\n/** The parameter types the profile schema accepts. */\nexport type ParamDraftType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"duration\"\n | \"enum\"\n | \"list\";\n\n/** filter, limit, offset, time-from or time-to; empty behaves as filter. */\nexport type ParamDraftRole =\n | \"filter\"\n | \"limit\"\n | \"offset\"\n | \"time-from\"\n | \"time-to\";\n\nexport type ParamDraft = {\n name?: string | undefined;\n label?: string | undefined;\n type?: ParamDraftType | undefined;\n role?: ParamDraftRole | undefined;\n default?: unknown | undefined;\n options?: string[] | undefined;\n required?: boolean | undefined;\n description?: string | undefined;\n /** Value rewrite; {value} is the supplied value. */\n template?: string | undefined;\n /** Backend field a list parameter filters on. Setting it lets a value be\n * excluded as well as included; it requires an OpenSearch-backed provider. */\n field?: string | undefined;\n};\n\n/** PARAM_TYPES_WITH_OPTIONS are the types whose values come from a fixed set, so\n * the editor offers an options picker for them. */\nexport const PARAM_TYPES_WITH_OPTIONS: ParamDraftType[] = [\"enum\", \"list\"];\n\nexport function paramHasOptions(param: ParamDraft): boolean {\n return (\n param.type !== undefined && PARAM_TYPES_WITH_OPTIONS.includes(param.type)\n );\n}\n\nexport type ProfileWizardDraft = Record<string, unknown> & {\n namespace?: string | undefined;\n profile?: string | undefined;\n /** Overrides the sidebar/picker glyph the provider type would otherwise give. */\n icon?: string | undefined;\n provider?: ProfileProvider | undefined;\n query?: string | undefined;\n columns?: ProfileColumn[] | undefined;\n /** The inputs a run binds — by name in the query, the provider options or the\n * connection. The query workspace previews against their defaults. */\n params?: ParamDraft[] | undefined;\n /** The row caps this profile sets for itself; unset ones take their default. */\n limits?: ProfileRowLimits | undefined;\n};\n\n/**\n * A profile that caps nothing carries no block at all, so the defaults are what\n * it inherits rather than what it froze at the moment it was edited. Both draft\n * hosts write the caps through this, so neither can leave an empty map behind.\n */\nexport function withProfileLimits<T extends ProfileWizardDraft>(\n draft: T,\n limits: ProfileRowLimits | undefined,\n): T {\n const next = { ...draft };\n if (limits) next.limits = limits;\n else delete next.limits;\n return next;\n}\n\nexport type ProfileFieldFilter = {\n query: string;\n type: string;\n selection: \"all\" | \"selected\" | \"unselected\";\n};\n\nexport const PROFILE_COLUMN_FORMAT_OPTIONS = [\n { value: \"date\", label: \"Date/time\" },\n { value: \"float\", label: \"Number\" },\n { value: \"duration\", label: \"Duration\" },\n { value: \"bytes\", label: \"Bytes\" },\n { value: \"currency\", label: \"Currency\" },\n] as const;\n\nexport const PROFILE_COLUMN_UNIT_OPTIONS = [\n { value: \"none\", label: \"Compact count\" },\n { value: \"short\", label: \"Short number\" },\n { value: \"percent\", label: \"Percent (0-100)\" },\n { value: \"percentunit\", label: \"Percent (0-1)\" },\n { value: \"bytes\", label: \"Bytes (IEC)\" },\n { value: \"decbytes\", label: \"Bytes (SI)\" },\n { value: \"Bps\", label: \"Bytes/sec\" },\n { value: \"binBps\", label: \"Binary bytes/sec\" },\n { value: \"ms\", label: \"Milliseconds\" },\n { value: \"s\", label: \"Seconds\" },\n] as const;\n\nexport const profileWizardSteps = [\n { id: \"source\", label: \"Choose source\", description: \"Connection\" },\n { id: \"query\", label: \"Explore & sample\", description: \"Query\" },\n { id: \"fields\", label: \"Name & shape\", description: \"Fields\" },\n { id: \"review\", label: \"Review\", description: \"Save\" },\n] as const;\n\nexport function filterProfileFields(\n fields: ProfileColumn[],\n selectedNames: Set<string>,\n filter: ProfileFieldFilter,\n): ProfileColumn[] {\n const query = filter.query.trim().toLowerCase();\n return fields.filter((field) => {\n const selected = selectedNames.has(field.name);\n if (filter.selection === \"selected\" && !selected) return false;\n if (filter.selection === \"unselected\" && selected) return false;\n if (filter.type && field.type !== filter.type) return false;\n if (!query) return true;\n return `${field.name} ${field.label ?? \"\"}`.toLowerCase().includes(query);\n });\n}\n\n/**\n * Every field the editors can show, each in its configured form. A discovered\n * field is a snapshot of what the source reported — the configured one carries\n * the user's edits, so it is the only version safe to render into a control or\n * to patch on top of.\n *\n * The configuration owns the order, because it is the order the profile renders\n * its columns in and the one the user drags rows into. A discovered field that\n * was never configured (not selected, or dropped from the profile) has no place\n * of its own, so it keeps the one it had: it is anchored just after whichever\n * configured field preceded it in the sample.\n */\nexport function availableProfileFields(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n): ProfileColumn[] {\n const configuredByName = new Map(\n configured.map((field) => [field.name, field]),\n );\n const configuredBySource = new Map(\n configured\n .filter((field) => field.source)\n .map((field) => [field.source as string, field]),\n );\n const ordered = [...configured];\n let anchor = 0;\n for (const field of discovered) {\n const match =\n configuredByName.get(field.name) ?? configuredBySource.get(field.name);\n if (match) {\n anchor = ordered.indexOf(match) + 1;\n continue;\n }\n ordered.splice(anchor, 0, field);\n anchor += 1;\n }\n return ordered;\n}\n\n/**\n * Moves the named column onto the target's position, shifting the columns\n * between them — the drop semantics the field grid's row drag needs. Columns\n * are addressed by name because a drag only ever carries the row's identity.\n * A name that is not configured has no position, so the order is returned\n * unchanged rather than guessed at.\n */\nexport function reorderProfileColumns(\n columns: ProfileColumn[],\n sourceName: string,\n targetName: string,\n): ProfileColumn[] {\n const from = columns.findIndex((column) => column.name === sourceName);\n const to = columns.findIndex((column) => column.name === targetName);\n if (from < 0 || to < 0 || from === to) return columns;\n const next = [...columns];\n next.splice(to, 0, ...next.splice(from, 1));\n return next;\n}\n\n/**\n * Selects or deselects the named fields, keeping the configured order intact —\n * a re-selected field returns to where the grid already showed it rather than\n * to the back of the list or to its position in the sample.\n */\nexport function applyVisibleFieldSelection(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n visibleNames: Set<string>,\n selected: boolean,\n): ProfileColumn[] {\n const selectedNames = new Set(configured.map((field) => field.name));\n for (const name of visibleNames) {\n if (selected) selectedNames.add(name);\n else selectedNames.delete(name);\n }\n return availableProfileFields(discovered, configured).filter((field) =>\n selectedNames.has(field.name),\n );\n}\n\n/** The control kinds a column filter can render as, with the server's own\n * wording. Mirrors query.ColumnFilterKindValues() and the x-enum-labels the\n * profile schema carries for them. */\nexport const PROFILE_FILTER_KIND_OPTIONS = [\n { value: \"terms\", label: \"Value list\" },\n { value: \"exact\", label: \"Exact match\" },\n { value: \"text\", label: \"Text search\" },\n { value: \"range\", label: \"Numeric range\" },\n { value: \"duration\", label: \"Duration range\" },\n { value: \"date\", label: \"Date range\" },\n { value: \"time\", label: \"Date & time range\" },\n { value: \"boolean\", label: \"Boolean\" },\n { value: \"none\", label: \"Not filterable\" },\n] as const;\n\n/** The server's own default, so an unset limit can be shown for what it does.\n * Mirrors query.DefaultFilterLookupLimit. */\nexport const PROFILE_FILTER_DEFAULT_LIMIT = 50;\n\n/** Mirrors query.MaxFilterLookupLimit — the largest head a lookup will serve. */\nexport const PROFILE_FILTER_MAX_LIMIT = 200;\n\n/**\n * Merges one filter knob into a column's filter block, dropping the block once\n * nothing is left in it.\n *\n * The distinction matters on save: `filter: {}` is a declaration that declares\n * nothing, and the server reads a present-but-empty block differently from an\n * absent one — unchecking the last box has to mean \"infer this again\", not\n * \"override it with silence\".\n */\nexport function patchColumnFilter(\n filter: ProfileColumnFilter | undefined,\n patch: Patch<ProfileColumnFilter>,\n): ProfileColumnFilter | undefined {\n const merged = Object.fromEntries(\n Object.entries({ ...filter, ...patch }).filter(\n ([, value]) => value !== undefined,\n ),\n ) as ProfileColumnFilter;\n return Object.keys(merged).length ? merged : undefined;\n}\n\n/** What the server picks for a column that declares no filter kind. Mirrors\n * columnFilterKindFor; text and date are absent there on purpose, so they are\n * here too. Bytes stays a plain range: a size literal has two bases, so \"5MB\"\n * would mean two different numbers. */\nexport function inferredFilterKind(column: ProfileColumn): string {\n switch (column.type) {\n case \"number\":\n case \"bytes\":\n return \"range\";\n case \"duration\":\n return \"duration\";\n case \"datetime\":\n return \"time\";\n case \"boolean\":\n return \"boolean\";\n case \"uuid\":\n return \"exact\";\n case \"key_value\":\n case \"key_values\":\n case \"json\":\n return \"none\";\n default:\n return \"terms\";\n }\n}\n\nexport function patchProfileField(\n field: ProfileColumn,\n patch: Patch<ProfileColumn>,\n): ProfileColumn {\n return Object.fromEntries(\n Object.entries({ ...field, ...patch }).filter(\n ([, value]) => value !== undefined,\n ),\n ) as ProfileColumn;\n}\n\nexport function renameProfileField(\n field: ProfileColumn,\n name: string,\n): ProfileColumn {\n const source = field.source ?? (field.cel ? undefined : field.name);\n return patchProfileField(field, {\n name,\n source: source === name ? undefined : source,\n });\n}\n\n/**\n * The connection type carried in a lookup option's label.\n *\n * The server renders each option as `\"<name> (<type>)\"`, so the parenthesised\n * suffix is the **connection** type — not the query provider that reads it. The\n * two coincide often enough (`opensearch`, `loki`, `postgres`) that using one as\n * the other looks correct, and they diverge for exactly the cloud and cluster\n * log backends: an `aws` connection is read by `cloudwatch`, `kubernetes` by\n * `k8s`, `azure` by `azureloganalytics`. Resolving one to the other is\n * providerTypesForConnectionType's job, and it uses the schema rather than a\n * second copy of that mapping.\n */\nexport function connectionTypeFromLabel(label: string): string | null {\n const match = label.match(/\\(([^()]+)\\)\\s*$/);\n return match?.[1]?.trim() || null;\n}\n\n/**\n * The query providers the profile schema says can read this connection type,\n * most specific first, or empty when nothing can read it.\n *\n * The authority is the schema the server already ships: the connection field's\n * lookup scope carries provider → connection types, so inverting it here keeps\n * one mapping rather than a client-side duplicate that can drift.\n */\nexport function providerTypesForConnectionType(\n connectionType: string,\n): string[] {\n const scope = providerConnectionScope();\n const candidates = Object.keys(scope)\n .filter((provider) => scope[provider]?.includes(connectionType))\n .sort();\n if (candidates.length <= 1) return candidates;\n // A provider keyed exactly as the connection type is the one named for it.\n const exact = candidates.find((provider) => provider === connectionType);\n if (exact) return [exact];\n // Otherwise drop the dialect-agnostic umbrella, so `sql_server` resolves to\n // `sqlserver` instead of tying with the generic `sql`. A genuine tie —\n // `google_cloud`, read by both `gcpcloudlogging` and `bigquery` — survives as\n // a list for the caller to disambiguate.\n const specific = candidates.filter((provider) => provider !== \"sql\");\n return specific.length === 1 ? specific : candidates;\n}\n\nfunction providerConnectionScope(): Record<string, string[]> {\n const provider = profileSchema().properties?.provider as\n | JsonSchemaObject\n | undefined;\n const connection = provider?.properties?.connection as\n | JsonSchemaObject\n | undefined;\n const lookup = connection?.[\"x-clicky-lookup\"] as\n | { scope?: { map?: unknown } }\n | undefined;\n const map = lookup?.scope?.map;\n if (!map || typeof map !== \"object\") {\n throw new Error(\n \"profile schema is missing provider.connection x-clicky-lookup.scope.map — the wizard cannot resolve a provider for a connection without it\",\n );\n }\n return map as Record<string, string[]>;\n}\n\nexport function profileConnectionID(value: string): string | null {\n const prefix = \"connection://\";\n if (!value.startsWith(prefix)) return null;\n return value.slice(prefix.length).trim() || null;\n}\n\nexport function profileWizardErrorMessage(\n error: unknown,\n fallback: string,\n): string {\n return error instanceof Error && error.message.trim()\n ? error.message.trim()\n : fallback;\n}\n\n/**\n * A profile says what to fetch either as a raw query or as a structured search\n * specification — never both, which is why this is an either/or rather than a\n * check on `query` alone.\n */\nexport function profileWizardHasQuery(draft: ProfileWizardDraft): boolean {\n return Boolean(\n draft.query?.trim() || draft.provider?.options?.search !== undefined,\n );\n}\n\nexport function profileWizardStepReady(\n step: (typeof profileWizardSteps)[number][\"id\"],\n draft: ProfileWizardDraft,\n discovered: ProfileColumn[],\n): boolean {\n if (step === \"source\") {\n return Boolean(draft.provider?.connection && draft.provider.type);\n }\n if (step === \"query\") {\n return Boolean(profileWizardHasQuery(draft) && discovered.length > 0);\n }\n if (step === \"fields\") {\n return Boolean(draft.profile?.trim() && draft.columns?.length);\n }\n return (\n Boolean(draft.profile?.trim() && draft.provider?.connection) &&\n discovered.length > 0\n );\n}\n"],"names":["profileSchema"],"mappings":"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"}
|
|
@@ -4,6 +4,10 @@ import { ProfileRowLimits } from '../connections/connectionBrowserModel';
|
|
|
4
4
|
export type ProfileColumnFilter = {
|
|
5
5
|
/** Backend field the selection applies to; blank infers it from the column. */
|
|
6
6
|
field?: string;
|
|
7
|
+
/** Nested mapping containing the backend field. */
|
|
8
|
+
nested?: string;
|
|
9
|
+
/** Constants that pin the matching nested entry. */
|
|
10
|
+
where?: Record<string, string>;
|
|
7
11
|
/** terms, range, time, boolean, text or none; blank infers it from the type. */
|
|
8
12
|
kind?: string;
|
|
9
13
|
/** Enumerated values, replacing the backend lookup. */
|
|
@@ -205,13 +209,13 @@ export declare function applyVisibleFieldSelection(discovered: ProfileColumn[],
|
|
|
205
209
|
* profile schema carries for them. */
|
|
206
210
|
export declare const PROFILE_FILTER_KIND_OPTIONS: readonly [{
|
|
207
211
|
readonly value: "terms";
|
|
208
|
-
readonly label: "Value
|
|
212
|
+
readonly label: "Value list";
|
|
209
213
|
}, {
|
|
210
214
|
readonly value: "exact";
|
|
211
215
|
readonly label: "Exact match";
|
|
212
216
|
}, {
|
|
213
217
|
readonly value: "text";
|
|
214
|
-
readonly label: "
|
|
218
|
+
readonly label: "Text search";
|
|
215
219
|
}, {
|
|
216
220
|
readonly value: "range";
|
|
217
221
|
readonly label: "Numeric range";
|
|
@@ -226,7 +230,7 @@ export declare const PROFILE_FILTER_KIND_OPTIONS: readonly [{
|
|
|
226
230
|
readonly label: "Date & time range";
|
|
227
231
|
}, {
|
|
228
232
|
readonly value: "boolean";
|
|
229
|
-
readonly label: "
|
|
233
|
+
readonly label: "Boolean";
|
|
230
234
|
}, {
|
|
231
235
|
readonly value: "none";
|
|
232
236
|
readonly label: "Not filterable";
|
|
@@ -253,7 +257,28 @@ export declare function patchColumnFilter(filter: ProfileColumnFilter | undefine
|
|
|
253
257
|
export declare function inferredFilterKind(column: ProfileColumn): string;
|
|
254
258
|
export declare function patchProfileField(field: ProfileColumn, patch: Patch<ProfileColumn>): ProfileColumn;
|
|
255
259
|
export declare function renameProfileField(field: ProfileColumn, name: string): ProfileColumn;
|
|
256
|
-
|
|
260
|
+
/**
|
|
261
|
+
* The connection type carried in a lookup option's label.
|
|
262
|
+
*
|
|
263
|
+
* The server renders each option as `"<name> (<type>)"`, so the parenthesised
|
|
264
|
+
* suffix is the **connection** type — not the query provider that reads it. The
|
|
265
|
+
* two coincide often enough (`opensearch`, `loki`, `postgres`) that using one as
|
|
266
|
+
* the other looks correct, and they diverge for exactly the cloud and cluster
|
|
267
|
+
* log backends: an `aws` connection is read by `cloudwatch`, `kubernetes` by
|
|
268
|
+
* `k8s`, `azure` by `azureloganalytics`. Resolving one to the other is
|
|
269
|
+
* providerTypesForConnectionType's job, and it uses the schema rather than a
|
|
270
|
+
* second copy of that mapping.
|
|
271
|
+
*/
|
|
272
|
+
export declare function connectionTypeFromLabel(label: string): string | null;
|
|
273
|
+
/**
|
|
274
|
+
* The query providers the profile schema says can read this connection type,
|
|
275
|
+
* most specific first, or empty when nothing can read it.
|
|
276
|
+
*
|
|
277
|
+
* The authority is the schema the server already ships: the connection field's
|
|
278
|
+
* lookup scope carries provider → connection types, so inverting it here keeps
|
|
279
|
+
* one mapping rather than a client-side duplicate that can drift.
|
|
280
|
+
*/
|
|
281
|
+
export declare function providerTypesForConnectionType(connectionType: string): string[];
|
|
257
282
|
export declare function profileConnectionID(value: string): string | null;
|
|
258
283
|
export declare function profileWizardErrorMessage(error: unknown, fallback: string): string;
|
|
259
284
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profileWizardModel.d.ts","sourceRoot":"","sources":["../../../src/profiles/wizard/profileWizardModel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"profileWizardModel.d.ts","sourceRoot":"","sources":["../../../src/profiles/wizard/profileWizardModel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { profileSchema } from "../profileApi.js";
|
|
1
2
|
function applyPatch(value, patch) {
|
|
2
3
|
const next = { ...value };
|
|
3
4
|
for (const [key, entry] of Object.entries(patch)) {
|
|
@@ -91,21 +92,23 @@ function applyVisibleFieldSelection(discovered, configured, visibleNames, select
|
|
|
91
92
|
);
|
|
92
93
|
}
|
|
93
94
|
const PROFILE_FILTER_KIND_OPTIONS = [
|
|
94
|
-
{ value: "terms", label: "Value
|
|
95
|
+
{ value: "terms", label: "Value list" },
|
|
95
96
|
{ value: "exact", label: "Exact match" },
|
|
96
|
-
{ value: "text", label: "
|
|
97
|
+
{ value: "text", label: "Text search" },
|
|
97
98
|
{ value: "range", label: "Numeric range" },
|
|
98
99
|
{ value: "duration", label: "Duration range" },
|
|
99
100
|
{ value: "date", label: "Date range" },
|
|
100
101
|
{ value: "time", label: "Date & time range" },
|
|
101
|
-
{ value: "boolean", label: "
|
|
102
|
+
{ value: "boolean", label: "Boolean" },
|
|
102
103
|
{ value: "none", label: "Not filterable" }
|
|
103
104
|
];
|
|
104
105
|
const PROFILE_FILTER_DEFAULT_LIMIT = 50;
|
|
105
106
|
const PROFILE_FILTER_MAX_LIMIT = 200;
|
|
106
107
|
function patchColumnFilter(filter, patch) {
|
|
107
108
|
const merged = Object.fromEntries(
|
|
108
|
-
Object.entries({ ...filter, ...patch }).filter(
|
|
109
|
+
Object.entries({ ...filter, ...patch }).filter(
|
|
110
|
+
([, value]) => value !== void 0
|
|
111
|
+
)
|
|
109
112
|
);
|
|
110
113
|
return Object.keys(merged).length ? merged : void 0;
|
|
111
114
|
}
|
|
@@ -144,11 +147,36 @@ function renameProfileField(field, name) {
|
|
|
144
147
|
source: source === name ? void 0 : source
|
|
145
148
|
});
|
|
146
149
|
}
|
|
147
|
-
function
|
|
150
|
+
function connectionTypeFromLabel(label) {
|
|
148
151
|
var _a;
|
|
149
152
|
const match = label.match(/\(([^()]+)\)\s*$/);
|
|
150
153
|
return ((_a = match == null ? void 0 : match[1]) == null ? void 0 : _a.trim()) || null;
|
|
151
154
|
}
|
|
155
|
+
function providerTypesForConnectionType(connectionType) {
|
|
156
|
+
const scope = providerConnectionScope();
|
|
157
|
+
const candidates = Object.keys(scope).filter((provider) => {
|
|
158
|
+
var _a;
|
|
159
|
+
return (_a = scope[provider]) == null ? void 0 : _a.includes(connectionType);
|
|
160
|
+
}).sort();
|
|
161
|
+
if (candidates.length <= 1) return candidates;
|
|
162
|
+
const exact = candidates.find((provider) => provider === connectionType);
|
|
163
|
+
if (exact) return [exact];
|
|
164
|
+
const specific = candidates.filter((provider) => provider !== "sql");
|
|
165
|
+
return specific.length === 1 ? specific : candidates;
|
|
166
|
+
}
|
|
167
|
+
function providerConnectionScope() {
|
|
168
|
+
var _a, _b, _c;
|
|
169
|
+
const provider = (_a = profileSchema().properties) == null ? void 0 : _a.provider;
|
|
170
|
+
const connection = (_b = provider == null ? void 0 : provider.properties) == null ? void 0 : _b.connection;
|
|
171
|
+
const lookup = connection == null ? void 0 : connection["x-clicky-lookup"];
|
|
172
|
+
const map = (_c = lookup == null ? void 0 : lookup.scope) == null ? void 0 : _c.map;
|
|
173
|
+
if (!map || typeof map !== "object") {
|
|
174
|
+
throw new Error(
|
|
175
|
+
"profile schema is missing provider.connection x-clicky-lookup.scope.map — the wizard cannot resolve a provider for a connection without it"
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return map;
|
|
179
|
+
}
|
|
152
180
|
function profileConnectionID(value) {
|
|
153
181
|
const prefix = "connection://";
|
|
154
182
|
if (!value.startsWith(prefix)) return null;
|
|
@@ -186,6 +214,7 @@ export {
|
|
|
186
214
|
applyPatch,
|
|
187
215
|
applyVisibleFieldSelection,
|
|
188
216
|
availableProfileFields,
|
|
217
|
+
connectionTypeFromLabel,
|
|
189
218
|
filterProfileFields,
|
|
190
219
|
inferredFilterKind,
|
|
191
220
|
paramHasOptions,
|
|
@@ -196,7 +225,7 @@ export {
|
|
|
196
225
|
profileWizardHasQuery,
|
|
197
226
|
profileWizardStepReady,
|
|
198
227
|
profileWizardSteps,
|
|
199
|
-
|
|
228
|
+
providerTypesForConnectionType,
|
|
200
229
|
renameProfileField,
|
|
201
230
|
reorderProfileColumns,
|
|
202
231
|
withProfileLimits
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profileWizardModel.js","sources":["../../../src/profiles/wizard/profileWizardModel.ts"],"sourcesContent":["import type { ProfileRowLimits } from \"../connections/connectionBrowserModel\";\n\n/** How a column is filtered at the backend; every field overrides an inference\n * the server would otherwise make from the column itself. */\nexport type ProfileColumnFilter = {\n /** Backend field the selection applies to; blank infers it from the column. */\n field?: string;\n /** terms, range, time, boolean, text or none; blank infers it from the type. */\n kind?: string;\n /** Enumerated values, replacing the backend lookup. */\n options?: string[];\n /** Ask the backend for this field's distinct values. */\n lookup?: boolean;\n /** How many of those values the control offers before the rest are typed for. */\n limit?: number;\n /** Allow several values at once. */\n multi?: boolean;\n /** Offer no filter while keeping the column rendered. */\n disabled?: boolean;\n};\n\n/**\n * A patch of T: every key optional, and explicitly settable to `undefined` to\n * clear it.\n *\n * Not Partial<T>. Under `exactOptionalPropertyTypes` an optional key may be\n * absent but not present-and-undefined, and \"clear this field\" — which is what\n * every editor control sends when its input goes empty — is precisely a present\n * `undefined`. The patch appliers drop those keys; the type has to permit them.\n */\nexport type Patch<T> = { [K in keyof T]?: T[K] | undefined };\n\n/**\n * Applies a patch, removing the keys it clears instead of leaving them present\n * and undefined.\n *\n * Spreading a patch would keep them, and these objects are serialized to the\n * server, where a present `field: undefined` is a key to interpret rather than\n * an absent one.\n */\nexport function applyPatch<T extends object>(value: T, patch: Patch<T>): T {\n const next = { ...value };\n for (const [key, entry] of Object.entries(patch)) {\n if (entry === undefined) delete next[key as keyof T];\n else next[key as keyof T] = entry as T[keyof T];\n }\n return next;\n}\n\nexport type ProfileColumn = {\n name: string;\n source?: string;\n label?: string;\n type?: string;\n kind?: string;\n format?: string;\n unit?: string;\n width?: number;\n cel?: string;\n /** Path computing the value, rooted at the row or at `source` when set. */\n jsonpath?: string;\n hidden?: boolean;\n filter?: ProfileColumnFilter;\n [key: string]: unknown;\n};\n\nexport type ProfileProvider = {\n type?: string;\n connection?: string;\n options?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\n/** The parameter types the profile schema accepts. */\nexport type ParamDraftType = \"string\" | \"number\" | \"boolean\" | \"date\" | \"datetime\" | \"duration\" | \"enum\" | \"list\";\n\n/** filter, limit, offset, time-from or time-to; empty behaves as filter. */\nexport type ParamDraftRole = \"filter\" | \"limit\" | \"offset\" | \"time-from\" | \"time-to\";\n\nexport type ParamDraft = {\n name?: string | undefined;\n label?: string | undefined;\n type?: ParamDraftType | undefined;\n role?: ParamDraftRole | undefined;\n default?: unknown | undefined;\n options?: string[] | undefined;\n required?: boolean | undefined;\n description?: string | undefined;\n /** Value rewrite; {value} is the supplied value. */\n template?: string | undefined;\n /** Backend field a list parameter filters on. Setting it lets a value be\n * excluded as well as included; it requires an OpenSearch-backed provider. */\n field?: string | undefined;\n};\n\n/** PARAM_TYPES_WITH_OPTIONS are the types whose values come from a fixed set, so\n * the editor offers an options picker for them. */\nexport const PARAM_TYPES_WITH_OPTIONS: ParamDraftType[] = [\"enum\", \"list\"];\n\nexport function paramHasOptions(param: ParamDraft): boolean {\n return param.type !== undefined && PARAM_TYPES_WITH_OPTIONS.includes(param.type);\n}\n\nexport type ProfileWizardDraft = Record<string, unknown> & {\n namespace?: string | undefined;\n profile?: string | undefined;\n /** Overrides the sidebar/picker glyph the provider type would otherwise give. */\n icon?: string | undefined;\n provider?: ProfileProvider | undefined;\n query?: string | undefined;\n columns?: ProfileColumn[] | undefined;\n /** The inputs a run binds — by name in the query, the provider options or the\n * connection. The query workspace previews against their defaults. */\n params?: ParamDraft[] | undefined;\n /** The row caps this profile sets for itself; unset ones take their default. */\n limits?: ProfileRowLimits | undefined;\n};\n\n/**\n * A profile that caps nothing carries no block at all, so the defaults are what\n * it inherits rather than what it froze at the moment it was edited. Both draft\n * hosts write the caps through this, so neither can leave an empty map behind.\n */\nexport function withProfileLimits<T extends ProfileWizardDraft>(\n draft: T,\n limits: ProfileRowLimits | undefined,\n): T {\n const next = { ...draft };\n if (limits) next.limits = limits;\n else delete next.limits;\n return next;\n}\n\nexport type ProfileFieldFilter = {\n query: string;\n type: string;\n selection: \"all\" | \"selected\" | \"unselected\";\n};\n\nexport const PROFILE_COLUMN_FORMAT_OPTIONS = [\n { value: \"date\", label: \"Date/time\" },\n { value: \"float\", label: \"Number\" },\n { value: \"duration\", label: \"Duration\" },\n { value: \"bytes\", label: \"Bytes\" },\n { value: \"currency\", label: \"Currency\" },\n] as const;\n\nexport const PROFILE_COLUMN_UNIT_OPTIONS = [\n { value: \"none\", label: \"Compact count\" },\n { value: \"short\", label: \"Short number\" },\n { value: \"percent\", label: \"Percent (0-100)\" },\n { value: \"percentunit\", label: \"Percent (0-1)\" },\n { value: \"bytes\", label: \"Bytes (IEC)\" },\n { value: \"decbytes\", label: \"Bytes (SI)\" },\n { value: \"Bps\", label: \"Bytes/sec\" },\n { value: \"binBps\", label: \"Binary bytes/sec\" },\n { value: \"ms\", label: \"Milliseconds\" },\n { value: \"s\", label: \"Seconds\" },\n] as const;\n\nexport const profileWizardSteps = [\n { id: \"source\", label: \"Choose source\", description: \"Connection\" },\n { id: \"query\", label: \"Explore & sample\", description: \"Query\" },\n { id: \"fields\", label: \"Name & shape\", description: \"Fields\" },\n { id: \"review\", label: \"Review\", description: \"Save\" },\n] as const;\n\nexport function filterProfileFields(\n fields: ProfileColumn[],\n selectedNames: Set<string>,\n filter: ProfileFieldFilter,\n): ProfileColumn[] {\n const query = filter.query.trim().toLowerCase();\n return fields.filter((field) => {\n const selected = selectedNames.has(field.name);\n if (filter.selection === \"selected\" && !selected) return false;\n if (filter.selection === \"unselected\" && selected) return false;\n if (filter.type && field.type !== filter.type) return false;\n if (!query) return true;\n return `${field.name} ${field.label ?? \"\"}`.toLowerCase().includes(query);\n });\n}\n\n/**\n * Every field the editors can show, each in its configured form. A discovered\n * field is a snapshot of what the source reported — the configured one carries\n * the user's edits, so it is the only version safe to render into a control or\n * to patch on top of.\n *\n * The configuration owns the order, because it is the order the profile renders\n * its columns in and the one the user drags rows into. A discovered field that\n * was never configured (not selected, or dropped from the profile) has no place\n * of its own, so it keeps the one it had: it is anchored just after whichever\n * configured field preceded it in the sample.\n */\nexport function availableProfileFields(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n): ProfileColumn[] {\n const configuredByName = new Map(\n configured.map((field) => [field.name, field]),\n );\n const configuredBySource = new Map(\n configured\n .filter((field) => field.source)\n .map((field) => [field.source as string, field]),\n );\n const ordered = [...configured];\n let anchor = 0;\n for (const field of discovered) {\n const match =\n configuredByName.get(field.name) ?? configuredBySource.get(field.name);\n if (match) {\n anchor = ordered.indexOf(match) + 1;\n continue;\n }\n ordered.splice(anchor, 0, field);\n anchor += 1;\n }\n return ordered;\n}\n\n/**\n * Moves the named column onto the target's position, shifting the columns\n * between them — the drop semantics the field grid's row drag needs. Columns\n * are addressed by name because a drag only ever carries the row's identity.\n * A name that is not configured has no position, so the order is returned\n * unchanged rather than guessed at.\n */\nexport function reorderProfileColumns(\n columns: ProfileColumn[],\n sourceName: string,\n targetName: string,\n): ProfileColumn[] {\n const from = columns.findIndex((column) => column.name === sourceName);\n const to = columns.findIndex((column) => column.name === targetName);\n if (from < 0 || to < 0 || from === to) return columns;\n const next = [...columns];\n next.splice(to, 0, ...next.splice(from, 1));\n return next;\n}\n\n/**\n * Selects or deselects the named fields, keeping the configured order intact —\n * a re-selected field returns to where the grid already showed it rather than\n * to the back of the list or to its position in the sample.\n */\nexport function applyVisibleFieldSelection(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n visibleNames: Set<string>,\n selected: boolean,\n): ProfileColumn[] {\n const selectedNames = new Set(configured.map((field) => field.name));\n for (const name of visibleNames) {\n if (selected) selectedNames.add(name);\n else selectedNames.delete(name);\n }\n return availableProfileFields(discovered, configured).filter((field) =>\n selectedNames.has(field.name),\n );\n}\n\n/** The control kinds a column filter can render as, with the server's own\n * wording. Mirrors query.ColumnFilterKindValues() and the x-enum-labels the\n * profile schema carries for them. */\nexport const PROFILE_FILTER_KIND_OPTIONS = [\n { value: \"terms\", label: \"Value selection\" },\n { value: \"exact\", label: \"Exact match\" },\n { value: \"text\", label: \"Substring\" },\n { value: \"range\", label: \"Numeric range\" },\n { value: \"duration\", label: \"Duration range\" },\n { value: \"date\", label: \"Date range\" },\n { value: \"time\", label: \"Date & time range\" },\n { value: \"boolean\", label: \"Yes/no\" },\n { value: \"none\", label: \"Not filterable\" },\n] as const;\n\n/** The server's own default, so an unset limit can be shown for what it does.\n * Mirrors query.DefaultFilterLookupLimit. */\nexport const PROFILE_FILTER_DEFAULT_LIMIT = 50;\n\n/** Mirrors query.MaxFilterLookupLimit — the largest head a lookup will serve. */\nexport const PROFILE_FILTER_MAX_LIMIT = 200;\n\n/**\n * Merges one filter knob into a column's filter block, dropping the block once\n * nothing is left in it.\n *\n * The distinction matters on save: `filter: {}` is a declaration that declares\n * nothing, and the server reads a present-but-empty block differently from an\n * absent one — unchecking the last box has to mean \"infer this again\", not\n * \"override it with silence\".\n */\nexport function patchColumnFilter(\n filter: ProfileColumnFilter | undefined,\n patch: Patch<ProfileColumnFilter>,\n): ProfileColumnFilter | undefined {\n const merged = Object.fromEntries(\n Object.entries({ ...filter, ...patch }).filter(([, value]) => value !== undefined),\n ) as ProfileColumnFilter;\n return Object.keys(merged).length ? merged : undefined;\n}\n\n/** What the server picks for a column that declares no filter kind. Mirrors\n * columnFilterKindFor; text and date are absent there on purpose, so they are\n * here too. Bytes stays a plain range: a size literal has two bases, so \"5MB\"\n * would mean two different numbers. */\nexport function inferredFilterKind(column: ProfileColumn): string {\n switch (column.type) {\n case \"number\":\n case \"bytes\":\n return \"range\";\n case \"duration\":\n return \"duration\";\n case \"datetime\":\n return \"time\";\n case \"boolean\":\n return \"boolean\";\n case \"uuid\":\n return \"exact\";\n case \"key_value\":\n case \"key_values\":\n case \"json\":\n return \"none\";\n default:\n return \"terms\";\n }\n}\n\nexport function patchProfileField(\n field: ProfileColumn,\n patch: Patch<ProfileColumn>,\n): ProfileColumn {\n return Object.fromEntries(\n Object.entries({ ...field, ...patch }).filter(\n ([, value]) => value !== undefined,\n ),\n ) as ProfileColumn;\n}\n\nexport function renameProfileField(\n field: ProfileColumn,\n name: string,\n): ProfileColumn {\n const source = field.source ?? (field.cel ? undefined : field.name);\n return patchProfileField(field, {\n name,\n source: source === name ? undefined : source,\n });\n}\n\nexport function providerTypeFromConnectionLabel(label: string): string | null {\n const match = label.match(/\\(([^()]+)\\)\\s*$/);\n return match?.[1]?.trim() || null;\n}\n\nexport function profileConnectionID(value: string): string | null {\n const prefix = \"connection://\";\n if (!value.startsWith(prefix)) return null;\n return value.slice(prefix.length).trim() || null;\n}\n\nexport function profileWizardErrorMessage(\n error: unknown,\n fallback: string,\n): string {\n return error instanceof Error && error.message.trim()\n ? error.message.trim()\n : fallback;\n}\n\n/**\n * A profile says what to fetch either as a raw query or as a structured search\n * specification — never both, which is why this is an either/or rather than a\n * check on `query` alone.\n */\nexport function profileWizardHasQuery(draft: ProfileWizardDraft): boolean {\n return Boolean(\n draft.query?.trim() || draft.provider?.options?.search !== undefined,\n );\n}\n\nexport function profileWizardStepReady(\n step: (typeof profileWizardSteps)[number][\"id\"],\n draft: ProfileWizardDraft,\n discovered: ProfileColumn[],\n): boolean {\n if (step === \"source\") {\n return Boolean(draft.provider?.connection && draft.provider.type);\n }\n if (step === \"query\") {\n return Boolean(profileWizardHasQuery(draft) && discovered.length > 0);\n }\n if (step === \"fields\") {\n return Boolean(draft.profile?.trim() && draft.columns?.length);\n }\n return (\n Boolean(draft.profile?.trim() && draft.provider?.connection) &&\n discovered.length > 0\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"profileWizardModel.js","sources":["../../../src/profiles/wizard/profileWizardModel.ts"],"sourcesContent":["import type { JsonSchemaObject } from \"../../components/json-schema-form-types\";\nimport { profileSchema } from \"../profileApi\";\nimport type { ProfileRowLimits } from \"../connections/connectionBrowserModel\";\n\n/** How a column is filtered at the backend; every field overrides an inference\n * the server would otherwise make from the column itself. */\nexport type ProfileColumnFilter = {\n /** Backend field the selection applies to; blank infers it from the column. */\n field?: string;\n /** Nested mapping containing the backend field. */\n nested?: string;\n /** Constants that pin the matching nested entry. */\n where?: Record<string, string>;\n /** terms, range, time, boolean, text or none; blank infers it from the type. */\n kind?: string;\n /** Enumerated values, replacing the backend lookup. */\n options?: string[];\n /** Ask the backend for this field's distinct values. */\n lookup?: boolean;\n /** How many of those values the control offers before the rest are typed for. */\n limit?: number;\n /** Allow several values at once. */\n multi?: boolean;\n /** Offer no filter while keeping the column rendered. */\n disabled?: boolean;\n};\n\n/**\n * A patch of T: every key optional, and explicitly settable to `undefined` to\n * clear it.\n *\n * Not Partial<T>. Under `exactOptionalPropertyTypes` an optional key may be\n * absent but not present-and-undefined, and \"clear this field\" — which is what\n * every editor control sends when its input goes empty — is precisely a present\n * `undefined`. The patch appliers drop those keys; the type has to permit them.\n */\nexport type Patch<T> = { [K in keyof T]?: T[K] | undefined };\n\n/**\n * Applies a patch, removing the keys it clears instead of leaving them present\n * and undefined.\n *\n * Spreading a patch would keep them, and these objects are serialized to the\n * server, where a present `field: undefined` is a key to interpret rather than\n * an absent one.\n */\nexport function applyPatch<T extends object>(value: T, patch: Patch<T>): T {\n const next = { ...value };\n for (const [key, entry] of Object.entries(patch)) {\n if (entry === undefined) delete next[key as keyof T];\n else next[key as keyof T] = entry as T[keyof T];\n }\n return next;\n}\n\nexport type ProfileColumn = {\n name: string;\n source?: string;\n label?: string;\n type?: string;\n kind?: string;\n format?: string;\n unit?: string;\n width?: number;\n cel?: string;\n /** Path computing the value, rooted at the row or at `source` when set. */\n jsonpath?: string;\n hidden?: boolean;\n filter?: ProfileColumnFilter;\n [key: string]: unknown;\n};\n\nexport type ProfileProvider = {\n type?: string;\n connection?: string;\n options?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\n/** The parameter types the profile schema accepts. */\nexport type ParamDraftType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"duration\"\n | \"enum\"\n | \"list\";\n\n/** filter, limit, offset, time-from or time-to; empty behaves as filter. */\nexport type ParamDraftRole =\n | \"filter\"\n | \"limit\"\n | \"offset\"\n | \"time-from\"\n | \"time-to\";\n\nexport type ParamDraft = {\n name?: string | undefined;\n label?: string | undefined;\n type?: ParamDraftType | undefined;\n role?: ParamDraftRole | undefined;\n default?: unknown | undefined;\n options?: string[] | undefined;\n required?: boolean | undefined;\n description?: string | undefined;\n /** Value rewrite; {value} is the supplied value. */\n template?: string | undefined;\n /** Backend field a list parameter filters on. Setting it lets a value be\n * excluded as well as included; it requires an OpenSearch-backed provider. */\n field?: string | undefined;\n};\n\n/** PARAM_TYPES_WITH_OPTIONS are the types whose values come from a fixed set, so\n * the editor offers an options picker for them. */\nexport const PARAM_TYPES_WITH_OPTIONS: ParamDraftType[] = [\"enum\", \"list\"];\n\nexport function paramHasOptions(param: ParamDraft): boolean {\n return (\n param.type !== undefined && PARAM_TYPES_WITH_OPTIONS.includes(param.type)\n );\n}\n\nexport type ProfileWizardDraft = Record<string, unknown> & {\n namespace?: string | undefined;\n profile?: string | undefined;\n /** Overrides the sidebar/picker glyph the provider type would otherwise give. */\n icon?: string | undefined;\n provider?: ProfileProvider | undefined;\n query?: string | undefined;\n columns?: ProfileColumn[] | undefined;\n /** The inputs a run binds — by name in the query, the provider options or the\n * connection. The query workspace previews against their defaults. */\n params?: ParamDraft[] | undefined;\n /** The row caps this profile sets for itself; unset ones take their default. */\n limits?: ProfileRowLimits | undefined;\n};\n\n/**\n * A profile that caps nothing carries no block at all, so the defaults are what\n * it inherits rather than what it froze at the moment it was edited. Both draft\n * hosts write the caps through this, so neither can leave an empty map behind.\n */\nexport function withProfileLimits<T extends ProfileWizardDraft>(\n draft: T,\n limits: ProfileRowLimits | undefined,\n): T {\n const next = { ...draft };\n if (limits) next.limits = limits;\n else delete next.limits;\n return next;\n}\n\nexport type ProfileFieldFilter = {\n query: string;\n type: string;\n selection: \"all\" | \"selected\" | \"unselected\";\n};\n\nexport const PROFILE_COLUMN_FORMAT_OPTIONS = [\n { value: \"date\", label: \"Date/time\" },\n { value: \"float\", label: \"Number\" },\n { value: \"duration\", label: \"Duration\" },\n { value: \"bytes\", label: \"Bytes\" },\n { value: \"currency\", label: \"Currency\" },\n] as const;\n\nexport const PROFILE_COLUMN_UNIT_OPTIONS = [\n { value: \"none\", label: \"Compact count\" },\n { value: \"short\", label: \"Short number\" },\n { value: \"percent\", label: \"Percent (0-100)\" },\n { value: \"percentunit\", label: \"Percent (0-1)\" },\n { value: \"bytes\", label: \"Bytes (IEC)\" },\n { value: \"decbytes\", label: \"Bytes (SI)\" },\n { value: \"Bps\", label: \"Bytes/sec\" },\n { value: \"binBps\", label: \"Binary bytes/sec\" },\n { value: \"ms\", label: \"Milliseconds\" },\n { value: \"s\", label: \"Seconds\" },\n] as const;\n\nexport const profileWizardSteps = [\n { id: \"source\", label: \"Choose source\", description: \"Connection\" },\n { id: \"query\", label: \"Explore & sample\", description: \"Query\" },\n { id: \"fields\", label: \"Name & shape\", description: \"Fields\" },\n { id: \"review\", label: \"Review\", description: \"Save\" },\n] as const;\n\nexport function filterProfileFields(\n fields: ProfileColumn[],\n selectedNames: Set<string>,\n filter: ProfileFieldFilter,\n): ProfileColumn[] {\n const query = filter.query.trim().toLowerCase();\n return fields.filter((field) => {\n const selected = selectedNames.has(field.name);\n if (filter.selection === \"selected\" && !selected) return false;\n if (filter.selection === \"unselected\" && selected) return false;\n if (filter.type && field.type !== filter.type) return false;\n if (!query) return true;\n return `${field.name} ${field.label ?? \"\"}`.toLowerCase().includes(query);\n });\n}\n\n/**\n * Every field the editors can show, each in its configured form. A discovered\n * field is a snapshot of what the source reported — the configured one carries\n * the user's edits, so it is the only version safe to render into a control or\n * to patch on top of.\n *\n * The configuration owns the order, because it is the order the profile renders\n * its columns in and the one the user drags rows into. A discovered field that\n * was never configured (not selected, or dropped from the profile) has no place\n * of its own, so it keeps the one it had: it is anchored just after whichever\n * configured field preceded it in the sample.\n */\nexport function availableProfileFields(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n): ProfileColumn[] {\n const configuredByName = new Map(\n configured.map((field) => [field.name, field]),\n );\n const configuredBySource = new Map(\n configured\n .filter((field) => field.source)\n .map((field) => [field.source as string, field]),\n );\n const ordered = [...configured];\n let anchor = 0;\n for (const field of discovered) {\n const match =\n configuredByName.get(field.name) ?? configuredBySource.get(field.name);\n if (match) {\n anchor = ordered.indexOf(match) + 1;\n continue;\n }\n ordered.splice(anchor, 0, field);\n anchor += 1;\n }\n return ordered;\n}\n\n/**\n * Moves the named column onto the target's position, shifting the columns\n * between them — the drop semantics the field grid's row drag needs. Columns\n * are addressed by name because a drag only ever carries the row's identity.\n * A name that is not configured has no position, so the order is returned\n * unchanged rather than guessed at.\n */\nexport function reorderProfileColumns(\n columns: ProfileColumn[],\n sourceName: string,\n targetName: string,\n): ProfileColumn[] {\n const from = columns.findIndex((column) => column.name === sourceName);\n const to = columns.findIndex((column) => column.name === targetName);\n if (from < 0 || to < 0 || from === to) return columns;\n const next = [...columns];\n next.splice(to, 0, ...next.splice(from, 1));\n return next;\n}\n\n/**\n * Selects or deselects the named fields, keeping the configured order intact —\n * a re-selected field returns to where the grid already showed it rather than\n * to the back of the list or to its position in the sample.\n */\nexport function applyVisibleFieldSelection(\n discovered: ProfileColumn[],\n configured: ProfileColumn[],\n visibleNames: Set<string>,\n selected: boolean,\n): ProfileColumn[] {\n const selectedNames = new Set(configured.map((field) => field.name));\n for (const name of visibleNames) {\n if (selected) selectedNames.add(name);\n else selectedNames.delete(name);\n }\n return availableProfileFields(discovered, configured).filter((field) =>\n selectedNames.has(field.name),\n );\n}\n\n/** The control kinds a column filter can render as, with the server's own\n * wording. Mirrors query.ColumnFilterKindValues() and the x-enum-labels the\n * profile schema carries for them. */\nexport const PROFILE_FILTER_KIND_OPTIONS = [\n { value: \"terms\", label: \"Value list\" },\n { value: \"exact\", label: \"Exact match\" },\n { value: \"text\", label: \"Text search\" },\n { value: \"range\", label: \"Numeric range\" },\n { value: \"duration\", label: \"Duration range\" },\n { value: \"date\", label: \"Date range\" },\n { value: \"time\", label: \"Date & time range\" },\n { value: \"boolean\", label: \"Boolean\" },\n { value: \"none\", label: \"Not filterable\" },\n] as const;\n\n/** The server's own default, so an unset limit can be shown for what it does.\n * Mirrors query.DefaultFilterLookupLimit. */\nexport const PROFILE_FILTER_DEFAULT_LIMIT = 50;\n\n/** Mirrors query.MaxFilterLookupLimit — the largest head a lookup will serve. */\nexport const PROFILE_FILTER_MAX_LIMIT = 200;\n\n/**\n * Merges one filter knob into a column's filter block, dropping the block once\n * nothing is left in it.\n *\n * The distinction matters on save: `filter: {}` is a declaration that declares\n * nothing, and the server reads a present-but-empty block differently from an\n * absent one — unchecking the last box has to mean \"infer this again\", not\n * \"override it with silence\".\n */\nexport function patchColumnFilter(\n filter: ProfileColumnFilter | undefined,\n patch: Patch<ProfileColumnFilter>,\n): ProfileColumnFilter | undefined {\n const merged = Object.fromEntries(\n Object.entries({ ...filter, ...patch }).filter(\n ([, value]) => value !== undefined,\n ),\n ) as ProfileColumnFilter;\n return Object.keys(merged).length ? merged : undefined;\n}\n\n/** What the server picks for a column that declares no filter kind. Mirrors\n * columnFilterKindFor; text and date are absent there on purpose, so they are\n * here too. Bytes stays a plain range: a size literal has two bases, so \"5MB\"\n * would mean two different numbers. */\nexport function inferredFilterKind(column: ProfileColumn): string {\n switch (column.type) {\n case \"number\":\n case \"bytes\":\n return \"range\";\n case \"duration\":\n return \"duration\";\n case \"datetime\":\n return \"time\";\n case \"boolean\":\n return \"boolean\";\n case \"uuid\":\n return \"exact\";\n case \"key_value\":\n case \"key_values\":\n case \"json\":\n return \"none\";\n default:\n return \"terms\";\n }\n}\n\nexport function patchProfileField(\n field: ProfileColumn,\n patch: Patch<ProfileColumn>,\n): ProfileColumn {\n return Object.fromEntries(\n Object.entries({ ...field, ...patch }).filter(\n ([, value]) => value !== undefined,\n ),\n ) as ProfileColumn;\n}\n\nexport function renameProfileField(\n field: ProfileColumn,\n name: string,\n): ProfileColumn {\n const source = field.source ?? (field.cel ? undefined : field.name);\n return patchProfileField(field, {\n name,\n source: source === name ? undefined : source,\n });\n}\n\n/**\n * The connection type carried in a lookup option's label.\n *\n * The server renders each option as `\"<name> (<type>)\"`, so the parenthesised\n * suffix is the **connection** type — not the query provider that reads it. The\n * two coincide often enough (`opensearch`, `loki`, `postgres`) that using one as\n * the other looks correct, and they diverge for exactly the cloud and cluster\n * log backends: an `aws` connection is read by `cloudwatch`, `kubernetes` by\n * `k8s`, `azure` by `azureloganalytics`. Resolving one to the other is\n * providerTypesForConnectionType's job, and it uses the schema rather than a\n * second copy of that mapping.\n */\nexport function connectionTypeFromLabel(label: string): string | null {\n const match = label.match(/\\(([^()]+)\\)\\s*$/);\n return match?.[1]?.trim() || null;\n}\n\n/**\n * The query providers the profile schema says can read this connection type,\n * most specific first, or empty when nothing can read it.\n *\n * The authority is the schema the server already ships: the connection field's\n * lookup scope carries provider → connection types, so inverting it here keeps\n * one mapping rather than a client-side duplicate that can drift.\n */\nexport function providerTypesForConnectionType(\n connectionType: string,\n): string[] {\n const scope = providerConnectionScope();\n const candidates = Object.keys(scope)\n .filter((provider) => scope[provider]?.includes(connectionType))\n .sort();\n if (candidates.length <= 1) return candidates;\n // A provider keyed exactly as the connection type is the one named for it.\n const exact = candidates.find((provider) => provider === connectionType);\n if (exact) return [exact];\n // Otherwise drop the dialect-agnostic umbrella, so `sql_server` resolves to\n // `sqlserver` instead of tying with the generic `sql`. A genuine tie —\n // `google_cloud`, read by both `gcpcloudlogging` and `bigquery` — survives as\n // a list for the caller to disambiguate.\n const specific = candidates.filter((provider) => provider !== \"sql\");\n return specific.length === 1 ? specific : candidates;\n}\n\nfunction providerConnectionScope(): Record<string, string[]> {\n const provider = profileSchema().properties?.provider as\n | JsonSchemaObject\n | undefined;\n const connection = provider?.properties?.connection as\n | JsonSchemaObject\n | undefined;\n const lookup = connection?.[\"x-clicky-lookup\"] as\n | { scope?: { map?: unknown } }\n | undefined;\n const map = lookup?.scope?.map;\n if (!map || typeof map !== \"object\") {\n throw new Error(\n \"profile schema is missing provider.connection x-clicky-lookup.scope.map — the wizard cannot resolve a provider for a connection without it\",\n );\n }\n return map as Record<string, string[]>;\n}\n\nexport function profileConnectionID(value: string): string | null {\n const prefix = \"connection://\";\n if (!value.startsWith(prefix)) return null;\n return value.slice(prefix.length).trim() || null;\n}\n\nexport function profileWizardErrorMessage(\n error: unknown,\n fallback: string,\n): string {\n return error instanceof Error && error.message.trim()\n ? error.message.trim()\n : fallback;\n}\n\n/**\n * A profile says what to fetch either as a raw query or as a structured search\n * specification — never both, which is why this is an either/or rather than a\n * check on `query` alone.\n */\nexport function profileWizardHasQuery(draft: ProfileWizardDraft): boolean {\n return Boolean(\n draft.query?.trim() || draft.provider?.options?.search !== undefined,\n );\n}\n\nexport function profileWizardStepReady(\n step: (typeof profileWizardSteps)[number][\"id\"],\n draft: ProfileWizardDraft,\n discovered: ProfileColumn[],\n): boolean {\n if (step === \"source\") {\n return Boolean(draft.provider?.connection && draft.provider.type);\n }\n if (step === \"query\") {\n return Boolean(profileWizardHasQuery(draft) && discovered.length > 0);\n }\n if (step === \"fields\") {\n return Boolean(draft.profile?.trim() && draft.columns?.length);\n }\n return (\n Boolean(draft.profile?.trim() && draft.provider?.connection) &&\n discovered.length > 0\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const reactQuery = require("@tanstack/react-query");
|
|
5
|
+
const debugConsoleSignal = require("../../data/debugConsoleSignal.cjs");
|
|
5
6
|
const react = require("react");
|
|
6
7
|
const connectionBrowserModel = require("../connections/connectionBrowserModel.cjs");
|
|
7
8
|
const connectionQueryWorkspace = require("../connections/connectionQueryWorkspace.cjs");
|
|
9
|
+
const useInspection = require("../connections/useInspection.cjs");
|
|
8
10
|
const profileApi = require("../profileApi.cjs");
|
|
9
11
|
const profileSamplePayload = require("../query/profileSamplePayload.cjs");
|
|
12
|
+
const profileSampleFilterLookup = require("../query/profileSampleFilterLookup.cjs");
|
|
13
|
+
const profileSampleResult = require("../query/profileSampleResult.cjs");
|
|
10
14
|
const profileWizardModel = require("./profileWizardModel.cjs");
|
|
11
15
|
const connectionQueryWorkspaceModel = require("../connections/connectionQueryWorkspaceModel.cjs");
|
|
12
16
|
const esQueryBuilderForm = require("../elasticsearch/esQueryBuilderForm.cjs");
|
|
@@ -17,7 +21,7 @@ function ProfileWizardQueryStep({
|
|
|
17
21
|
onDraftChange,
|
|
18
22
|
onSample
|
|
19
23
|
}) {
|
|
20
|
-
var _a, _b, _c, _d;
|
|
24
|
+
var _a, _b, _c, _d, _e, _f;
|
|
21
25
|
const baseUrl = connectionBrowserModel.browserBaseUrl(connectionID);
|
|
22
26
|
const descriptor = reactQuery.useQuery({
|
|
23
27
|
queryKey: ["profile-wizard-descriptor", connectionID],
|
|
@@ -37,6 +41,7 @@ function ProfileWizardQueryStep({
|
|
|
37
41
|
{}
|
|
38
42
|
);
|
|
39
43
|
const [selectedDatabase, setSelectedDatabase] = react.useState("");
|
|
44
|
+
const filterColumns = react.useRef([]);
|
|
40
45
|
const rawArtifact = descriptor.data !== void 0 && !connectionQueryWorkspaceModel.supportsQueryBuilder(descriptor.data);
|
|
41
46
|
react.useEffect(() => {
|
|
42
47
|
var _a2;
|
|
@@ -46,14 +51,15 @@ function ProfileWizardQueryStep({
|
|
|
46
51
|
}
|
|
47
52
|
}, [(_b = descriptor.data) == null ? void 0 : _b.defaultQuery, draft, onDraftChange, query, rawArtifact]);
|
|
48
53
|
const explicitTargetKind = liveOptions.targetKind ?? providerOptions.targetKind;
|
|
49
|
-
const
|
|
54
|
+
const targetOption = ((_d = (_c = descriptor.data) == null ? void 0 : _c.target) == null ? void 0 : _d.kind) === "index" ? descriptor.data.target.option : "";
|
|
55
|
+
const inspection = useInspection.useInspection({
|
|
50
56
|
cacheKey: "profile-wizard-inspection",
|
|
51
57
|
id: connectionID,
|
|
52
58
|
baseUrl,
|
|
53
|
-
enabled: ((
|
|
59
|
+
enabled: ((_e = descriptor.data) == null ? void 0 : _e.catalog) === true,
|
|
54
60
|
database: selectedDatabase,
|
|
55
61
|
fallbackDatabase: String(providerOptions.database ?? ""),
|
|
56
|
-
target: String(liveOptions
|
|
62
|
+
target: targetOption ? String(liveOptions[targetOption] ?? providerOptions[targetOption] ?? "") : "",
|
|
57
63
|
...typeof explicitTargetKind === "string" ? { targetKind: explicitTargetKind } : {}
|
|
58
64
|
});
|
|
59
65
|
const browserOptions = react.useMemo(
|
|
@@ -71,7 +77,7 @@ function ProfileWizardQueryStep({
|
|
|
71
77
|
},
|
|
72
78
|
[
|
|
73
79
|
catalogOptions,
|
|
74
|
-
(
|
|
80
|
+
(_f = descriptor.data) == null ? void 0 : _f.initialOptions,
|
|
75
81
|
inspection.sqlDatabase,
|
|
76
82
|
providerOptions
|
|
77
83
|
]
|
|
@@ -173,6 +179,19 @@ function ProfileWizardQueryStep({
|
|
|
173
179
|
}
|
|
174
180
|
});
|
|
175
181
|
},
|
|
182
|
+
lookupFilterValues: (request) => profileSampleFilterLookup.lookupProfileSampleFilterValues({
|
|
183
|
+
draft: {
|
|
184
|
+
...draft,
|
|
185
|
+
query: request.query,
|
|
186
|
+
provider: {
|
|
187
|
+
...draft.provider,
|
|
188
|
+
options: effectiveOptions(request.options)
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
params: esQueryBuilderForm.defaultParamValues(draft.params),
|
|
192
|
+
filterColumns: filterColumns.current,
|
|
193
|
+
request
|
|
194
|
+
}),
|
|
176
195
|
execute: async (request) => {
|
|
177
196
|
const nextDraft = {
|
|
178
197
|
...draft,
|
|
@@ -183,17 +202,31 @@ function ProfileWizardQueryStep({
|
|
|
183
202
|
}
|
|
184
203
|
};
|
|
185
204
|
onDraftChange(nextDraft);
|
|
186
|
-
const result = await connectionBrowserModel.fetchJSON(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
205
|
+
const result = await connectionBrowserModel.fetchJSON(
|
|
206
|
+
profileApi.profileApiPath("profile/sample"),
|
|
207
|
+
{
|
|
208
|
+
method: "POST",
|
|
209
|
+
headers: {
|
|
210
|
+
"Content-Type": "application/json",
|
|
211
|
+
...debugConsoleSignal.debugCaptureHeaders()
|
|
212
|
+
},
|
|
213
|
+
body: JSON.stringify(
|
|
214
|
+
profileSamplePayload.profileSamplePayload({
|
|
215
|
+
draft: nextDraft,
|
|
216
|
+
request,
|
|
217
|
+
params: esQueryBuilderForm.defaultParamValues(nextDraft.params),
|
|
218
|
+
filterColumns: filterColumns.current
|
|
219
|
+
})
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
filterColumns.current = profileSampleResult.profileSampleFilterColumns(result);
|
|
191
224
|
onSample({
|
|
192
225
|
columns: result.columns ?? [],
|
|
193
226
|
rows: result.rows ?? [],
|
|
194
227
|
sourceDraft: nextDraft
|
|
195
228
|
});
|
|
196
|
-
return result;
|
|
229
|
+
return profileSampleResult.profileSampleQueryResult(result);
|
|
197
230
|
}
|
|
198
231
|
}
|
|
199
232
|
)
|