Skip to content

Commit

Permalink
feat(dashboard): WfSpec var values are shown for current ThreadRun (
Browse files Browse the repository at this point in the history
  • Loading branch information
HazimAr committed Jun 3, 2024
1 parent f85aeeb commit 3fc31f5
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'
import { WfRun } from 'littlehorse-client/dist/proto/wf_run'
import { WfSpec } from 'littlehorse-client/dist/proto/wf_spec'
import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'
import { useRouter } from 'next/navigation'
import { FC, useMemo } from 'react'
import { useReplaceQueryValue } from '../hooks/useReplaceQueryValue'
import { useScrollbar } from '../hooks/useScrollbar'
import { useThread } from '../hooks/useThread'

export const ThreadPanel: FC<{ spec: WfSpec; wfRun?: WfRun }> = ({ spec, wfRun }) => {
const { thread, setThread } = useThread()
const threads = useMemo(() => extractThreads(spec, wfRun), [spec, wfRun])
const { scroll, itemsRef, containerRef, maxScroll, scrollLeft, scrollRight } = useScrollbar()
const router = useRouter()
const replaceQuery = useReplaceQueryValue()

return (
<div className="relative mb-2 flex items-center">
Expand All @@ -21,7 +25,7 @@ export const ThreadPanel: FC<{ spec: WfSpec; wfRun?: WfRun }> = ({ spec, wfRun }
</div>
<div className="flex touch-pan-y items-center overflow-hidden text-nowrap" ref={containerRef}>
<div
className="duration-[15ms] ease-[cubic-bezier(.05,0,0,1)] flex gap-2 will-change-transform"
className="flex gap-2 duration-[15ms] ease-[cubic-bezier(.05,0,0,1)] will-change-transform"
style={{ transform: `translateX(${scroll}px)` }}
ref={itemsRef}
>
Expand All @@ -42,6 +46,7 @@ export const ThreadPanel: FC<{ spec: WfSpec; wfRun?: WfRun }> = ({ spec, wfRun }
...current,
}
})
router.replace(replaceQuery('threadRunNumber', number?.toString() ?? '0'))
}}
>
{`${name}${number !== undefined ? `-${number}` : ''}`}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { usePathname, useSearchParams } from 'next/navigation'
import { useCallback } from 'react'

