Skip to content

Commit 95a933a

Browse files
committed
feat: improve action parameter list
1 parent e6c20c4 commit 95a933a

8 files changed

Lines changed: 13547 additions & 91 deletions

File tree

src/app/(landing)/[locale]/actions/[slug]/page.tsx

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,6 @@ export default async function ActionDetailPage({ params }: { params: LocaleSlugP
3131
const referencesLabel = actionsBlock?.referencesLabel ?? (locale === "de" ? "Referenzen" : "References")
3232
const flowTypesLabel = actionsBlock?.flowTypesLabel ?? "FlowTypes"
3333
const functionDefinitionsLabel = actionsBlock?.functionDefinitionsLabel ?? "FunctionDefinitions"
34-
const emptyDefinitionLabels = {
35-
flowTypes: actionsBlock?.noFlowTypesFoundLabel ?? (locale === "de" ? "Keine FlowTypes gefunden." : "No flow types found."),
36-
functionDefinitions: actionsBlock?.noFunctionDefinitionsFoundLabel ?? (locale === "de" ? "Keine FunctionDefinitions gefunden." : "No function definitions found."),
37-
both: actionsBlock?.noActionDefinitionsFoundLabel ?? (locale === "de" ? "Keine FlowTypes oder FunctionDefinitions gefunden." : "No flow types or function definitions found."),
38-
}
3934

4035
return (
4136
<>
@@ -50,49 +45,38 @@ export default async function ActionDetailPage({ params }: { params: LocaleSlugP
5045
<div className="flex flex-col gap-8">
5146
<div className="relative z-10 flex flex-col gap-8">
5247
<div className="flex flex-col gap-4 sm:flex-row sm:justify-between">
53-
<div className="flex flex-col gap-6 sm:flex-row sm:items-start">
48+
<div className="flex flex-col gap-4 sm:flex-row sm:items-start">
5449
{action.icon && (
55-
<div className="flex size-20 shrink-0 items-center justify-center overflow-hidden rounded-3xl border border-white/10 bg-light text-white">
50+
<div className="flex size-20 shrink-0 items-center justify-center overflow-hidden rounded-3xl border border-white/10 bg-primary text-white">
5651
<ActionIcon icon={action.icon} size={40} />
5752
</div>
5853
)}
5954

6055
<div className="flex flex-col min-w-0 flex-1 gap-2">
6156
<h1 className="mt-1 text-3xl font-semibold tracking-tight text-white sm:text-4xl">{action.title}</h1>
62-
{tags.length > 0 && (
63-
<div className="flex flex-wrap gap-2">
64-
{tags.map((tag) => (
65-
<span key={tag} className="rounded-full border border-white/10 bg-light px-3 py-1 text-xs text-secondary">
66-
{tag}
67-
</span>
68-
))}
69-
</div>
70-
)}
57+
{action.description && <div className="max-w-3xl whitespace-pre-line text-sm leading-6 text-secondary">{action.description}</div>}
7158
</div>
7259
</div>
7360
</div>
74-
{action.description && <div className="max-w-3xl whitespace-pre-line text-sm leading-6 text-secondary">{action.description}</div>}
7561

76-
{extractedFlowTypes.length > 0 || extractedFunctionDefinitions.length > 0 ? (
62+
{(extractedFlowTypes.length > 0 || extractedFunctionDefinitions.length > 0) && (
7763
<div className="space-y-8">
78-
<ActionDefinitionGroup label={flowTypesLabel}>
79-
{extractedFlowTypes.length > 0 ? (
80-
extractedFlowTypes.map((item) => <ActionTriggerCard key={item.id} type="flowType" item={item} />)
81-
) : (
82-
<p className="px-2 text-sm text-tertiary">{emptyDefinitionLabels.flowTypes}</p>
83-
)}
84-
</ActionDefinitionGroup>
64+
{extractedFlowTypes.length > 0 && (
65+
<ActionDefinitionGroup label={flowTypesLabel}>
66+
{extractedFlowTypes.map((item) => (
67+
<ActionTriggerCard key={item.id} type="flowType" item={item} />
68+
))}
69+
</ActionDefinitionGroup>
70+
)}
8571

86-
<ActionDefinitionGroup label={functionDefinitionsLabel}>
87-
{extractedFunctionDefinitions.length > 0 ? (
88-
extractedFunctionDefinitions.map((item) => <ActionTriggerCard key={item.id} type="functionDefinition" item={item} />)
89-
) : (
90-
<p className="px-2 text-sm text-tertiary">{emptyDefinitionLabels.functionDefinitions}</p>
91-
)}
92-
</ActionDefinitionGroup>
72+
{extractedFunctionDefinitions.length > 0 && (
73+
<ActionDefinitionGroup label={functionDefinitionsLabel}>
74+
{extractedFunctionDefinitions.map((item) => (
75+
<ActionTriggerCard key={item.id} type="functionDefinition" item={item} />
76+
))}
77+
</ActionDefinitionGroup>
78+
)}
9379
</div>
94-
) : (
95-
<p className="px-2 text-sm text-tertiary">{emptyDefinitionLabels.both}</p>
9680
)}
9781

9882
{references.length > 0 && (
@@ -116,11 +100,7 @@ export default async function ActionDetailPage({ params }: { params: LocaleSlugP
116100
function ActionDefinitionGroup({ label, children }: { label: string; children: ReactNode }) {
117101
return (
118102
<div className="space-y-4">
119-
<div className="flex items-center gap-3">
120-
<div className="h-px flex-1 bg-white/10" />
121-
<p className="shrink-0 text-xs font-medium tracking-wider text-tertiary">{label}</p>
122-
<div className="h-px flex-1 bg-white/10" />
123-
</div>
103+
<p className="shrink-0 text-sm text-tertiary">{label}</p>
124104
<div className="flex flex-col gap-3">{children}</div>
125105
</div>
126106
)

src/blocks/ActionBlock.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,5 @@ export const ActionBlock: Block = {
5656
localized: true,
5757
defaultValue: "FunctionDefinitions",
5858
},
59-
{
60-
name: "noFlowTypesFoundLabel",
61-
type: "text",
62-
required: true,
63-
localized: true,
64-
defaultValue: "No flow types found.",
65-
},
66-
{
67-
name: "noFunctionDefinitionsFoundLabel",
68-
type: "text",
69-
required: true,
70-
localized: true,
71-
defaultValue: "No function definitions found.",
72-
},
73-
{
74-
name: "noActionDefinitionsFoundLabel",
75-
type: "text",
76-
required: true,
77-
localized: true,
78-
defaultValue: "No flow types or function definitions found.",
79-
},
8059
],
8160
}

src/components/ActionTriggerCard.tsx

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use client"
22

33
import type { ExtractedFlowType, ExtractedFunctionDefinition } from "@/lib/actionExtraction"
4+
import { cn } from "@/lib/utils"
45
import { IconChevronDown } from "@tabler/icons-react"
56
import { useCallback, useMemo, useState } from "react"
6-
import { Card } from "./ui/Card"
77

88
interface ActionTriggerCardProps {
99
type: "flowType" | "functionDefinition"
@@ -21,19 +21,22 @@ export function ActionTriggerCard({ type, item }: ActionTriggerCardProps) {
2121
}, [])
2222
const parameterList = useMemo(
2323
() => (
24-
<div className="flex flex-col gap-3">
24+
<div className="flex flex-col gap-2">
2525
<div className="grid gap-1 text-xs">
2626
<div className="text-tertiary">{label}</div>
2727
<div className="font-medium text-white">{item.identifier}</div>
2828
</div>
2929

3030
{parameters.length > 0 && (
31-
<div className="flex flex-col gap-2">
31+
<div className="-mx-2 flex flex-col gap-1 border-t border-white/5 px-2 pt-2">
3232
<div className="text-xs text-tertiary">{parameterLabel}</div>
3333
{parameters.map((parameter) => (
34-
<div key={parameter.id} className="rounded-md bg-primary/50 p-2">
35-
<div className="text-xs font-medium text-white">{parameter.name || parameter.identifier}</div>
36-
{parameter.description && <div className="mt-1 text-xs leading-5 text-tertiary">{parameter.description}</div>}
34+
<div key={parameter.id} className="flex flex-col md:flex-row md:gap-1 md:items-center">
35+
<div className="text-xs font-medium text-white">
36+
{parameter.name || parameter.identifier}
37+
{parameter.description ? ":" : ""}
38+
</div>
39+
{parameter.description && <div className="text-xs leading-5 text-secondary">{parameter.description}</div>}
3740
</div>
3841
))}
3942
</div>
@@ -44,15 +47,24 @@ export function ActionTriggerCard({ type, item }: ActionTriggerCardProps) {
4447
)
4548

4649
return (
47-
<Card size="sm" className="bg-light p-0!">
50+
<div
51+
className={cn(
52+
"overflow-hidden rounded-xl border transition-[background-color,border-color,box-shadow] duration-300 ease-out",
53+
open ? "border-white/10 bg-light shadow-[0_10px_30px_rgba(0,0,0,0.18)]" : "border-transparent bg-transparent"
54+
)}
55+
>
4856
<div className="relative z-10">
49-
<button type="button" onClick={() => toggleItem(0)} className="flex w-full items-center justify-between gap-3 p-3 text-left">
57+
<button type="button" onClick={() => toggleItem(0)} className={cn("flex w-full items-center justify-between gap-3 text-left transition-[padding] duration-300 ease-out", open ? "px-2 py-2" : "p-0")}>
5058
<span className="min-w-0 truncate text-sm font-medium text-white">{item.name || item.identifier}</span>
51-
<IconChevronDown size={16} className={`shrink-0 text-tertiary transition-transform ${open ? "rotate-180" : ""}`} />
59+
<IconChevronDown size={16} className={cn("shrink-0 text-tertiary transition-transform duration-300 ease-out", open && "rotate-180")} />
5260
</button>
5361

54-
{open && <div className="border-t border-white/5 px-3 pb-3 pt-2">{parameterList}</div>}
62+
<div className={cn("grid transition-[grid-template-rows,opacity] duration-300 ease-out", open ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0")}>
63+
<div className="min-h-0 overflow-hidden">
64+
<div className="border-t border-white/5 px-2 pb-2 pt-2">{parameterList}</div>
65+
</div>
66+
</div>
5567
</div>
56-
</Card>
68+
</div>
5769
)
5870
}

src/lib/cms.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ const getLandingPageCached = cache(async (cachedSlug: string, cachedLocale: AppL
319319
fallbackLocale: DEFAULT_LOCALE,
320320
where: { slug: { equals: cachedSlug } },
321321
limit: 1,
322-
depth: 1,
322+
depth: 2,
323323
pagination: false,
324324
})
325325
})
@@ -329,7 +329,7 @@ const getNavigationCached = cache(async (locale: AppLocale): Promise<NavigationD
329329
slug: "navigation",
330330
locale,
331331
fallbackLocale: DEFAULT_LOCALE,
332-
depth: 1,
332+
depth: 2,
333333
})
334334
})
335335

@@ -402,18 +402,12 @@ const getJobsCached = cache(async (locale: AppLocale): Promise<JobItem[]> => {
402402
})
403403
})
404404

405-
async function enrichAction(action: Action, includeReferences = true): Promise<ActionItem> {
405+
async function enrichAction(action: Action): Promise<ActionItem> {
406406
const module = typeof action.module === "number" ? undefined : action.module
407407
const moduleJson = await fetchMediaJson(module).catch(() => null)
408408
const moduleInfo = extractActionModuleInfo(moduleJson)
409409
const slug = moduleInfo?.identifier || `action-${action.id}`
410410
const title = moduleInfo?.title || slug
411-
const references = includeReferences
412-
? await enrichActions(
413-
(action.references ?? []).filter((reference): reference is Action => typeof reference !== "number"),
414-
false
415-
)
416-
: null
417411

418412
return {
419413
id: action.id,
@@ -425,13 +419,23 @@ async function enrichAction(action: Action, includeReferences = true): Promise<A
425419
icon: moduleInfo?.icon,
426420
documentation: moduleInfo?.documentation || null,
427421
tags: action.tags,
428-
references,
422+
references: action.references?.map((reference) => (typeof reference === "number" ? reference : reference.id)) ?? null,
429423
}
430424
}
431425

432-
async function enrichActions(actions: Action[], includeReferences = true): Promise<ActionItem[]> {
433-
const enrichedActions = await Promise.all(actions.map((action) => enrichAction(action, includeReferences)))
434-
return enrichedActions.sort((a, b) => a.title.localeCompare(b.title))
426+
async function enrichActions(actions: Action[]): Promise<ActionItem[]> {
427+
const enrichedActions = await Promise.all(actions.map((action) => enrichAction(action)))
428+
const enrichedActionsById = new Map(enrichedActions.map((action) => [action.id, action]))
429+
430+
return enrichedActions
431+
.map((action) => ({
432+
...action,
433+
references:
434+
action.references
435+
?.map((reference) => enrichedActionsById.get(typeof reference === "number" ? reference : reference.id))
436+
.filter((reference): reference is ActionItem => Boolean(reference)) ?? null,
437+
}))
438+
.sort((a, b) => a.title.localeCompare(b.title))
435439
}
436440

437441
const getActionsCached = cache(async (locale: AppLocale): Promise<ActionItem[]> => {

0 commit comments

Comments
 (0)