Skip to content

Commit

Permalink
chore(editor-3000): reintegrate editor variables in editor 3000 (#26587)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
EDsCODE and github-actions[bot] authored Dec 5, 2024
1 parent 6459e6c commit 7cf87c8
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 247 deletions.
2 changes: 1 addition & 1 deletion frontend/src/layout/navigation-3000/navigationLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ export const navigation3000Logic = kea<navigation3000LogicType>([
featureFlags[FEATURE_FLAGS.SQL_EDITOR]
? {
identifier: Scene.SQLEditor,
label: 'Data warehouse 3000',
label: 'SQL Editor',
icon: <IconServer />,
to: urls.sqlEditor(),
logic: editorSidebarLogic,
Expand Down
12 changes: 11 additions & 1 deletion frontend/src/lib/monaco/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@ export interface CodeEditorProps extends Omit<EditorProps, 'loading' | 'theme'>
sourceQuery?: AnyDataNode
globals?: Record<string, any>
schema?: Record<string, any> | null

onError?: (error: string | null, isValidView: boolean) => void
}
let codeEditorIndex = 0

export function initModel(model: editor.ITextModel, builtCodeEditorLogic: BuiltLogic<codeEditorLogicType>): void {
;(model as any).codeEditorLogic = builtCodeEditorLogic
}

function initEditor(
monaco: Monaco,
editor: importedEditor.IStandaloneCodeEditor,
Expand All @@ -44,7 +50,9 @@ function initEditor(
): void {
// This gives autocomplete access to the specific editor
const model = editor.getModel()
;(model as any).codeEditorLogic = builtCodeEditorLogic
if (model) {
initModel(model, builtCodeEditorLogic)
}

if (editorProps?.language === 'hog') {
initHogLanguage(monaco)
Expand Down Expand Up @@ -112,6 +120,7 @@ export function CodeEditor({
globals,
sourceQuery,
schema,
onError,
...editorProps
}: CodeEditorProps): JSX.Element {
const { isDarkModeOn } = useValues(themeLogic)
Expand All @@ -130,6 +139,7 @@ export function CodeEditor({
sourceQuery,
monaco: monaco,
editor: editor,
onError,
})
useMountedLogic(builtCodeEditorLogic)

Expand Down
10 changes: 10 additions & 0 deletions frontend/src/lib/monaco/codeEditorLogic.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Monaco } from '@monaco-editor/react'
import { actions, connect, kea, key, listeners, path, props, propsChanged, reducers, selectors } from 'kea'
import { loaders } from 'kea-loaders'
import { subscriptions } from 'kea-subscriptions'
import { FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
// Note: we can oly import types and not values from monaco-editor, because otherwise some Monaco code breaks
Expand Down Expand Up @@ -48,6 +49,7 @@ export interface CodeEditorLogicProps {
editor?: editor.IStandaloneCodeEditor | null
globals?: Record<string, any>
multitab?: boolean
onError?: (error: string | null, isValidView: boolean) => void
}

export const codeEditorLogic = kea<codeEditorLogicType>([
Expand Down Expand Up @@ -270,6 +272,14 @@ export const codeEditorLogic = kea<codeEditorLogicType>([
},
],
}),
subscriptions(({ props, values }) => ({
isValidView: (isValidView) => {
props.onError?.(values.error, isValidView)
},
error: (error) => {
props.onError?.(error, values.isValidView)
},
})),
propsChanged(({ actions, props }, oldProps) => {
if (
props.query !== oldProps.query ||
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/scenes/data-warehouse/editor/EditorScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useRef } from 'react'
import { Sidebar } from '~/layout/navigation-3000/components/Sidebar'
import { navigation3000Logic } from '~/layout/navigation-3000/navigationLogic'

import { ViewLinkModal } from '../ViewLinkModal'
import { editorSceneLogic } from './editorSceneLogic'
import { editorSizingLogic } from './editorSizingLogic'
import { QueryWindow } from './QueryWindow'
Expand Down Expand Up @@ -47,6 +48,7 @@ export function EditorScene(): JSX.Element {
)}
<QueryWindow />
</div>
<ViewLinkModal />
</BindLogic>
)
}
Expand Down
180 changes: 56 additions & 124 deletions frontend/src/scenes/data-warehouse/editor/OutputPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,57 @@ import 'react-data-grid/lib/styles.css'
import { IconGear } from '@posthog/icons'
import { LemonButton, LemonTabs, Spinner } from '@posthog/lemon-ui'
import clsx from 'clsx'
import { BindLogic, useActions, useValues } from 'kea'
import { useActions, useValues } from 'kea'
import { router } from 'kea-router'
import { AnimationType } from 'lib/animations/animations'
import { Animation } from 'lib/components/Animation/Animation'
import { ExportButton } from 'lib/components/ExportButton/ExportButton'
import { useMemo } from 'react'
import DataGrid from 'react-data-grid'
import { InsightErrorState } from 'scenes/insights/EmptyStates'
import { insightDataLogic } from 'scenes/insights/insightDataLogic'
import { insightLogic } from 'scenes/insights/insightLogic'
import { HogQLBoldNumber } from 'scenes/insights/views/BoldNumber/BoldNumber'

import { KeyboardShortcut } from '~/layout/navigation-3000/components/KeyboardShortcut'
import { themeLogic } from '~/layout/navigation-3000/themeLogic'
import { dataNodeLogic, DataNodeLogicProps } from '~/queries/nodes/DataNode/dataNodeLogic'
import { dataNodeLogic } from '~/queries/nodes/DataNode/dataNodeLogic'
import { LineGraph } from '~/queries/nodes/DataVisualization/Components/Charts/LineGraph'
import { SideBar } from '~/queries/nodes/DataVisualization/Components/SideBar'
import { Table } from '~/queries/nodes/DataVisualization/Components/Table'
import { TableDisplay } from '~/queries/nodes/DataVisualization/Components/TableDisplay'
import { variableModalLogic } from '~/queries/nodes/DataVisualization/Components/Variables/variableModalLogic'
import { AddVariableButton } from '~/queries/nodes/DataVisualization/Components/Variables/AddVariableButton'
import { VariablesForInsight } from '~/queries/nodes/DataVisualization/Components/Variables/Variables'
import { variablesLogic } from '~/queries/nodes/DataVisualization/Components/Variables/variablesLogic'
import { DataTableVisualizationProps } from '~/queries/nodes/DataVisualization/DataVisualization'
import {
dataVisualizationLogic,
DataVisualizationLogicProps,
} from '~/queries/nodes/DataVisualization/dataVisualizationLogic'
import { displayLogic } from '~/queries/nodes/DataVisualization/displayLogic'
import { dataVisualizationLogic } from '~/queries/nodes/DataVisualization/dataVisualizationLogic'
import { DataVisualizationNode, HogQLQueryResponse, NodeKind } from '~/queries/schema'
import { ChartDisplayType, ExporterFormat, ItemMode } from '~/types'
import { ChartDisplayType, ExportContext, ExporterFormat } from '~/types'

import { DATAWAREHOUSE_EDITOR_ITEM_ID } from '../external/dataWarehouseExternalSceneLogic'
import { dataWarehouseViewsLogic } from '../saved_queries/dataWarehouseViewsLogic'
import { multitabEditorLogic } from './multitabEditorLogic'
import { outputPaneLogic, OutputTab } from './outputPaneLogic'

interface OutputPaneProps {
onSave: () => void
onSaveInsight: () => void
onSaveView: () => void
saveDisabledReason?: string
onQueryInputChange: () => void
logicKey: string
onQueryChange: (query: DataVisualizationNode) => void
query: string
exportContext?: ExportContext
}

export function OutputPane({
onQueryInputChange,
onSave,
onQueryChange,
onSaveView,
onSaveInsight,
saveDisabledReason,
logicKey,
query,
exportContext,
}: OutputPaneProps): JSX.Element {
const { activeTab } = useValues(outputPaneLogic)
const { setActiveTab } = useActions(outputPaneLogic)
const { variablesForInsight } = useValues(variablesLogic)

const codeEditorKey = `hogQLQueryEditor/${router.values.location.pathname}`

Expand All @@ -65,31 +63,12 @@ export function OutputPane({
})
)
const { isDarkModeOn } = useValues(themeLogic)
const { response, responseLoading } = useValues(
dataNodeLogic({
key: logicKey,
query: {
kind: NodeKind.HogQLQuery,
query,
},
doNotLoad: !query,
})
)
const { response, responseLoading } = useValues(dataNodeLogic)
const { dataWarehouseSavedQueriesLoading } = useValues(dataWarehouseViewsLogic)
const { updateDataWarehouseSavedQuery } = useActions(dataWarehouseViewsLogic)
const { visualizationType } = useValues(dataVisualizationLogic)

const { insightProps } = useValues(
insightLogic({
dashboardItemId: DATAWAREHOUSE_EDITOR_ITEM_ID,
cachedInsight: null,
doNotLoad: true,
})
)
const { setQuery } = useActions(
insightDataLogic({
...insightProps,
})
)
const vizKey = `SQLEditorScene`

const columns = useMemo(() => {
return (
Expand Down Expand Up @@ -138,16 +117,20 @@ export function OutputPane({
</div>
) : (
<div className="flex-1 absolute top-0 left-0 right-0 bottom-0 px-4 py-1 hide-scrollbar">
<DataTableVisualizationContent
activeTab={activeTab}
<InternalDataTableVisualization
uniqueKey={vizKey}
query={{
kind: NodeKind.DataVisualizationNode,
source: {
kind: NodeKind.HogQLQuery,
query,
},
}}
setQuery={setQuery}
setQuery={onQueryChange}
context={{}}
cachedResults={undefined}
exportContext={exportContext}
onSaveInsight={onSaveInsight}
/>
</div>
)
Expand All @@ -158,6 +141,11 @@ export function OutputPane({

return (
<div className="flex flex-col w-full flex-1 bg-bg-3000">
{variablesForInsight.length > 0 && (
<div className="py-2 px-4">
<VariablesForInsight />
</div>
)}
<div className="flex flex-row justify-between align-center py-2 px-4 w-full h-[55px]">
<LemonTabs
activeKey={activeTab}
Expand All @@ -174,6 +162,28 @@ export function OutputPane({
]}
/>
<div className="flex gap-4">
<AddVariableButton />

{exportContext && (
<ExportButton
disabledReason={
visualizationType != ChartDisplayType.ActionsTable &&
'Only table results are exportable'
}
type="secondary"
items={[
{
export_format: ExporterFormat.CSV,
export_context: exportContext,
},
{
export_format: ExporterFormat.XLSX,
export_context: exportContext,
},
]}
/>
)}

{editingView ? (
<>
<LemonButton
Expand All @@ -194,7 +204,7 @@ export function OutputPane({
</LemonButton>
</>
) : (
<LemonButton type="secondary" onClick={() => onSave()} disabledReason={saveDisabledReason}>
<LemonButton type="secondary" onClick={() => onSaveView()} disabledReason={saveDisabledReason}>
Save as view
</LemonButton>
)}
Expand All @@ -211,65 +221,9 @@ export function OutputPane({
)
}

function DataTableVisualizationContent({
query,
setQuery,
activeTab,
}: {
query: DataVisualizationNode
setQuery: (query: DataVisualizationNode) => void
activeTab: OutputTab
}): JSX.Element {
const vizKey = `SQLEditorScene.${activeTab}`
const dataVisualizationLogicProps: DataVisualizationLogicProps = {
key: vizKey,
query,
dashboardId: undefined,
dataNodeCollectionId: vizKey,
insightMode: ItemMode.Edit,
loadPriority: undefined,
setQuery,
cachedResults: undefined,
variablesOverride: undefined,
}

const dataNodeLogicProps: DataNodeLogicProps = {
query: query.source,
key: vizKey,
cachedResults: undefined,
loadPriority: undefined,
dataNodeCollectionId: vizKey,
variablesOverride: undefined,
}

return (
<BindLogic logic={dataNodeLogic} props={dataNodeLogicProps}>
<BindLogic logic={dataVisualizationLogic} props={dataVisualizationLogicProps}>
<BindLogic logic={displayLogic} props={{ key: dataVisualizationLogicProps.key }}>
<BindLogic logic={variablesLogic} props={{ key: dataVisualizationLogicProps.key, readOnly: false }}>
<BindLogic logic={variableModalLogic} props={{ key: dataVisualizationLogicProps.key }}>
<InternalDataTableVisualization
uniqueKey={vizKey}
query={query}
setQuery={setQuery}
context={{}}
cachedResults={undefined}
/>
</BindLogic>
</BindLogic>
</BindLogic>
</BindLogic>
</BindLogic>
)
}

function InternalDataTableVisualization(props: DataTableVisualizationProps): JSX.Element {
const logic = insightLogic({
dashboardItemId: DATAWAREHOUSE_EDITOR_ITEM_ID,
cachedInsight: null,
})
const { saveAs } = useActions(logic)

function InternalDataTableVisualization(
props: DataTableVisualizationProps & { onSaveInsight: () => void }
): JSX.Element {
const {
query,
visualizationType,
Expand Down Expand Up @@ -361,36 +315,14 @@ function InternalDataTableVisualization(props: DataTableVisualizationProps): JSX
tooltip="Visualization settings"
/>

{props.exportContext && (
<ExportButton
disabledReason={
visualizationType != ChartDisplayType.ActionsTable &&
'Only table results are exportable'
}
type="secondary"
items={[
{
export_format: ExporterFormat.CSV,
export_context: props.exportContext,
},
{
export_format: ExporterFormat.XLSX,
export_context: props.exportContext,
},
]}
/>
)}

<LemonButton type="primary" onClick={() => saveAs(true, false)}>
<LemonButton type="primary" onClick={() => props.onSaveInsight()}>
Create insight
</LemonButton>
</div>
</div>
</div>
</>
)}

<VariablesForInsight />
</div>
</div>
)
Expand Down
Loading

0 comments on commit 7cf87c8

Please sign in to comment.