@workflow/web-shared 4.1.6 → 4.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import type { Event, WorkflowRun } from '@workflow/world';
2
+ import { type ExactIdSearchResult, type ExactWorkflowSearchIdKind } from '../lib/exact-event-search-id';
2
3
  export interface DurationInfo {
3
4
  /** Time from created → started (ms) */
4
5
  queued?: number;
@@ -33,7 +34,9 @@ interface EventsListProps {
33
34
  isDecrypting?: boolean;
34
35
  /** Run-level hint: the run contains encrypted data (from probe). */
35
36
  hasEncryptedData?: boolean;
37
+ /** Fetch events for an exact correlation or event ID. */
38
+ onExactIdSearch?: (id: string, kind: ExactWorkflowSearchIdKind, signal?: AbortSignal) => Promise<ExactIdSearchResult>;
36
39
  }
37
- export declare function EventListView({ events, run, onLoadEventData, hasMoreEvents, isLoadingMoreEvents, onLoadMoreEvents, encryptionKey, isLoading, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting, hasEncryptedData: hasEncryptedDataProp, }: EventsListProps): import("react/jsx-runtime").JSX.Element;
40
+ export declare function EventListView({ events, run, onLoadEventData, hasMoreEvents, isLoadingMoreEvents, onLoadMoreEvents, encryptionKey, isLoading, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting, hasEncryptedData: hasEncryptedDataProp, onExactIdSearch, }: EventsListProps): import("react/jsx-runtime").JSX.Element;
38
41
  export {};
39
42
  //# sourceMappingURL=event-list-view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-list-view.d.ts","sourceRoot":"","sources":["../../src/components/event-list-view.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA6I1D,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAwE3E;AAydD,UAAU,eAAe;IACvB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9C,6FAA6F;IAC7F,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B;iFAC6E;IAC7E,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAoaD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,GAAG,EACH,eAAe,EACf,aAAqB,EACrB,mBAA2B,EAC3B,gBAAgB,EAChB,aAAa,EACb,SAAiB,EACjB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,SAAS,EACT,YAAoB,EACpB,gBAAgB,EAAE,oBAA4B,GAC/C,EAAE,eAAe,2CAqcjB"}
1
+ {"version":3,"file":"event-list-view.d.ts","sourceRoot":"","sources":["../../src/components/event-list-view.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAU1D,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC/B,MAAM,8BAA8B,CAAC;AAyItC,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAwE3E;AAydD,UAAU,eAAe;IACvB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9C,6FAA6F;IAC7F,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gDAAgD;IAChD,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC3B;iFAC6E;IAC7E,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC;IACpD,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,eAAe,CAAC,EAAE,CAChB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,yBAAyB,EAC/B,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACnC;AAuaD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,GAAG,EACH,eAAe,EACf,aAAqB,EACrB,mBAA2B,EAC3B,gBAAgB,EAChB,aAAa,EACb,SAAiB,EACjB,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,SAAS,EACT,YAAoB,EACpB,gBAAgB,EAAE,oBAA4B,EAC9C,eAAe,GAChB,EAAE,eAAe,2CAujBjB"}
@@ -5,8 +5,10 @@ import { Check, ChevronRight, Copy } from 'lucide-react';
5
5
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
6
6
  import { Virtuoso } from 'react-virtuoso';
7
7
  import { isEncryptedMarker } from '../lib/hydration';
8
+ import { parseExactWorkflowSearchId, looksLikeWorkflowIdSearchInput, } from '../lib/exact-event-search-id';
8
9
  import { DecryptButton } from './ui/decrypt-button';
9
10
  import { formatDuration } from '../lib/utils';
11
+ import { useToast } from '../lib/toast';
10
12
  import { DataInspector, DecryptClickContext } from './ui/data-inspector';
11
13
  import { ErrorStackBlock, isStructuredErrorWithStack, } from './ui/error-stack-block';
12
14
  import { LoadMoreButton } from './ui/load-more-button';
@@ -403,7 +405,7 @@ function RowsSkeleton() {
403
405
  marginLeft: i % 4 === 0 ? 5 : 6,
404
406
  } })] }), _jsx("div", { className: "w-5 flex-shrink-0 flex items-center justify-center", children: _jsx(Skeleton, { className: "w-5 h-5", style: { borderRadius: 4 } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: '70%' } }) }), _jsxs("div", { className: "min-w-0 px-4 flex items-center gap-1.5", style: { flex: '2 1 0%' }, children: [_jsx(Skeleton, { className: "flex-shrink-0", style: { width: 6, height: 6, borderRadius: '50%' } }), _jsx(Skeleton, { className: "h-3", style: { width: '60%' } })] }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: '50%' } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: '75%' } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: '75%' } }) })] }, i))) }));
