- {#each visibleFilters as activityFilter, i (activityFilter.id)}
- {#if isStatusFilter(activityFilter) && i === firstExecutionStatusIndex}
- updateStatusFilters(i, statusFilters)}
- />
- {:else if !isStatusFilter(activityFilter) && activityFilter.attribute}
- updateFilter(i, updatedFilter)}
- onRemove={() => removeFilter(i)}
- />
- {/if}
- {/each}
-
- {#if hasMoreFilters}
-
- {/if}
-
-{/if}
diff --git a/src/lib/components/standalone-activities/activities-summary-filter-bar/filter-bar.svelte b/src/lib/components/standalone-activities/activities-summary-filter-bar/filter-bar.svelte
index d46b7a3e58..c0677a53de 100644
--- a/src/lib/components/standalone-activities/activities-summary-filter-bar/filter-bar.svelte
+++ b/src/lib/components/standalone-activities/activities-summary-filter-bar/filter-bar.svelte
@@ -1,40 +1,19 @@
-{#snippet actionToggleButtons()}
-
{translate('standalone-activities.standalone-activities-enablement')}
diff --git a/src/lib/components/worker-table.svelte b/src/lib/components/worker-table.svelte
index 52737720ca..2af0455b96 100644
--- a/src/lib/components/worker-table.svelte
+++ b/src/lib/components/worker-table.svelte
@@ -178,7 +178,7 @@
{:else}
|
-
+
|
{/each}
diff --git a/src/lib/components/workers/no-workers-polling-alert.svelte b/src/lib/components/workers/no-workers-polling-alert.svelte
new file mode 100644
index 0000000000..691d68ce66
--- /dev/null
+++ b/src/lib/components/workers/no-workers-polling-alert.svelte
@@ -0,0 +1,32 @@
+
+
+
+ {translate('workflows.workflow-error-no-workers-description', {
+ taskQueue: workflow?.taskQueue ?? '',
+ })}
+ {translate('workflows.workers-alert-description')}
+
+ {translate('workers.troubleshooting-workers-link')}
+
+
+
diff --git a/src/lib/components/workers/worker-details/skeleton.svelte b/src/lib/components/workers/worker-details/skeleton.svelte
new file mode 100644
index 0000000000..20ec1912c0
--- /dev/null
+++ b/src/lib/components/workers/worker-details/skeleton.svelte
@@ -0,0 +1,122 @@
+
+
+
+ {@render breadcrumb()}
+
+
+
+
+
+
+
+
+ {#each Array(3) as _, i (i)}
+
+
+
+
+
+
+ {/each}
+
+
+
+
+ {#each Array(4) as _, i (i)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/each}
+
+
+
+
+
diff --git a/src/lib/components/workers/worker-details/worker-details.svelte b/src/lib/components/workers/worker-details/worker-details.svelte
new file mode 100644
index 0000000000..a0b542f6a8
--- /dev/null
+++ b/src/lib/components/workers/worker-details/worker-details.svelte
@@ -0,0 +1,419 @@
+
+
+
+ {@render breadcrumb()}
+ {#if heartbeat?.workerInstanceKey}
+
+ {heartbeat.workerInstanceKey}
+ {/if}
+
+
+
+
+
+
+
+ {translate('workflows.last-heartbeat')}
+
+ {translate('common.start')}
+
+
+
+
+ {#if heartbeat?.taskQueue}
+ {translate('common.task-queue')}
+
+ {/if}
+ {translate('workers.sdk')}
+
+
+
+
+
+
+ {translate('deployments.build-id')}
+
+ {translate('deployments.deployment')}
+
+
+
+
+
+
+ {@render taskSlotCard(
+ translate('common.workflows-plural', { count: 1 }),
+ heartbeat?.workflowTaskSlotsInfo,
+ heartbeat?.workflowPollerInfo,
+ )}
+ {@render taskSlotCard(
+ translate('common.activities-plural', { count: 1 }),
+ heartbeat?.activityTaskSlotsInfo,
+ heartbeat?.activityPollerInfo,
+ )}
+ {@render taskSlotCard(
+ translate('workers.nexus-tasks'),
+ heartbeat?.nexusTaskSlotsInfo,
+ heartbeat?.nexusPollerInfo,
+ )}
+ {@render taskSlotCard(
+ translate('workers.local-activities'),
+ heartbeat?.localActivitySlotsInfo,
+ null,
+ )}
+
+
+
+
+
+
+{#snippet taskSlotCard(
+ title: string,
+ slots: WorkerSlotsInfo | null | undefined,
+ poller: WorkerPollerInfo | null | undefined,
+)}
+
+
+
{title}
+ {#if slots?.slotSupplierKind}
+ {slots.slotSupplierKind}
+ {/if}
+
+
+
+
+
-
+ {translate('workers.slots')}
+
+
-
+
+
+ {slots?.currentUsedSlots ?? 0}
+
+
+ {#if slots?.currentAvailableSlots}
+ {slots.currentAvailableSlots - (slots?.currentUsedSlots ?? 0)}
+ {:else}
+ -
+ {/if}
+
+
+
+
{translate('workers.used')}
+
+ {#if slots?.currentAvailableSlots}
+ {translate('workers.available-out-of', {
+ count: slots.currentAvailableSlots,
+ })}
+ {:else}
+ {translate('workers.none-available')}
+ {/if}
+
+
+
+ {@render meterBar(
+ `slots-${title}`,
+ slots?.currentUsedSlots ?? 0,
+ slots?.currentAvailableSlots
+ ? slots.currentAvailableSlots
+ : (slots?.currentUsedSlots ?? 0),
+ )}
+
+
+
+
-
+ {translate('workers.tasks-processed')}
+
+ -
+ {(slots?.totalProcessedTasks ?? 0).toLocaleString()}
+
+
+
+ {#if poller}
+
+
-
+ {translate('workers.poller')}
+
+ {poller.isAutoscaling ? 'Autoscaling' : 'Manual'}
+
+
+
-
+
+ {poller.currentPollers ?? 0}
+
+
+ {#if poller.lastSuccessfulPollTime}
+ {translate('workers.last-poll')}
+
+ {:else}
+ {translate('workers.no-activity')}
+ {/if}
+
+
+
+ {/if}
+
+
+{/snippet}
+
+{#snippet meterBar(labelledby: string, value: number, maxValue: number = 100)}
+
+{/snippet}
+
+{#snippet goDependencyWarning()}
+
+ {translate('workers.go-dependency-warning-description')}
+
+
+
+{/snippet}
+
+{#snippet hostUsage()}
+
+
+
+
+
+ {translate('workers.cpu-usage')}
+
+ {heartbeat?.hostInfo?.currentHostCpuUsage?.toFixed(0) ?? '0'}%
+
+ {@render meterBar(
+ 'cpu-label',
+ heartbeat?.hostInfo?.currentHostCpuUsage ?? 0,
+ )}
+
+
+
+
+
+ {translate('workers.memory-usage')}
+
+ {heartbeat?.hostInfo?.currentHostMemUsage?.toFixed(0) ?? '0'}%
+
+ {@render meterBar(
+ 'memory-label',
+ heartbeat?.hostInfo?.currentHostMemUsage ?? 0,
+ )}
+
+ {#if goDependencyPotentiallyMissing}
+ {@render goDependencyWarning()}
+ {/if}
+
+{/snippet}
+
+{#snippet hostInfo()}
+
+
+
+ {translate('workers.host-info')}
+
+
+ - {translate('workers.host-name')}
+ - {heartbeat?.hostInfo?.hostName ?? '-'}
+
+ - {translate('workers.process-id')}
+ - {heartbeat?.hostInfo?.processId ?? '-'}
+
+ -
+ {translate('workers.worker-grouping')}
+
+ -
+ {heartbeat?.hostInfo?.workerGroupingKey ?? '-'}
+
+
+
+ {@render hostUsage()}
+
+{/snippet}
+
+{#snippet workflowCache()}
+
+
+ {translate('workers.workflow-cache')}
+
+
+
+
-
+ {currentStickyCacheSize.toLocaleString()}
+
+ -
+ {translate('workers.cache-size')}
+
+
+
+
-
+ {cacheHitRate}%
+
+ -
+ {translate('workers.cache-hits')}
+
+
+
+
+{/snippet}
+
+{#snippet diagnostics()}
+
+
+ {translate('workers.diagnostics')}
+
+
+ - {pollSuccessRate}%
+ -
+ {translate('workers.poll-success-rate')}
+
+
+
+{/snippet}
diff --git a/src/lib/components/workers/worker-heartbeats-disabled.svelte b/src/lib/components/workers/worker-heartbeats-disabled.svelte
new file mode 100644
index 0000000000..61dce95d99
--- /dev/null
+++ b/src/lib/components/workers/worker-heartbeats-disabled.svelte
@@ -0,0 +1,18 @@
+
+
+
+
+
{translate('workers.worker-heartbeats-enablement')}
+
+
diff --git a/src/lib/components/workers/worker-status.svelte b/src/lib/components/workers/worker-status.svelte
new file mode 100644
index 0000000000..d35e9d1490
--- /dev/null
+++ b/src/lib/components/workers/worker-status.svelte
@@ -0,0 +1,46 @@
+
+
+
+
+ {label[status]}
+ {#if isRunning}
+
+ {/if}
+
+
diff --git a/src/lib/components/workers/workers-table/task-queue-workers-table.svelte b/src/lib/components/workers/workers-table/task-queue-workers-table.svelte
new file mode 100644
index 0000000000..94c8fcb234
--- /dev/null
+++ b/src/lib/components/workers/workers-table/task-queue-workers-table.svelte
@@ -0,0 +1,50 @@
+
+
+{#snippet fallback()}
+ {#await getPollers({ queue: taskQueue, namespace })}
+
+
+ {:then workers}
+
+ {:catch error}
+
+ {/await}
+{/snippet}
+
+{#if useFallback}
+ {@render fallback()}
+{:else}
+
+{/if}
diff --git a/src/lib/components/workers/workers-table/worker-heartbeats-sdk-alert.svelte b/src/lib/components/workers/workers-table/worker-heartbeats-sdk-alert.svelte
new file mode 100644
index 0000000000..40305289ce
--- /dev/null
+++ b/src/lib/components/workers/workers-table/worker-heartbeats-sdk-alert.svelte
@@ -0,0 +1,64 @@
+
+
+
+
+ {#if currentSdk}
+ {@const { href, sdk, version } = currentSdk}
+
+ {translate('workers.worker-heartbeats-sdk-link-preface')}
+
+
+
+ {translate('workers.worker-heartbeats-sdk-link-postface')}
+
+ {:else}
+
{translate('workers.worker-heartbeats-sdk-list-preface')}
+ {#each supportedVersions as { href, sdk, version } (`${sdk}:${version}`)}
+
+
+
+ {/each}
+ {/if}
+
+
diff --git a/src/lib/components/workers/workers-table/workers-table-cell.svelte b/src/lib/components/workers/workers-table/workers-table-cell.svelte
new file mode 100644
index 0000000000..956da88701
--- /dev/null
+++ b/src/lib/components/workers/workers-table/workers-table-cell.svelte
@@ -0,0 +1,115 @@
+
+
+
+ {#if attribute === 'BuildId' || attribute === 'WorkerInstanceKey'}
+ {#if href}
+
+ {truncate(value)}
+
+ {:else}
+
+ {truncate(value)}
+
+ {/if}
+ {:else if href}
+ {value}
+ {:else if children}
+ {@render children?.()}
+ {:else}
+ {value}
+ {/if}
+ {#if value}
+
+ {/if}
+ |
diff --git a/src/lib/components/workers/workers-table/workers-table-row.svelte b/src/lib/components/workers/workers-table/workers-table-row.svelte
new file mode 100644
index 0000000000..81156eedfb
--- /dev/null
+++ b/src/lib/components/workers/workers-table/workers-table-row.svelte
@@ -0,0 +1,74 @@
+
+
+
+ |
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/components/workers/workers-table/workers-table.svelte b/src/lib/components/workers/workers-table/workers-table.svelte
new file mode 100644
index 0000000000..2cb318a1c5
--- /dev/null
+++ b/src/lib/components/workers/workers-table/workers-table.svelte
@@ -0,0 +1,74 @@
+
+
+
+
+ {translate('workers.workers')}
+
+
+
+ {#each columns as { label } (label)}
+ | {label} |
+ {/each}
+
+ {#each visibleItems as worker, i (worker.workerHeartbeat?.workerInstanceKey ?? i)}
+
+ {/each}
+
+
+ {#if hasQuery || runningWithNoWorkers}
+
+ {:else}
+
+
+
+ {/if}
+
+
diff --git a/src/lib/components/workflow/filter-bar/dropdown-filter-chip.svelte b/src/lib/components/workflow/filter-bar/dropdown-filter-chip.svelte
index 1f1a7b2e24..8ef5b5ab4f 100644
--- a/src/lib/components/workflow/filter-bar/dropdown-filter-chip.svelte
+++ b/src/lib/components/workflow/filter-bar/dropdown-filter-chip.svelte
@@ -55,7 +55,7 @@
onUpdate: (updatedFilter: SearchAttributeFilter) => void;
onRemove: () => void;
index?: number;
- openIndex?: number;
+ openIndex?: number | null;
};
let {
@@ -179,7 +179,7 @@
}
if (isDateTimeFilter(filter)) {
- if (filter.customDate) return value.split('BETWEEN')[1];
+ if (filter.customDate) return value?.split('BETWEEN')[1];
return $timestamp(value, { format: 'short' });
}
@@ -190,7 +190,7 @@
return value;
}
- function applyChanges(e) {
+ function applyChanges(e: SubmitEvent) {
e.preventDefault();
if (isInConditional(localFilter.conditional)) {
diff --git a/src/lib/components/workflow/workflow-call-stack-error.svelte b/src/lib/components/workflow/workflow-call-stack-error.svelte
deleted file mode 100644
index 9cb6992968..0000000000
--- a/src/lib/components/workflow/workflow-call-stack-error.svelte
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-{#if runningWithNoWorkers}
-
-
- {translate('workflows.workflow-error-no-workers-description', {
- taskQueue: workflow?.taskQueue ?? '',
- })}
-
-
-{/if}
diff --git a/src/lib/components/workflow/workflow-summary.svelte b/src/lib/components/workflow/workflow-summary.svelte
index 6c69b7135e..5f04a912d7 100644
--- a/src/lib/components/workflow/workflow-summary.svelte
+++ b/src/lib/components/workflow/workflow-summary.svelte
@@ -10,7 +10,7 @@
workflowSummaryViewOpen,
} from '$lib/stores/workflow-run';
import { formatDistanceAbbreviated } from '$lib/utilities/format-time';
- import { routeForWorkers } from '$lib/utilities/route-for';
+ import { routeForWorkflowWorkers } from '$lib/utilities/route-for';
$: ({ workflow } = $workflowRun);
$: elapsedTime = formatDistanceAbbreviated({
@@ -40,19 +40,19 @@
@@ -60,19 +60,21 @@
{translate('common.task-queue')}
-
+ {#if workflow?.taskQueue}
+
+ {/if}
diff --git a/src/lib/holocene/badge.svelte b/src/lib/holocene/badge.svelte
index 949160f488..11f8744a52 100644
--- a/src/lib/holocene/badge.svelte
+++ b/src/lib/holocene/badge.svelte
@@ -12,6 +12,7 @@
danger: 'bg-red-200',
count: 'h-6 w-6 min-w-max rounded-full bg-blue-300',
subtle: 'surface-subtle dark:text-white font-normal select-all',
+ ghost: 'surface-primary text-primary border border-subtle',
};
const types = cva(
diff --git a/src/lib/holocene/filter-or-copy-buttons.svelte b/src/lib/holocene/filter-or-copy-buttons.svelte
index c5c7d5b774..f43fcc977c 100644
--- a/src/lib/holocene/filter-or-copy-buttons.svelte
+++ b/src/lib/holocene/filter-or-copy-buttons.svelte
@@ -52,11 +52,11 @@