Skip to content

Commit

Permalink
Add Blocked Reason, Link and Link Namespace to Callback UI (#2476)
Browse files Browse the repository at this point in the history
* Add blocked reason and links

* Add blocked reason to callback, add link namespace with a link to namespace

* Remove unused classes, consistent padding
  • Loading branch information
Alex-Tideman authored Dec 13, 2024
1 parent 125a99f commit 22b37ea
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 67 deletions.
8 changes: 4 additions & 4 deletions server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ require (
github.com/labstack/echo/v4 v4.9.1
github.com/stretchr/testify v1.9.0
github.com/urfave/cli/v2 v2.3.0
go.temporal.io/api v1.38.0
go.temporal.io/api v1.43.0
golang.org/x/net v0.28.0
golang.org/x/oauth2 v0.22.0
google.golang.org/grpc v1.65.0
google.golang.org/grpc v1.66.0
google.golang.org/protobuf v1.34.2
gopkg.in/validator.v2 v2.0.0-20210331031555-b37d688a7fb0
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -35,8 +35,8 @@ require (
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect
)

replace github.com/grpc-ecosystem/grpc-gateway => github.com/temporalio/grpc-gateway v1.17.0
16 changes: 8 additions & 8 deletions server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
go.temporal.io/api v1.38.0 h1:L5i+Ai7UoBa2Gq/goVHLY32064AgawxPDLkKm4I7fu4=
go.temporal.io/api v1.38.0/go.mod h1:fmh06EjstyrPp6SHbjJo7yYHBfHamPE4SytM+2NRejc=
go.temporal.io/api v1.43.0 h1:lBhq+u5qFJqGMXwWsmg/i8qn1UA/3LCwVc88l2xUMHg=
go.temporal.io/api v1.43.0/go.mod h1:1WwYUMo6lao8yl0371xWUm13paHExN5ATYT/B7QtFis=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
Expand All @@ -69,12 +69,12 @@ golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo=
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0=
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
20 changes: 13 additions & 7 deletions src/lib/components/event/event-link.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
<script lang="ts">
import Link from '$lib/holocene/link.svelte';
import { translate } from '$lib/i18n/translate';
import type { EventLink } from '$lib/types/events';
import { routeForEventHistory } from '$lib/utilities/route-for';
export let link: EventLink;
$: href = routeForEventHistory({
export let value = link.workflowEvent.workflowId;
export let label = translate('nexus.link');
export let href = routeForEventHistory({
namespace: link.workflowEvent.namespace,
workflow: link.workflowEvent.workflowId,
run: link.workflowEvent.runId,
});
</script>

<div
class="flex flex-row items-center gap-2 overflow-hidden first:pt-0 last:border-b-0 xl:max-w-xl {$$props.class}"
class="flex flex-row items-center gap-2 overflow-hidden first:pt-0 last:border-b-0 {$$props.class}"
>
<p class="max-w-fit whitespace-nowrap text-right text-xs">Link</p>
<Link {href}>
{link.workflowEvent.workflowId}
</Link>
<p class="max-w-fit whitespace-nowrap text-right text-sm">
{label}
</p>
<div class="overflow-hidden {$$props.linkClass}">
<Link {href}>
{value}
</Link>
</div>
</div>
36 changes: 16 additions & 20 deletions src/lib/components/event/event-links-expanded.svelte
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
<script lang="ts">
import Link from '$lib/holocene/link.svelte';
import type { EventLink } from '$lib/types/events';
import { routeForEventHistory } from '$lib/utilities/route-for';
import { translate } from '$lib/i18n/translate';
import type { EventLink as ELink } from '$lib/types/events';
import { routeForNamespace } from '$lib/utilities/route-for';
export let links: EventLink[] = [];
import EventLink from './event-link.svelte';
export let links: ELink[] = [];
</script>

{#each links as link}
{#if link?.workflowEvent}
{@const href = routeForEventHistory({
namespace: link.workflowEvent.namespace,
workflow: link.workflowEvent.workflowId,
run: link.workflowEvent.runId,
})}
<div class="content">
<p class="text-sm">Link</p>
<Link class="whitespace-pre-line" {href}>
{link.workflowEvent.workflowId}
</Link>
<div class="flex w-full items-center gap-4 p-2">
<EventLink {link} />
</div>
<div class="flex w-full items-center gap-4 p-2">
<EventLink
{link}
label={translate('nexus.link-namespace')}
value={link.workflowEvent.namespace}
href={routeForNamespace({ namespace: link.workflowEvent.namespace })}
/>
</div>
{/if}
{/each}

<style lang="postcss">
.content {
@apply block flex w-full w-full items-center gap-4 px-2 py-1 py-1 text-left text-left xl:flex;
}
</style>
6 changes: 5 additions & 1 deletion src/lib/components/event/event-summary-row.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,11 @@
</div>
{/if}
{#if currentEvent?.links?.length}
<EventLink link={currentEvent.links[0]} class="max-w-xl truncate" />
<EventLink
link={currentEvent.links[0]}
class="max-w-xl"
linkClass="truncate"
/>
{/if}
{#if primaryAttribute?.key}
<EventDetailsRow {...primaryAttribute} {attributes} />
Expand Down
55 changes: 33 additions & 22 deletions src/lib/components/lines-and-dots/workflow-callback.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
<script lang="ts">
import Alert from '$lib/holocene/alert.svelte';
import Badge from '$lib/holocene/badge.svelte';
import CodeBlock from '$lib/holocene/code-block.svelte';
import { translate } from '$lib/i18n/translate';
import { fullEventHistory } from '$lib/stores/events';
import { timeFormat } from '$lib/stores/time-format';
import type { CallbackInfo } from '$lib/types';
import type { Callback } from '$lib/types/nexus';
import { formatDate } from '$lib/utilities/format-date';
import { routeForNamespace } from '$lib/utilities/route-for';
export let callback: CallbackInfo;
import EventLink from '../event/event-link.svelte';
export let callback: Callback;
$: completedTime = formatDate(callback.lastAttemptCompleteTime, $timeFormat);
$: nextTime = formatDate(callback.nextAttemptScheduleTime, $timeFormat);
$: failure = callback?.lastAttemptFailure?.message;
$: blockedReason = callback?.blockedReason;
const titles = {
Standby: translate('nexus.callback.standby'),
Expand All @@ -19,41 +25,52 @@
Failed: translate('nexus.callback.failed'),
Succeeded: translate('nexus.callback.succeeded'),
};
$: initialEvent = $fullEventHistory[0];
$: link = initialEvent?.links[0];
$: title = titles[callback.state] || translate('nexus.nexus-callback');
</script>

<Alert icon="nexus" intent="info" {title}>
<div class="flex flex-col gap-2 pt-2">
<div class="flex items-center gap-2">
<p>
{translate('common.url')}
<span class="badge">{callback.callback.nexus.url}</span>
</p>
</div>
{#if link}
<EventLink {link} />
<EventLink
{link}
label={translate('nexus.link-namespace')}
value={link.workflowEvent.namespace}
href={routeForNamespace({ namespace: link.workflowEvent.namespace })}
/>
{/if}
<div class="flex flex-col items-start gap-2 md:flex-row md:items-center">
<p>
{translate('common.state')} <span class="badge">{callback.state}</span>
<p class="flex items-center gap-2">
{translate('common.state')}<Badge type="subtle">{callback.state}</Badge>
</p>
{#if callback.attempt}
<p>
<p class="flex items-center gap-2">
{translate('common.attempt')}
<span class="badge">{callback.attempt}</span>
<Badge type="subtle">{callback.attempt}</Badge>
</p>
{/if}
{#if callback.lastAttemptCompleteTime}
<p>
<p class="flex items-center gap-2">
{translate('nexus.last-attempt-completed-time')}
<span class="badge">{completedTime}</span>
<Badge type="subtle">{completedTime}</Badge>
</p>
{/if}
{#if callback.nextAttemptScheduleTime}
<p>
<p class="flex items-center gap-2">
{translate('nexus.next-attempt-scheduled-time')}
<span class="badge">{nextTime}</span>
<Badge type="subtle">{nextTime}</Badge>
</p>
{/if}
</div>
{#if blockedReason}
<p class="flex items-center gap-2">
{translate('nexus.blocked-reason')}
<Badge type="subtle">{blockedReason}</Badge>
</p>
{/if}
{#if failure}
<div class="flex flex-col gap-2">
<p>{translate('nexus.last-attempt-failure')}</p>
Expand All @@ -67,9 +84,3 @@
{/if}
</div>
</Alert>

<style lang="postcss">
.badge {
@apply inline-flex items-center gap-1 rounded-sm bg-subtle px-1 py-0.5 font-medium;
}
</style>
3 changes: 3 additions & 0 deletions src/lib/i18n/locales/en/nexus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,7 @@ export const Strings = {
'last-attempt-completed-time': 'Last Attempt Completed Time',
'next-attempt-scheduled-time': 'Next Attempt Scheduled Time',
'last-attempt-failure': 'Last Attempt Failure',
'blocked-reason': 'Blocked Reason',
link: 'Link',
'link-namespace': 'Link Namespace',
} as const;
4 changes: 2 additions & 2 deletions src/lib/models/workflow-execution.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { CallbackInfo } from '$lib/types';
import type {
Callbacks,
PendingActivity,
PendingActivityInfo,
PendingChildren,
PendingNexusOperation,
} from '$lib/types/events';
import type { Callback } from '$lib/types/nexus';
import type {
ListWorkflowExecutionsResponse,
WorkflowExecution,
Expand Down Expand Up @@ -47,7 +47,7 @@ const toPendingNexusOperations = (

const toCallbacks = (callbacks?: Callbacks): Callbacks => {
if (!callbacks) return [];
return callbacks.map((callback): CallbackInfo => {
return callbacks.map((callback): Callback => {
return {
...callback,
state: toCallbackStateReadable(callback.state),
Expand Down
5 changes: 4 additions & 1 deletion src/lib/types/nexus.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Endpoint, EndpointSpec } from '$lib/types';
import type { CallbackInfo, Endpoint, EndpointSpec } from '$lib/types';

export interface NexusEndpointSpec extends EndpointSpec {
descriptionString?: string;
Expand All @@ -9,3 +9,6 @@ export interface NexusEndpoint extends Endpoint {
state?: string;
spec?: NexusEndpointSpec;
}
export interface Callback extends CallbackInfo {
blockedReason?: string;
}
4 changes: 2 additions & 2 deletions src/lib/utilities/get-single-attribute-for-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ export const shouldDisplayChildWorkflowLink = (
const keysWithNexusEndpointLinks = ['endpointId'] as const;

export const shouldDisplayNexusEndpointLink = (key: string): boolean => {
for (const taskQueueKey of keysWithNexusEndpointLinks) {
if (key === taskQueueKey) return true;
for (const endpointKey of keysWithNexusEndpointLinks) {
if (key === endpointKey) return true;
}

return false;
Expand Down

0 comments on commit 22b37ea

Please sign in to comment.