export const useReplaceQueryValue = () => {
const pathname = usePathname()
const searchParams = useSearchParams()

// Get a new searchParams string by merging the current
// searchParams with a provided key/value pair
return useCallback(
(name: string, value: string) => {
const params = new URLSearchParams(searchParams.toString())
params.set(name, value)

return pathname + '?' + params.toString()
},
[pathname, searchParams]
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { VARIABLE_TYPES } from '@/app/constants'
import { getVariableValue } from '@/app/utils'
import { Variable } from 'littlehorse-client/dist/proto/variable'
import { ThreadVarDef, WfRunVariableAccessLevel } from 'littlehorse-client/dist/proto/wf_spec'
import { FC } from 'react'

type VariablesProps = {
variableDefs: ThreadVarDef[]
variables: Variable[]
}

const accessLevels: { [key in WfRunVariableAccessLevel]: string } = {
PUBLIC_VAR: 'Public',
INHERITED_VAR: 'Inherited',
PRIVATE_VAR: 'Private',
UNRECOGNIZED: '',
}

export const Variables: FC<VariablesProps> = ({ variableDefs, variables }) => {
if (variableDefs.length === 0) return <></>
return (
<div className="">
<h2 className="text-md mb-2 font-bold">Variables</h2>
{variableDefs.map(variable => (
<div key={variable.varDef?.name} className="mb-1 flex items-center gap-1">
<span className="rounded bg-gray-100 px-2 py-1 font-mono text-fuchsia-500">{variable.varDef?.name}</span>
<span className="rounded bg-yellow-100 p-1 text-xs">{VARIABLE_TYPES[variable.varDef!.type]}</span>
{variable.required && <span className="rounded bg-orange-300 p-1 text-xs">Required</span>}
{variable.searchable && <span className="rounded bg-blue-300 p-1 text-xs">Searchable</span>}
<span className="rounded bg-green-300 p-1 text-xs">{accessLevels[variable.accessLevel]}</span>
<span>=</span>
<span className="truncate">
{getVariableValue(variables.find(v => v.id?.name === variable.varDef?.name)?.value)}
</span>
</div>
))}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
'use client'
import { Diagram } from '@/app/(authenticated)/(diagram)/components/Diagram'
import { Navigation } from '@/app/(authenticated)/components/Navigation'
import { useSearchParams } from 'next/navigation'
import { FC } from 'react'
import { Modals } from '../../../components/Modals'
import { useModal } from '../../../hooks/useModal'
import { WfRunResponse } from '../getWfRun'
import { Details } from './Details'
import { useModal } from '../../../hooks/useModal'
import { Modals } from '../../../components/Modals'
import { Variables } from './Variables';

export const WfRun: FC<WfRunResponse> = ({ wfRun, wfSpec, nodeRuns }) => {
export const WfRun: FC<WfRunResponse> = ({ wfRun, wfSpec, nodeRuns, variables }) => {
const { modal, showModal } = useModal()
const searchParams = useSearchParams()
const threadRunNumber = Number(searchParams.get('threadRunNumber'))
return (
<>
<div className='mb-16'>
<Navigation
href={`/wfSpec/${wfRun.wfSpecId?.name}/${wfRun.wfSpecId?.majorVersion}/${wfRun.wfSpecId?.revision}`}
title="Go back to WfSpec"
/>
<Details {...wfRun} />
<Diagram spec={wfSpec} wfRun={wfRun} nodeRuns={nodeRuns} />

<Variables
variableDefs={wfSpec.threadSpecs[wfRun.threadRuns[threadRunNumber].threadSpecName].variableDefs}
variables={variables.filter(v => v.id?.threadRunNumber == Number(searchParams.get('threadRunNumber')))}
/>
<Modals />
</>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { lhClient } from '@/app/lhClient'
import { NodeRun } from 'littlehorse-client/dist/proto/node_run'
import { WfRunId } from 'littlehorse-client/dist/proto/object_id'
import { Variable } from 'littlehorse-client/dist/proto/variable'
import { ThreadRun, WfRun } from 'littlehorse-client/dist/proto/wf_run'
import { WfSpec } from 'littlehorse-client/dist/proto/wf_spec'
import { cookies } from 'next/headers'
Expand All @@ -17,6 +18,7 @@ export type WfRunResponse = {
wfRun: WfRun & { threadRuns: ThreadRunWithNodeRuns[] }
wfSpec: WfSpec
nodeRuns: NodeRun[]
variables: Variable[]
}
export const getWfRun = async ({ ids }: Props): Promise<WfRunResponse> => {
const tenantId = cookies().get('tenantId')?.value
Expand All @@ -25,15 +27,18 @@ export const getWfRun = async ({ ids }: Props): Promise<WfRunResponse> => {
.reverse()
.reduceRight<WfRunId | undefined>((parentWfRunId, id) => ({ id, parentWfRunId }), undefined)
const wfRun = await client.getWfRun(wfRunId!)
const [wfSpec, { results: nodeRuns }] = await Promise.all([
const [wfSpec, { results: nodeRuns }, { results: variables }] = await Promise.all([
client.getWfSpec({ ...wfRun.wfSpecId }),
client.listNodeRuns({
wfRunId,
}),
client.listVariables({
wfRunId,
}),
])

const threadRuns = wfRun.threadRuns.map(threadRun => mergeThreadRunsWithNodeRuns(threadRun, nodeRuns))
return { wfRun: { ...wfRun, threadRuns }, wfSpec, nodeRuns }
return { wfRun: { ...wfRun, threadRuns }, wfSpec, nodeRuns, variables }
}

const mergeThreadRunsWithNodeRuns = (threadRun: ThreadRun, nodeRuns: NodeRun[]): ThreadRunWithNodeRuns => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ type Props = { params: { ids: string[] } }

export default async function Page({ params: { ids } }: Props) {
try {
const { wfRun, wfSpec, nodeRuns } = await getWfRun({ ids })
return <WfRun wfRun={wfRun} wfSpec={wfSpec} nodeRuns={nodeRuns} />
return <WfRun {...await getWfRun({ ids })} />
} catch (error) {
if (error instanceof ClientError && error.code === Status.NOT_FOUND) return notFound()
throw error
Expand Down

0 comments on commit 3fc31f5

Please sign in to comment.