From 09e923f4202f43203f1ea1bc9b883326cd260c9f Mon Sep 17 00:00:00 2001 From: Denise Li Date: Thu, 24 Oct 2024 17:29:27 +1100 Subject: [PATCH] feat: show callers in console verb page (#3183) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds `Callers` to verb right panel. Also cleans up CSS for the identical `Calls` panel. Screenshot 2024-10-24 at 4 52 09 PM --- .../console/src/features/verbs/VerbPage.tsx | 7 ++++- .../src/features/verbs/VerbRightPanel.tsx | 29 ++++++++++++++----- .../console/src/features/verbs/verb.utils.ts | 18 ++++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/frontend/console/src/features/verbs/VerbPage.tsx b/frontend/console/src/features/verbs/VerbPage.tsx index 450b301d99..5a44e0435a 100644 --- a/frontend/console/src/features/verbs/VerbPage.tsx +++ b/frontend/console/src/features/verbs/VerbPage.tsx @@ -10,6 +10,7 @@ import { SidePanelProvider } from '../../providers/side-panel-provider' import { TraceRequestList } from '../traces/TraceRequestList' import { VerbRequestForm } from './VerbRequestForm' import { verbPanels } from './VerbRightPanel' +import { type VerbRef, findCallers } from './verb.utils' export const VerbPage = ({ moduleName, declName }: { moduleName: string; declName: string }) => { const notification = useContext(NotificationsContext) @@ -17,6 +18,7 @@ export const VerbPage = ({ moduleName, declName }: { moduleName: string; declNam const modules = useModules() const [module, setModule] = useState() const [verb, setVerb] = useState() + const [callers, setCallers] = useState() useEffect(() => { if (!modules.isSuccess) return @@ -35,6 +37,9 @@ export const VerbPage = ({ moduleName, declName }: { moduleName: string; declNam setModule(module) const verb = module?.verbs.find((verb) => verb.verb?.name.toLocaleLowerCase() === declName?.toLocaleLowerCase()) setVerb(verb) + if (verb) { + setCallers(findCallers(verb, moduleName, modules.data.modules)) + } }, [modules.data, moduleName, declName]) if (!module || !verb) { @@ -59,7 +64,7 @@ export const VerbPage = ({ moduleName, declName }: { moduleName: string; declNam } rightPanelHeader={header} - rightPanelPanels={verbPanels(verb)} + rightPanelPanels={verbPanels(verb, callers)} bottomPanelContent={} /> diff --git a/frontend/console/src/features/verbs/VerbRightPanel.tsx b/frontend/console/src/features/verbs/VerbRightPanel.tsx index cf680b60ec..5b360de5ba 100644 --- a/frontend/console/src/features/verbs/VerbRightPanel.tsx +++ b/frontend/console/src/features/verbs/VerbRightPanel.tsx @@ -1,10 +1,20 @@ import { InboxUploadIcon } from 'hugeicons-react' +import { Link } from 'react-router-dom' import { RightPanelAttribute } from '../../components/RightPanelAttribute' import type { Verb } from '../../protos/xyz/block/ftl/v1/console/console_pb' import type { ExpandablePanelProps } from '../console/ExpandablePanel' -import { httpRequestPath, ingress, isHttpIngress, verbCalls } from './verb.utils' +import { type VerbRef, httpRequestPath, ingress, isHttpIngress, verbCalls } from './verb.utils' -export const verbPanels = (verb?: Verb) => { +const PanelRow = ({ verb }: { verb: VerbRef }) => { + return ( + + +
{`${verb?.module}.${verb?.name}`}
+ + ) +} + +export const verbPanels = (verb?: Verb, callers?: VerbRef[]) => { const panels = [] as ExpandablePanelProps[] if (isHttpIngress(verb)) { @@ -27,12 +37,15 @@ export const verbPanels = (verb?: Verb) => { panels.push({ title: 'Calls', expanded: true, - children: calls?.map((c, index) => ( -
- -
{`${c?.module}.${c?.name}`}
-
- )), + children: calls?.map((c, index) => ), + }) + } + + if (callers && callers.length > 0) { + panels.push({ + title: 'Callers', + expanded: true, + children: callers.map((c, index) => ), }) } diff --git a/frontend/console/src/features/verbs/verb.utils.ts b/frontend/console/src/features/verbs/verb.utils.ts index 9e56ed277f..5fea2b3ec9 100644 --- a/frontend/console/src/features/verbs/verb.utils.ts +++ b/frontend/console/src/features/verbs/verb.utils.ts @@ -199,6 +199,24 @@ export const verbCalls = (verb?: Verb) => { return verb?.verb?.metadata.filter((meta) => meta.value.case === 'calls').map((meta) => meta.value.value as MetadataCalls) ?? null } +export interface VerbRef { + module: string + name: string +} + +export const findCallers = (verb: Verb, moduleName: string, modules: Module[]) => + modules.flatMap((m: Module) => { + const callers = m.verbs.filter((v: Verb) => { + const calls = v.verb?.metadata.find((m) => m.value.case === 'calls') + if (!calls) return false + return !!(calls.value.value as MetadataCalls)?.calls.find((ref: Ref) => ref.module === moduleName && ref.name === verb.verb?.name) + }) + return callers.map((c) => ({ + module: m.name, + name: c.verb?.name || '', + })) + }) + export const generateCliCommand = (verb: Verb, path: string, header: string, body: string) => { const method = requestType(verb) return method === 'CALL' ? generateFtlCallCommand(path, body) : generateCurlCommand(method, path, header, body)