405
407
  }
406
- function EventRow({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, }) {
408
+ function EventRow({ event, index, isFirst, isLast, isExpanded, onToggleExpand, activeGroupKey, selectedGroupKey, selectedGroupRange, correlationNameMap, workflowName, durationMap, onSelectGroup, onHoverGroup, onLoadEventData, cachedEventData, onCacheEventData, encryptionKey, onEncryptedDataDetected, suppressGroupDimming = false, }) {
407
409
  const [isLoading, setIsLoading] = useState(false);
408
410
  const [loadedEventData, setLoadedEventData] = useState(cachedEventData);
409
411
  const [loadError, setLoadError] = useState(null);
@@ -433,7 +435,7 @@ function EventRow({ event, index, isFirst, isLast, isExpanded, onToggleExpand, a
433
435
  const durationInfo = durationKey ? durationMap.get(durationKey) : undefined;
434
436
  const hasActive = activeGroupKey !== undefined;
435
437
  const isRelated = rowGroupKey !== undefined && rowGroupKey === activeGroupKey;
436
- const isDimmed = hasActive && !isRelated;
438
+ const isDimmed = hasActive && !isRelated && !suppressGroupDimming;
437
439
  const isPulsing = hasActive && isRelated;
438
440
  // Gutter state derived from selectedGroupRange
439
441
  const showBranch = hasActive && isRelated && !isRun;
@@ -581,7 +583,8 @@ function EventRow({ event, index, isFirst, isLast, isExpanded, onToggleExpand, a
581
583
  // ──────────────────────────────────────────────────────────────────────────
582
584
  // Main component
583
585
  // ──────────────────────────────────────────────────────────────────────────
584
- export function EventListView({ events, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, }) {
586
+ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = false, isLoadingMoreEvents = false, onLoadMoreEvents, encryptionKey, isLoading = false, sortOrder: sortOrderProp, onSortOrderChange, onDecrypt, isDecrypting = false, hasEncryptedData: hasEncryptedDataProp = false, onExactIdSearch, }) {
587
+ const toast = useToast();
585
588
  const [internalSortOrder, setInternalSortOrder] = useState('asc');
586
589
  const effectiveSortOrder = sortOrderProp ?? internalSortOrder;
587
590
  const handleSortOrderChange = useCallback((order) => {
@@ -592,24 +595,36 @@ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = fa
592
595
  setInternalSortOrder(order);
593
596
  }
594
597
  }, [onSortOrderChange]);
598
+ const [searchQuery, setSearchQuery] = useState('');
599
+ const [searchResults, setSearchResults] = useState(null);
600
+ const [searchResultsTruncated, setSearchResultsTruncated] = useState(false);
601
+ const [searchError, setSearchError] = useState(null);
602
+ const [searchLoading, setSearchLoading] = useState(false);
603
+ const [searchNotFound, setSearchNotFound] = useState(false);
604
+ const searchRequestRef = useRef(0);
605
+ const virtuosoRef = useRef(null);
606
+ const parsedSearchId = useMemo(() => parseExactWorkflowSearchId(searchQuery), [searchQuery]);
607
+ const isExactSearchActive = searchResults !== null;
595
608
  const sortedEvents = useMemo(() => {
596
- if (!events || events.length === 0)
609
+ const sourceEvents = isExactSearchActive ? searchResults : (events ?? []);
610
+ if (sourceEvents.length === 0)
597
611
  return [];
598
612
  const dir = effectiveSortOrder === 'desc' ? -1 : 1;
599
- return [...events].sort((a, b) => dir *
613
+ return [...sourceEvents].sort((a, b) => dir *
600
614
  (new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()));
601
- }, [events, effectiveSortOrder]);
615
+ }, [events, effectiveSortOrder, isExactSearchActive, searchResults]);
602
616
  // Detect encrypted fields across all loaded events (inline eventData).
603
617
  const hasEncryptedInlineData = useMemo(() => {
604
- if (!events)
618
+ const sourceEvents = isExactSearchActive ? searchResults : events;
619
+ if (!sourceEvents)
605
620
  return false;
606
- for (const event of events) {
621
+ for (const event of sourceEvents) {
607
622
  const ed = event.eventData;
608
623
  if (hasEncryptedValues(ed))
609
624
  return true;
610
625
  }
611
626
  return false;
612
- }, [events]);
627
+ }, [events, isExactSearchActive, searchResults]);
613
628
  // Tracks whether any expanded row's lazy-loaded data contained encrypted markers.
614
629
  // Set to true by EventRow via onEncryptedDataDetected; never reset (sticky).
615
630
  const [foundEncryptedInLazyData, setFoundEncryptedInLazyData] = useState(false);
@@ -617,7 +632,7 @@ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = fa
617
632
  setFoundEncryptedInLazyData(true);
618
633
  }, []);
619
634
  const hasEncryptedData = hasEncryptedDataProp || hasEncryptedInlineData || foundEncryptedInLazyData;
620
- const { correlationNameMap, workflowName } = useMemo(() => buildNameMaps(events ?? null, run ?? null), [events, run]);
635
+ const { correlationNameMap, workflowName } = useMemo(() => buildNameMaps(isExactSearchActive ? searchResults : (events ?? null), run ?? null), [events, isExactSearchActive, run, searchResults]);
621
636
  const durationMap = useMemo(() => buildDurationMap(sortedEvents), [sortedEvents]);
622
637
  const [selectedGroupKey, setSelectedGroupKey] = useState(undefined);
623
638
  const [hoveredGroupKey, setHoveredGroupKey] = useState(undefined);
@@ -695,61 +710,112 @@ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = fa
695
710
  }
