Skip to content

Commit

Permalink
feat(cdp): Input re-ordering and labelling (#23102)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjackwhite authored Jun 20, 2024
1 parent 77d9d85 commit 55cc5d2
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 40 deletions.
123 changes: 93 additions & 30 deletions frontend/src/scenes/pipeline/hogfunctions/HogFunctionInputs.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { closestCenter, DndContext } from '@dnd-kit/core'
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'
import { CSS } from '@dnd-kit/utilities'
import { Monaco } from '@monaco-editor/react'
import { IconGear, IconPlus, IconTrash, IconX } from '@posthog/icons'
import {
Expand All @@ -7,6 +10,7 @@ import {
LemonInputSelect,
LemonLabel,
LemonSelect,
LemonTag,
LemonTextArea,
} from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
Expand Down Expand Up @@ -362,6 +366,7 @@ function HogFunctionInputSchemaControls({ value, onChange, onDone }: HogFunction
}

export function HogFunctionInputWithSchema({ schema }: HogFunctionInputWithSchemaProps): JSX.Element {
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: schema.key })
const { showSource, configuration } = useValues(pipelineHogFunctionConfigurationLogic)
const { setConfigurationValue } = useActions(pipelineHogFunctionConfigurationLogic)
const [editing, setEditing] = useState(showSource)
Expand Down Expand Up @@ -394,38 +399,96 @@ export function HogFunctionInputWithSchema({ schema }: HogFunctionInputWithSchem
}
}, [showSource])

if (!editing) {
return (
<LemonField name={`inputs.${schema.key}`} help={schema.description}>
{({ value, onChange }) => {
return (
<>
<div className="flex items-center justify-between">
<LemonLabel showOptional={!schema.required}>{schema.label || schema.key}</LemonLabel>
{showSource ? (
<LemonButton
size="small"
noPadding
icon={<IconGear />}
onClick={() => setEditing(true)}
/>
) : null}
</div>
<HogFunctionInputRenderer
schema={schema}
value={value?.value}
onChange={(val) => onChange({ value: val })}
/>
</>
)
}}
</LemonField>
)
return (
<div
ref={setNodeRef}
// eslint-disable-next-line react/forbid-dom-props
style={{
transform: CSS.Transform.toString(transform),
transition,
}}
>
{!editing ? (
<LemonField name={`inputs.${schema.key}`} help={schema.description}>
{({ value, onChange }) => {
return (
<>
<div className="flex items-center gap-2">
<LemonLabel
className={showSource ? 'cursor-grab' : ''}
showOptional={!schema.required}
{...attributes}
{...listeners}
>
{schema.label || schema.key}
</LemonLabel>
{showSource ? (
<>
<LemonTag type="muted" className="font-mono">
inputs.{schema.key}
</LemonTag>
<div className="flex-1" />
<LemonButton
size="small"
noPadding
icon={<IconGear />}
onClick={() => setEditing(true)}
/>
</>
) : null}
</div>
<HogFunctionInputRenderer
schema={schema}
value={value?.value}
onChange={(val) => onChange({ value: val })}
/>
</>
)
}}
</LemonField>
) : (
<div className="border rounded p-2 border-dashed space-y-4">
<HogFunctionInputSchemaControls
value={schema}
onChange={onSchemaChange}
onDone={() => setEditing(false)}
/>
</div>
)}
</div>
)
}

export function HogFunctionInputs(): JSX.Element {
const { showSource, configuration } = useValues(pipelineHogFunctionConfigurationLogic)
const { setConfigurationValue } = useActions(pipelineHogFunctionConfigurationLogic)

if (!configuration?.inputs_schema?.length) {
return <span className="italic text-muted-alt">This function does not require any input variables.</span>
}

const inputSchemas = configuration.inputs_schema
const inputSchemaIds = inputSchemas.map((schema) => schema.key)

return (
<div className="border rounded p-2 border-dashed space-y-4">
<HogFunctionInputSchemaControls value={schema} onChange={onSchemaChange} onDone={() => setEditing(false)} />
</div>
<>
<DndContext
collisionDetection={closestCenter}
onDragEnd={({ active, over }) => {
if (over && active.id !== over.id) {
const oldIndex = inputSchemaIds.indexOf(active.id as string)
const newIndex = inputSchemaIds.indexOf(over.id as string)

setConfigurationValue('inputs_schema', arrayMove(inputSchemas, oldIndex, newIndex))
}
}}
>
<SortableContext disabled={!showSource} items={inputSchemaIds} strategy={verticalListSortingStrategy}>
{configuration.inputs_schema?.map((schema) => {
return <HogFunctionInputWithSchema key={schema.key} schema={schema} />
})}
</SortableContext>
</DndContext>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { groupsModel } from '~/models/groupsModel'
import { EntityTypes } from '~/types'

import { HogFunctionIconEditable } from './HogFunctionIcon'
import { HogFunctionInputWithSchema } from './HogFunctionInputs'
import { HogFunctionInputs } from './HogFunctionInputs'
import { HogFunctionTest, HogFunctionTestPlaceholder } from './HogFunctionTest'
import { pipelineHogFunctionConfigurationLogic } from './pipelineHogFunctionConfigurationLogic'

Expand Down Expand Up @@ -263,15 +263,7 @@ export function PipelineHogFunctionConfiguration({
<div className="flex-2 min-w-100 space-y-4">
<div className="border bg-bg-light rounded p-3 space-y-2">
<div className="space-y-2">
{configuration?.inputs_schema?.length ? (
configuration?.inputs_schema.map((schema, index) => {
return <HogFunctionInputWithSchema key={index} schema={schema} />
})
) : (
<span className="italic text-muted-alt">
This function does not require any input variables.
</span>
)}
<HogFunctionInputs />

{showSource ? (
<>
Expand Down

0 comments on commit 55cc5d2

Please sign in to comment.