696
711
  return first >= 0 ? { first, last } : null;
697
712
  }, [activeGroupKey, sortedEvents]);
698
- const [searchQuery, setSearchQuery] = useState('');
699
- const virtuosoRef = useRef(null);
700
- const searchIndex = useMemo(() => {
701
- const entries = [];
702
- for (let i = 0; i < sortedEvents.length; i++) {
703
- const ev = sortedEvents[i];
704
- const isRun = isRunLevel(ev.eventType);
705
- const name = isRun
706
- ? (workflowName ?? '')
707
- : ev.correlationId
708
- ? (correlationNameMap.get(ev.correlationId) ?? '')
709
- : '';
710
- entries.push({
711
- fields: [
712
- ev.eventId,
713
- ev.correlationId ?? '',
714
- ev.eventType,
715
- formatEventType(ev.eventType),
716
- name,
717
- ].map((f) => f.toLowerCase()),
718
- groupKey: ev.correlationId ?? (isRun ? '__run__' : undefined),
719
- eventId: ev.eventId,
720
- index: i,
721
- });
722
- }
723
- return entries;
724
- }, [sortedEvents, correlationNameMap, workflowName]);
725
713
  useEffect(() => {
726
- const q = searchQuery.trim().toLowerCase();
727
- if (!q) {
714
+ const trimmed = searchQuery.trim();
715
+ if (!trimmed) {
716
+ searchRequestRef.current += 1;
717
+ setSearchResults(null);
718
+ setSearchResultsTruncated(false);
719
+ setSearchError(null);
720
+ setSearchLoading(false);
721
+ setSearchNotFound(false);
728
722
  setSelectedGroupKey(undefined);
729
723
  return;
730
724
  }
731
- let bestMatch = null;
732
- let bestScore = 0;
733
- for (const entry of searchIndex) {
734
- for (const field of entry.fields) {
735
- if (field && field.includes(q)) {
736
- const score = q.length / field.length;
737
- if (score > bestScore) {
738
- bestScore = score;
739
- bestMatch = entry;
725
+ const parsed = parseExactWorkflowSearchId(trimmed);
726
+ if (!parsed || !onExactIdSearch) {
727
+ setSearchResults(null);
728
+ setSearchLoading(false);
729
+ setSearchNotFound(false);
730
+ return;
731
+ }
732
+ const requestId = ++searchRequestRef.current;
733
+ setSearchLoading(true);
734
+ setSearchNotFound(false);
735
+ setSearchError(null);
736
+ const abortController = new AbortController();
737
+ const timer = setTimeout(() => {
738
+ void (async () => {
739
+ try {
740
+ const results = await onExactIdSearch(parsed.id, parsed.kind, abortController.signal);
741
+ if (abortController.signal.aborted ||
742
+ searchRequestRef.current !== requestId) {
743
+ return;
744
+ }
745
+ if (results.status === 'error') {
746
+ setSearchResults([]);
747
+ setSearchResultsTruncated(false);
748
+ setSearchNotFound(false);
749
+ setSearchError(results.message);
750
+ setSelectedGroupKey(undefined);
751
+ return;
752
+ }
753
+ if (results.status === 'not_found' ||
754
+ (results.status === 'ok' && results.events.length === 0)) {
755
+ setSearchResults([]);
756
+ setSearchResultsTruncated(false);
757
+ setSearchNotFound(true);
758
+ setSearchError(null);
759
+ setSelectedGroupKey(undefined);
760
+ return;
740
761
  }
762
+ setSearchResults(results.events);
763
+ setSearchResultsTruncated(Boolean(results.truncated));
764
+ setSearchNotFound(false);
765
+ setSearchError(null);
766
+ setSelectedGroupKey(parsed.kind === 'event'
767
+ ? (() => {
768
+ const first = results.events[0];
769
+ if (!first)
770
+ return undefined;
771
+ return isRunLevel(first.eventType)
772
+ ? '__run__'
773
+ : (first.correlationId ?? undefined);
774
+ })()
775
+ : parsed.id);
776
+ virtuosoRef.current?.scrollToIndex({
777
+ index: 0,
778
+ align: 'start',
779
+ behavior: 'smooth',
780
+ });
741
781
  }
742
- }
782
+ catch {
783
+ if (abortController.signal.aborted ||
784
+ searchRequestRef.current !== requestId) {
785
+ return;
786
+ }
787
+ setSearchResults([]);
788
+ setSearchResultsTruncated(false);
789
+ setSearchNotFound(false);
790
+ setSearchError('Failed to search events. Try again.');
791
+ setSelectedGroupKey(undefined);
792
+ }
793
+ finally {
794
+ if (searchRequestRef.current === requestId &&
795
+ !abortController.signal.aborted) {
796
+ setSearchLoading(false);
797
+ }
798
+ }
799
+ })();
800
+ }, 300);
801
+ return () => {
802
+ clearTimeout(timer);
803
+ abortController.abort();
804
+ };
805
+ }, [searchQuery, onExactIdSearch]);
806
+ const handleSearchKeyDown = useCallback((event) => {
807
+ if (event.key !== 'Enter') {
808
+ return;
743
809
  }
744
- if (bestMatch) {
745
- setSelectedGroupKey(bestMatch.groupKey);
746
- virtuosoRef.current?.scrollToIndex({
747
- index: bestMatch.index,
748
- align: 'center',
749
- behavior: 'smooth',
750
- });
810
+ const trimmed = searchQuery.trim();
811
+ if (!trimmed ||
812
+ parseExactWorkflowSearchId(trimmed) ||
813
+ !onExactIdSearch ||
814
+ !looksLikeWorkflowIdSearchInput(trimmed)) {
815
+ return;
751
816
  }
752
- }, [searchQuery, searchIndex]);
817
+ toast.info('Enter a full step ID, wait ID, hook ID, or event ID');
818
+ }, [searchQuery, onExactIdSearch, toast]);
753
819
  // Track whether we've ever had events to distinguish initial load from refetch
754
820
  const hasHadEventsRef = useRef(false);
755
821
  if (sortedEvents.length > 0) {
@@ -760,9 +826,6 @@ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = fa
760
826
  if (isInitialLoad) {
761
827
  return (_jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [_jsx("div", { style: { padding: 6 }, children: _jsx(Skeleton, { style: { height: 40, borderRadius: 6 } }) }), _jsxs("div", { className: "flex items-center gap-0 h-10 border-b flex-shrink-0", style: { borderColor: 'var(--ds-gray-alpha-200)' }, children: [_jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), _jsx("div", { className: "w-5 flex-shrink-0" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: 40 } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: 72 } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: 44 } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: 92 } }) }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: _jsx(Skeleton, { className: "h-3", style: { width: 60 } }) })] }), _jsx(RowsSkeleton, {})] }));
762
828
  }
763
- if (!isLoading && (!events || events.length === 0)) {
764
- return (_jsx("div", { className: "flex items-center justify-center h-full text-sm", style: { color: 'var(--ds-gray-700)' }, children: "No events found" }));
765
- }
766
829
  return (_jsx(DecryptClickContext.Provider, { value: onDecrypt ? { onDecrypt, isDecrypting } : undefined, children: _jsxs("div", { className: "h-full flex flex-col overflow-hidden", children: [_jsx("style", { children: `@keyframes workflow-dot-pulse{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(2.2);opacity:0}}` }), _jsxs("div", { style: {
767
830
  padding: 6,
768
831
  backgroundColor: 'var(--ds-background-100)',
@@ -786,7 +849,9 @@ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = fa
786
849
  justifyContent: 'center',
787
850
  color: 'var(--ds-gray-800)',
788
851
  flexShrink: 0,
789
- }, children: _jsxs("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: [_jsx("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }), _jsx("path", { d: "M11.5 11.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })] }) }), _jsx("input", { type: "search", placeholder: "Search by name, event type, or ID\u2026", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), style: {
852
+ }, children: _jsxs("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", focusable: "false", children: [_jsx("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }), _jsx("path", { d: "M11.5 11.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })] }) }), _jsx("input", { type: "search", placeholder: "Search by step ID, wait ID, hook ID, or event ID\u2026", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: handleSearchKeyDown, disabled: !onExactIdSearch, title: onExactIdSearch
853
+ ? undefined
854
+ : 'Exact ID search is unavailable in this view.', style: {
790
855
  marginLeft: -16,
791
856
  paddingInline: 12,
792
857
  fontFamily: 'inherit',
@@ -796,22 +861,38 @@ export function EventListView({ events, run, onLoadEventData, hasMoreEvents = fa
796
861
  outline: 'none',
797
862
  height: 40,
798
863
  width: '100%',
864
+ opacity: onExactIdSearch ? 1 : 0.5,
865
+ cursor: onExactIdSearch ? 'text' : 'not-allowed',
799
866
  } })] }), _jsx(MenuDropdown, { options: SORT_OPTIONS, value: effectiveSortOrder, onChange: handleSortOrderChange }), (hasEncryptedData || encryptionKey) && onDecrypt && (_jsx(DecryptButton, { decrypted: !!encryptionKey, loading: isDecrypting, onClick: onDecrypt }))] }), _jsxs("div", { className: "flex items-center gap-0 text-[13px] font-medium h-10 border-b flex-shrink-0", style: {
800
867
  borderColor: 'var(--ds-gray-alpha-200)',
801
868
  color: 'var(--ds-gray-900)',
802
869
  backgroundColor: 'var(--ds-background-100)',
803
- }, children: [_jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), _jsx("div", { className: "w-5 flex-shrink-0" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: "Time" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: "Event Type" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: "Name" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: "Correlation ID" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: "Event ID" })] }), isRefetching ? (_jsx(RowsSkeleton, {})) : (_jsx(Virtuoso, { ref: virtuosoRef, totalCount: sortedEvents.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
804
- if (!hasMoreEvents || isLoadingMoreEvents) {
870
+ }, children: [_jsx("div", { className: "flex-shrink-0", style: { width: GUTTER_WIDTH } }), _jsx("div", { className: "w-5 flex-shrink-0" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: "Time" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: "Event Type" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '2 1 0%' }, children: "Name" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: "Correlation ID" }), _jsx("div", { className: "min-w-0 px-4", style: { flex: '3 1 0%' }, children: "Event ID" })] }), isRefetching || searchLoading ? (_jsx(RowsSkeleton, {})) : sortedEvents.length === 0 ? (_jsx("div", { className: "flex flex-1 items-center justify-center px-6 text-center text-sm", style: { color: 'var(--ds-gray-700)' }, children: searchNotFound && searchQuery.trim()
871
+ ? `No events found for ${searchQuery.trim()}`
872
+ : searchError
873
+ ? searchError
874
+ : parsedSearchId && searchQuery.trim() && !onExactIdSearch
875
+ ? 'Exact ID search is unavailable in this view.'
876
+ : 'No events found' })) : (_jsx(Virtuoso, { ref: virtuosoRef, totalCount: sortedEvents.length, overscan: 20, defaultItemHeight: 40, endReached: () => {
877
+ if (isExactSearchActive ||
878
+ !hasMoreEvents ||
879
+ isLoadingMoreEvents) {
805
880
  return;
806
881
  }
807
882
  void onLoadMoreEvents?.();
808
883
  }, itemContent: (index) => {
809
884
  const ev = sortedEvents[index];
810
- return (_jsx(EventRow, { event: ev, index: index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey: activeGroupKey, selectedGroupKey: selectedGroupKey, selectedGroupRange: selectedGroupRange, correlationNameMap: correlationNameMap, workflowName: workflowName, durationMap: durationMap, onSelectGroup: onSelectGroup, onHoverGroup: onHoverGroup, onLoadEventData: onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey: encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected }));
885
+ return (_jsx(EventRow, { event: ev, index: index, isFirst: index === 0, isLast: index === sortedEvents.length - 1, isExpanded: expandedEventIds.has(ev.eventId), onToggleExpand: toggleEventExpanded, activeGroupKey: activeGroupKey, selectedGroupKey: selectedGroupKey, selectedGroupRange: selectedGroupRange, correlationNameMap: correlationNameMap, workflowName: workflowName, durationMap: durationMap, onSelectGroup: onSelectGroup, onHoverGroup: onHoverGroup, onLoadEventData: onLoadEventData, cachedEventData: eventDataCacheRef.current.get(ev.eventId) ?? null, onCacheEventData: cacheEventData, encryptionKey: encryptionKey, onEncryptedDataDetected: handleEncryptedDataDetected, suppressGroupDimming: isExactSearchActive }));
811
886
  }, style: { flex: 1, minHeight: 0 } })), _jsxs("div", { className: "relative flex-shrink-0 flex items-center h-10 border-t px-4 text-xs", style: {
812
887
  borderColor: 'var(--ds-gray-alpha-200)',
813
888
  color: 'var(--ds-gray-900)',
814
889
  backgroundColor: 'var(--ds-background-100)',
815
- }, children: [_jsxs("span", { children: [sortedEvents.length, " event", sortedEvents.length !== 1 ? 's' : '', " loaded"] }), hasMoreEvents && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: _jsx("div", { className: "pointer-events-auto", children: _jsx(LoadMoreButton, { loading: isLoadingMoreEvents, onClick: () => void onLoadMoreEvents?.() }) }) }))] })] }) }));
890
+ }, children: [_jsx("span", { children: isExactSearchActive
891
+ ? searchError
892
+ ? searchError
893
+ : searchNotFound
894
+ ? `No events found for ${searchQuery.trim()}`
895
+ : `${sortedEvents.length} event${sortedEvents.length !== 1 ? 's' : ''} for ${searchQuery.trim()}${searchResultsTruncated ? ' (results may be truncated)' : ''}`
896
+ : `${sortedEvents.length} event${sortedEvents.length !== 1 ? 's' : ''} loaded` }), !isExactSearchActive && hasMoreEvents && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: _jsx("div", { className: "pointer-events-auto", children: _jsx(LoadMoreButton, { loading: isLoadingMoreEvents, onClick: () => void onLoadMoreEvents?.() }) }) }))] })] }) }));
816
897
  }
817
898
  //# sourceMappingURL=event-list-view.js.map