@odigos/ui-kit 0.0.89 → 0.0.90

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.90](https://github.com/odigos-io/ui-kit/compare/ui-kit-v0.0.89...ui-kit-v0.0.90) (2025-08-24)
4
+
5
+
6
+ ### Features
7
+
8
+ * improve trace-view design per Figma ([#342](https://github.com/odigos-io/ui-kit/issues/342)) ([9fd6a2b](https://github.com/odigos-io/ui-kit/commit/9fd6a2b23dd196aa6eb6f284fcf5f96d22c1a03a))
9
+
3
10
  ## [0.0.89](https://github.com/odigos-io/ui-kit/compare/ui-kit-v0.0.88...ui-kit-v0.0.89) (2025-08-21)
4
11
 
5
12
 
package/lib/components.js CHANGED
@@ -1,16 +1,16 @@
1
- import { B as Button } from './index-ff2e118e.js';
2
- export { A as AutocompleteInput, a as Badge, a9 as CenterThis, C as Checkbox, b as Code, c as ConditionDetails, D as DataCard, e as DataCardFieldTypes, d as DataCardFields, f as DataFinger, g as DataTab, h as DescribeRow, i as Divider, j as DocsButton, k as Drawer, m as DrawerFooter, l as DrawerHeader, n as Dropdown, E as ExtendArrow, F as FadeLoader, o as FieldError, p as FieldLabel, a8 as FlexColumn, a7 as FlexRow, H as Header, I as IconButton, q as IconGroup, r as IconTitleBadge, s as IconWrapped, t as IconsNav, u as ImageControlled, v as Input, w as InputList, x as InputTable, y as InteractiveTable, K as KeyValueInputsList, M as Modal, ac as ModalBody, z as MonitorsCheckboxes, G as MonitorsIcons, N as NavigationButtons, J as NoDataFound, L as NotificationNote, ab as Overlay, P as Popup, O as PopupForm, S as ScrollX, Q as SectionTitle, R as Segment, U as SelectionButton, V as SkeletonLoader, W as Status, X as Stepper, Y as TabList, ad as TableContainer, ae as TableTitleWrap, af as TableWrap, Z as Tag, _ as Text, a2 as TextArea, a3 as Toggle, T as ToggleCodeComponent, a4 as Tooltip, a5 as TraceLoader, aa as VerticalScroll, a6 as WarningModal, $ as getLinksFromText, a0 as getStrongsFromText, a1 as renderText } from './index-ff2e118e.js';
3
- export { C as CancelWarning, D as DeleteWarning } from './index-ff2ca759.js';
1
+ import { B as Button } from './index-651d36f3.js';
2
+ export { A as AutocompleteInput, a as Badge, a9 as CenterThis, C as Checkbox, b as Code, c as ConditionDetails, D as DataCard, e as DataCardFieldTypes, d as DataCardFields, f as DataFinger, g as DataTab, h as DescribeRow, i as Divider, j as DocsButton, k as Drawer, m as DrawerFooter, l as DrawerHeader, n as Dropdown, E as ExtendArrow, F as FadeLoader, o as FieldError, p as FieldLabel, a8 as FlexColumn, a7 as FlexRow, H as Header, I as IconButton, q as IconGroup, r as IconTitleBadge, s as IconWrapped, t as IconsNav, u as ImageControlled, v as Input, w as InputList, x as InputTable, y as InteractiveTable, K as KeyValueInputsList, M as Modal, ac as ModalBody, z as MonitorsCheckboxes, G as MonitorsIcons, N as NavigationButtons, J as NoDataFound, L as NotificationNote, ab as Overlay, P as Popup, O as PopupForm, S as ScrollX, Q as SectionTitle, R as Segment, U as SelectionButton, V as SkeletonLoader, W as Status, X as Stepper, Y as TabList, ad as TableContainer, ae as TableTitleWrap, af as TableWrap, Z as Tag, _ as Text, a2 as TextArea, a3 as Toggle, T as ToggleCodeComponent, a4 as Tooltip, a5 as TraceLoader, aa as VerticalScroll, a6 as WarningModal, $ as getLinksFromText, a0 as getStrongsFromText, a1 as renderText } from './index-651d36f3.js';
3
+ export { C as CancelWarning, D as DeleteWarning } from './index-41bb44dd.js';
4
4
  import React, { createContext, Component, createElement } from 'react';
5
- import { T as Theme } from './index-9436f4a7.js';
5
+ import { T as Theme } from './index-40dfa720.js';
6
6
  import 'styled-components';
7
- import './index-430be181.js';
7
+ import './index-1bc2b507.js';
8
8
  import './types.js';
9
9
  import './index-5e5f7bda.js';
10
- import './index-ddf36942.js';
11
- import './index-2b6ae9c8.js';
10
+ import './index-d92ef50b.js';
11
+ import './index-eff01b3d.js';
12
12
  import 'react-dom';
13
- import './useTransition-0f2cccf3.js';
13
+ import './useTransition-2df374a9.js';
14
14
 
15
15
  const ErrorBoundaryContext = createContext(null);
16
16
 
@@ -105,6 +105,8 @@ export declare const DISPLAY_TITLES: {
105
105
  INACTIVE: string;
106
106
  ENABLED: string;
107
107
  DISABLED: string;
108
+ NO_TRACES_FOUND: string;
109
+ ARE_SERVICES_INSTRUMENTED_AND_PRODUCING_TRAFFIC: string;
108
110
  };
109
111
  export declare const BUTTON_TEXTS: {
110
112
  ADD: string;
package/lib/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ACTION_OPTIONS, B as BUTTON_TEXTS, a as DEFAULT_DATA_STREAM_NAME, D as DISPLAY_LANGUAGES, b as DISPLAY_TITLES, F as FORM_ALERTS, I as INSTRUMENTATION_RULE_OPTIONS, L as LANGUAGE_OPTIONS, M as MONITORS_OPTIONS, S as STORAGE_KEYS } from './index-9436f4a7.js';
1
+ export { A as ACTION_OPTIONS, B as BUTTON_TEXTS, a as DEFAULT_DATA_STREAM_NAME, D as DISPLAY_LANGUAGES, b as DISPLAY_TITLES, F as FORM_ALERTS, I as INSTRUMENTATION_RULE_OPTIONS, L as LANGUAGE_OPTIONS, M as MONITORS_OPTIONS, S as STORAGE_KEYS } from './index-40dfa720.js';
2
2
  export { D as DESTINATION_CATEGORIES } from './index-1cb4f9e2.js';
3
3
  import 'react';
4
4
  import './types.js';
@@ -1,6 +1,8 @@
1
1
  import { type FC } from 'react';
2
2
  import type { Trace } from '@/types';
3
+ import { CSSProperties } from 'styled-components';
3
4
  interface TraceViewProps {
5
+ heightToRemove: CSSProperties['height'];
4
6
  traces: Trace[];
5
7
  }
6
8
  declare const TraceView: FC<TraceViewProps>;
@@ -2,6 +2,7 @@ import React, { type FC } from 'react';
2
2
  import type { TraceSpan } from '@/types';
3
3
  interface SpanProps {
4
4
  depth: number;
5
+ indexInMatrix: number;
5
6
  isHidden: boolean;
6
7
  isOpen: boolean;
7
8
  onToggleOpen: () => void;
@@ -11,8 +12,9 @@ interface SpanProps {
11
12
  minStartTime: number;
12
13
  maxEndTime: number;
13
14
  }
15
+ export declare const LEFT_MAX_WIDTH = 370;
14
16
  declare const Span: FC<SpanProps>;
15
- declare const renderSpans: (spans: TraceSpan[], depth: number, minStartTime: number, maxEndTime: number, maxDuration: number, openSpanIdsState: {
17
+ declare const renderSpans: (spans: TraceSpan[], indexInMatrix: number, depth: number, minStartTime: number, maxEndTime: number, maxDuration: number, openSpanIdsState: {
16
18
  value: string[];
17
19
  set: React.Dispatch<React.SetStateAction<string[]>>;
18
20
  }) => React.JSX.Element[];
package/lib/containers.js CHANGED
@@ -1,21 +1,21 @@
1
1
  import React, { useState, useEffect, forwardRef, useRef, useImperativeHandle, useMemo, Fragment, useCallback, Children } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
- import { b as DISPLAY_TITLES, T as Theme, V as usePendingStore, W as useNotificationStore, Q as useDrawerStore, B as BUTTON_TEXTS, X as useEntityStore, A as ACTION_OPTIONS, g as getActionIcon, O as useModalStore, F as FORM_ALERTS, Y as useFilterStore, e as getInstrumentationRuleIcon, Z as useDataStreamStore, _ as useInstrumentStore, d as getEntityId, D as DISPLAY_LANGUAGES, M as MONITORS_OPTIONS, S as STORAGE_KEYS, a as DEFAULT_DATA_STREAM_NAME, c as compareCondition, $ as useSetupStore, f as getProgrammingLanguageIcon, I as INSTRUMENTATION_RULE_OPTIONS, a0 as useSelectedStore, l as ImageErrorIcon, a1 as useDarkMode } from './index-9436f4a7.js';
3
+ import { b as DISPLAY_TITLES, T as Theme, V as usePendingStore, W as useNotificationStore, Q as useDrawerStore, B as BUTTON_TEXTS, X as useEntityStore, A as ACTION_OPTIONS, g as getActionIcon, O as useModalStore, F as FORM_ALERTS, Y as useFilterStore, e as getInstrumentationRuleIcon, Z as useDataStreamStore, _ as useInstrumentStore, d as getEntityId, D as DISPLAY_LANGUAGES, M as MONITORS_OPTIONS, S as STORAGE_KEYS, a as DEFAULT_DATA_STREAM_NAME, c as compareCondition, $ as useSetupStore, f as getProgrammingLanguageIcon, I as INSTRUMENTATION_RULE_OPTIONS, a0 as useSelectedStore, l as ImageErrorIcon, a1 as useDarkMode } from './index-40dfa720.js';
4
4
  import { ActionType, ActionKeyTypes, InputTypes, FieldTypes, EntityTypes, StatusType, Crud, OtherStatus, NodeTypes, EdgeTypes, AddNodeTypes, SignalType, HeadersCollectionKeyTypes, CustomInstrumentationsKeyTypes, CodeAttributesKeyTypes, PayloadCollectionKeyTypes, InstrumentationRuleType, K8sResourceKind, ProgrammingLanguages, MountMethod, AgentEnvVarsInjectionMethod, Profile, InstallationMethod } from './types.js';
5
- import { e as DataCardFieldTypes, p as FieldLabel, C as Checkbox, o as FieldError, v as Input, x as InputTable, a3 as Toggle, K as KeyValueInputsList, w as InputList, _ as Text, R as Segment, Q as SectionTitle, j as DocsButton, z as MonitorsCheckboxes, a2 as TextArea, k as Drawer, c as ConditionDetails, D as DataCard, a8 as FlexColumn, M as Modal, N as NavigationButtons, ac as ModalBody, L as NotificationNote, A as AutocompleteInput, i as Divider, W as Status, a7 as FlexRow, a4 as Tooltip, s as IconWrapped, G as MonitorsIcons, ad as TableContainer, ae as TableTitleWrap, r as IconTitleBadge, af as TableWrap, y as InteractiveTable, a9 as CenterThis, J as NoDataFound, a5 as TraceLoader, a as Badge, ag as nodeConfig, ah as useNodesState, ai as useEdgesState, aj as Flow, ak as applyNodeChanges, P as Popup, U as SelectionButton, aa as VerticalScroll, n as Dropdown, B as Button, I as IconButton, E as ExtendArrow, al as AddButton, F as FadeLoader, g as DataTab, X as Stepper, d as DataCardFields, Z as Tag, am as MarkerType, t as IconsNav, an as CopyText, h as DescribeRow, ao as PodContainer, ap as SourceContainer, q as IconGroup, O as PopupForm } from './index-ff2e118e.js';
5
+ import { e as DataCardFieldTypes, p as FieldLabel, C as Checkbox, o as FieldError, v as Input, x as InputTable, a3 as Toggle, K as KeyValueInputsList, w as InputList, _ as Text, R as Segment, Q as SectionTitle, j as DocsButton, z as MonitorsCheckboxes, a2 as TextArea, k as Drawer, c as ConditionDetails, D as DataCard, a8 as FlexColumn, M as Modal, N as NavigationButtons, ac as ModalBody, L as NotificationNote, A as AutocompleteInput, i as Divider, W as Status, a7 as FlexRow, a4 as Tooltip, s as IconWrapped, G as MonitorsIcons, ad as TableContainer, ae as TableTitleWrap, r as IconTitleBadge, af as TableWrap, y as InteractiveTable, a9 as CenterThis, J as NoDataFound, a5 as TraceLoader, a as Badge, ag as nodeConfig, ah as useNodesState, ai as useEdgesState, aj as Flow, ak as applyNodeChanges, P as Popup, U as SelectionButton, aa as VerticalScroll, n as Dropdown, B as Button, I as IconButton, E as ExtendArrow, al as AddButton, F as FadeLoader, g as DataTab, X as Stepper, d as DataCardFields, Z as Tag, am as MarkerType, t as IconsNav, an as CopyText, h as DescribeRow, ao as PodContainer, ap as SourceContainer, q as IconGroup, O as PopupForm } from './index-651d36f3.js';
6
6
  import { i as isEmpty, s as safeJsonParse, d as deepClone } from './index-5e5f7bda.js';
7
- import { C as CheckCircledIcon, O as OdigosLogo } from './index-2b6ae9c8.js';
8
- import { C as CrossCircledIcon, O as OdigosLogoText, F as FilterIcon, D as DataStreamsIcon, A as ArrowIcon, R as RefreshLeftArrowIcon, N as NotificationIcon, U as UserIcon, a as OverviewIcon, S as SlackLogo, K as KeyIcon, T as TerminalIcon, G as GearIcon } from './index-75412865.js';
7
+ import { C as CheckCircledIcon, O as OdigosLogo } from './index-eff01b3d.js';
8
+ import { C as CrossCircledIcon, O as OdigosLogoText, F as FilterIcon, D as DataStreamsIcon, A as ArrowIcon, R as RefreshLeftArrowIcon, N as NotificationIcon, U as UserIcon, a as OverviewIcon, S as SlackLogo, K as KeyIcon, T as TerminalIcon, G as GearIcon } from './index-a53852b3.js';
9
9
  import { useActionFormData, useSessionStorage, useDataStreamFormData, useDestinationFormData, useClickNotification, useSourceFormData, useSourceSelectionFormData } from './hooks.js';
10
- import { u as useKeyDown, a as useContainerSize, b as useClickNode, c as usePopup, d as useOnClickOutside, e as useInstrumentationRuleFormData, f as useTransition, g as useTimeAgo, h as useCopy, i as useGenericForm } from './useTransition-0f2cccf3.js';
11
- import { E as EditIcon, T as TrashIcon, S as SearchIcon, h as CheckIcon, P as PlusIcon, a as CopyIcon } from './index-430be181.js';
12
- import { D as DeleteWarning, C as CancelWarning } from './index-ff2ca759.js';
13
- import { g as getConditionsBooleans, m as mapConditions, b as getStatusIcon, h as splitCamelString, c as capitalizeFirstLetter, i as isStringABoolean, p as parseBooleanFromString } from './index-ddf36942.js';
14
- import { f as filterActions, k as getEntityLabel, j as getEntityIcon, s as sleep, e as formatBytes, h as getContainersIcons, m as getValueForRange, i as getDestinationIcon, d as filterSourcesByStream, c as filterSources, b as filterDestinationsByStream, a as filterDestinations, r as mapDestinationFieldsForDisplay, o as getYamlFieldsForDestination, l as getMetricForEntity, n as getWorkloadId, p as hasUnhealthyInstances, g as getContainersInstrumentedCount, q as isOverTime } from './index-5fb023f6.js';
10
+ import { u as useKeyDown, a as useContainerSize, b as useClickNode, c as usePopup, d as useOnClickOutside, e as useInstrumentationRuleFormData, f as useTransition, g as useTimeAgo, h as useCopy, i as useGenericForm } from './useTransition-2df374a9.js';
11
+ import { E as EditIcon, T as TrashIcon, S as SearchIcon, h as CheckIcon, P as PlusIcon, a as CopyIcon } from './index-1bc2b507.js';
12
+ import { D as DeleteWarning, C as CancelWarning } from './index-41bb44dd.js';
13
+ import { g as getConditionsBooleans, m as mapConditions, b as getStatusIcon, h as splitCamelString, c as capitalizeFirstLetter, i as isStringABoolean, p as parseBooleanFromString } from './index-d92ef50b.js';
14
+ import { f as filterActions, l as getEntityLabel, k as getEntityIcon, t as sleep, e as formatBytes, i as getContainersIcons, n as getValueForRange, j as getDestinationIcon, d as filterSourcesByStream, c as filterSources, b as filterDestinationsByStream, a as filterDestinations, s as mapDestinationFieldsForDisplay, p as getYamlFieldsForDestination, m as getMetricForEntity, o as getWorkloadId, q as hasUnhealthyInstances, h as getContainersInstrumentedCount, r as isOverTime, g as formatDuration } from './index-e21ce984.js';
15
15
  import { m as mapExportedSignals } from './index-6a6bea6e.js';
16
16
  import { NoteBackToSummary, EditButton } from './snippets.js';
17
17
  import { D as DESTINATION_CATEGORIES } from './index-1cb4f9e2.js';
18
- import { a6 as RulesIcon, a3 as SourcesIcon, a5 as ActionsIcon, a4 as DestinationsIcon } from './index-968d01e8.js';
18
+ import { a6 as RulesIcon, a3 as SourcesIcon, a5 as ActionsIcon, a4 as DestinationsIcon } from './index-b0883db6.js';
19
19
  import 'react-dom';
20
20
 
21
21
  const buildCard$3 = (action) => {
@@ -502,7 +502,7 @@ const CustomFields$1 = ({ actionType, value, setValue, formErrors }) => {
502
502
  return Component ? React.createElement(Component, { value: value, setValue: setValue, formErrors: formErrors }) : null;
503
503
  };
504
504
 
505
- const Container$i = styled.div `
505
+ const Container$j = styled.div `
506
506
  display: flex;
507
507
  flex-direction: column;
508
508
  gap: 24px;
@@ -513,7 +513,7 @@ const FieldTitle$2 = styled(Text) `
513
513
  `;
514
514
  const ActionForm = ({ isUpdate, action, formData, formErrors, handleFormChange }) => {
515
515
  const theme = Theme.useTheme();
516
- return (React.createElement(Container$i, null,
516
+ return (React.createElement(Container$j, null,
517
517
  isUpdate && (React.createElement("div", null,
518
518
  React.createElement(FieldTitle$2, null, "Status"),
519
519
  React.createElement(Segment, { options: [
@@ -1042,7 +1042,7 @@ const ActionTable = ({ maxHeight, maxWidth }) => {
1042
1042
  React.createElement(NoDataFound, null)))));
1043
1043
  };
1044
1044
 
1045
- const Container$h = styled(FlexColumn) `
1045
+ const Container$i = styled(FlexColumn) `
1046
1046
  // width: 100vw;
1047
1047
  // height: 100vh;
1048
1048
  gap: 64px;
@@ -1076,7 +1076,7 @@ const AwaitPipeline = () => {
1076
1076
  useEffect(() => {
1077
1077
  awaitPipeline();
1078
1078
  }, []);
1079
- return (React.createElement(Container$h, null,
1079
+ return (React.createElement(Container$i, null,
1080
1080
  React.createElement(OdigosLogoText, { size: 100 }),
1081
1081
  React.createElement(TraceLoader, { width: 400 }),
1082
1082
  React.createElement(TextWrap, null,
@@ -1612,7 +1612,7 @@ const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount,
1612
1612
  return nodes;
1613
1613
  };
1614
1614
 
1615
- const Container$g = styled.div `
1615
+ const Container$h = styled.div `
1616
1616
  width: 100%;
1617
1617
  height: ${({ $heightToRemove }) => `calc(100vh - ${$heightToRemove})`};
1618
1618
  position: relative;
@@ -1694,7 +1694,7 @@ const DataFlow = ({ heightToRemove, metrics }) => {
1694
1694
  });
1695
1695
  handleNodesChanged(ruleNodes, EntityTypes.InstrumentationRule);
1696
1696
  }, [instrumentationRules, instrumentationRulesLoading, positions[EntityTypes.InstrumentationRule], containerHeight]);
1697
- return (React.createElement(Container$g, { ref: containerRef, "$heightToRemove": heightToRemove },
1697
+ return (React.createElement(Container$h, { ref: containerRef, "$heightToRemove": heightToRemove },
1698
1698
  React.createElement(Flow, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange })));
1699
1699
  };
1700
1700
 
@@ -1958,7 +1958,7 @@ const Filters$1 = () => {
1958
1958
  React.createElement(ErrorDropdown, { sources: sourcesByStream, value: filters['errors'], onSelect: (val) => setFilters((prev) => ({ ...prev, errors: [...(prev.errors || []), val] })), onDeselect: (val) => setFilters((prev) => ({ ...prev, errors: (prev.errors || []).filter((opt) => opt.id !== val.id) })), disabled: !filters['onlyErrors'], showSearch: true, required: true, isMulti: true })))));
1959
1959
  };
1960
1960
 
1961
- const Container$f = styled.div `
1961
+ const Container$g = styled.div `
1962
1962
  display: flex;
1963
1963
  flex-direction: column;
1964
1964
  gap: 24px;
@@ -1967,7 +1967,7 @@ const Container$f = styled.div `
1967
1967
  const DataStreamForm = ({ formData, handleFormChange, formErrors }) => {
1968
1968
  const { dataStreams, selectedStreamName } = useDataStreamStore();
1969
1969
  const existingDS = useMemo(() => dataStreams.find((s) => s.name === formData.name && s.name !== selectedStreamName), [dataStreams, formData.name, selectedStreamName]);
1970
- return (React.createElement(Container$f, null,
1970
+ return (React.createElement(Container$g, null,
1971
1971
  React.createElement(Input, { name: 'name', title: DISPLAY_TITLES.STREAM_NAME, placeholder: DISPLAY_TITLES.NAME_YOUR_STREAM_PLACEHOLDER, required: true, value: formData.name, onChange: ({ target: { value } }) => handleFormChange('name', value), errorMessage: formErrors['name'] }),
1972
1972
  existingDS && React.createElement(NotificationNote, { type: StatusType.Warning, message: DISPLAY_TITLES.DATA_STREAM_EXISTS_WARNING(selectedStreamName, existingDS.name) })));
1973
1973
  };
@@ -2018,7 +2018,7 @@ const DataStreamDrawer = ({ isOpen, onClose, dataStreamName, updateDataStream })
2018
2018
  const RelativeContainer$1 = styled.div `
2019
2019
  position: relative;
2020
2020
  `;
2021
- const Container$e = styled(FlexRow) `
2021
+ const Container$f = styled(FlexRow) `
2022
2022
  border: 1px solid ${({ theme }) => theme.colors.border};
2023
2023
  border-radius: 32px;
2024
2024
 
@@ -2060,7 +2060,7 @@ const DataStreamSelect = ({ onClickNewDataStream, updateDataStream, deleteDataSt
2060
2060
  React.createElement(EditIcon, null))))), [dataStreams, selectedStreamName, searchText]);
2061
2061
  return (React.createElement(React.Fragment, null,
2062
2062
  React.createElement(RelativeContainer$1, null,
2063
- React.createElement(Container$e, { "$gap": 0 },
2063
+ React.createElement(Container$f, { "$gap": 0 },
2064
2064
  React.createElement(Button, { variant: 'tertiary', onClick: () => {
2065
2065
  handlePosition(0, 50);
2066
2066
  setPopupOpen((prev) => !prev);
@@ -2089,7 +2089,7 @@ const DataStreamSelect = ({ onClickNewDataStream, updateDataStream, deleteDataSt
2089
2089
  }, dataStreamName: editOpenForDataStreamName, updateDataStream: updateDataStream })));
2090
2090
  };
2091
2091
 
2092
- const Container$d = styled.div `
2092
+ const Container$e = styled.div `
2093
2093
  display: flex;
2094
2094
  align-items: center;
2095
2095
  margin: 20px 0;
@@ -2102,7 +2102,7 @@ const PushToEnd = styled.div `
2102
2102
  `;
2103
2103
  const DataFlowActionsMenu = ({ addEntity, preventSearchPopup, onClickNewDataStream, updateDataStream, deleteDataStream }) => {
2104
2104
  const { setCurrentModal } = useModalStore();
2105
- return (React.createElement(Container$d, null,
2105
+ return (React.createElement(Container$e, null,
2106
2106
  React.createElement(DataStreamSelect, { onClickNewDataStream: onClickNewDataStream, updateDataStream: updateDataStream, deleteDataStream: deleteDataStream }),
2107
2107
  React.createElement(Search, { preventPopup: preventSearchPopup }),
2108
2108
  React.createElement(Filters$1, null),
@@ -2240,7 +2240,7 @@ const TestConnection = ({ destination, validateForm, status, testConnection, onS
2240
2240
  React.createElement(Text, { family: 'secondary', decoration: 'underline', size: 14, color: !!status ? theme.text[status] : undefined }, loading ? 'Checking' : status === StatusType.Success ? 'Connection OK' : status === 'error' ? 'Connection Failed' : 'Test Connection')));
2241
2241
  };
2242
2242
 
2243
- const Container$c = styled(FlexColumn) `
2243
+ const Container$d = styled(FlexColumn) `
2244
2244
  align-items: unset;
2245
2245
  padding: 0 4px;
2246
2246
  `;
@@ -2332,8 +2332,8 @@ const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validat
2332
2332
  message: testResult?.message || '',
2333
2333
  });
2334
2334
  };
2335
- return (React.createElement(Container$c, { "$gap": 24 },
2336
- React.createElement(Container$c, { "$gap": 12 },
2335
+ return (React.createElement(Container$d, { "$gap": 24 },
2336
+ React.createElement(Container$d, { "$gap": 12 },
2337
2337
  React.createElement(SectionTitle, { title: isUpdate ? 'Update destination' : 'Create destination', description: `Connect ${displayName} with Odigos.`, actionButton: testConnectionSupported && (React.createElement(TestConnection, { destination: formData, validateForm: validateForm, status: connection?.type, testConnection: testConnection, onError: onTestConnectionError, onSuccess: onTestConnectionSuccess })) }),
2338
2338
  React.createElement(NotesWrapper, null,
2339
2339
  testConnectionSupported && connection && React.createElement(NotificationNote, { type: connection.type, title: connection.title, message: connection.message }),
@@ -2471,7 +2471,7 @@ const DestinationsList = ({ items, onSelectNew, onSelectConfigured, isLoadingFor
2471
2471
  });
2472
2472
  };
2473
2473
 
2474
- const Container$b = styled.div `
2474
+ const Container$c = styled.div `
2475
2475
  display: flex;
2476
2476
  flex-direction: column;
2477
2477
  gap: 24px;
@@ -2497,7 +2497,7 @@ const ListsContainer = styled.div `
2497
2497
  max-height: calc(100vh - 400px);
2498
2498
  }
2499
2499
  `;
2500
- const NoDataFoundWrapper = styled(Container$b) `
2500
+ const NoDataFoundWrapper = styled(Container$c) `
2501
2501
  margin-top: 80px;
2502
2502
  `;
2503
2503
  const { MANAGED, SELF_HOSTED, DETECTED, EXISTS } = DESTINATION_CATEGORIES;
@@ -2564,7 +2564,7 @@ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSe
2564
2564
  }, [categories, potentialDestinations, destinations, search, selectedCategory, selectedMonitors, selectedStreamName, configuredDestinations, configuredDestinationsUpdateOnly]);
2565
2565
  if (hidden)
2566
2566
  return null;
2567
- return (React.createElement(Container$b, null,
2567
+ return (React.createElement(Container$c, null,
2568
2568
  React.createElement(SectionTitle, { title: 'Choose destination', description: 'Add backend destination you want to connect with Odigos.' }),
2569
2569
  React.createElement(Filters, null,
2570
2570
  React.createElement(WidthConstraint, null,
@@ -2578,7 +2578,7 @@ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSe
2578
2578
  React.createElement(DestinationsList, { items: filteredDestinations, onSelectNew: (dest) => onSelectNew(dest, selectedMonitors), onSelectConfigured: onSelectConfigured, isLoadingForDestinationIds: isLoadingForDestinationIds })))));
2579
2579
  };
2580
2580
 
2581
- const Container$a = styled.div `
2581
+ const Container$b = styled.div `
2582
2582
  display: flex;
2583
2583
  `;
2584
2584
  const SideMenuWrapper = styled.div `
@@ -2721,7 +2721,7 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
2721
2721
  };
2722
2722
  useKeyDown({ key: 'Enter', active: isOpen }, () => handleSubmit());
2723
2723
  return (React.createElement(Modal, { isOpen: isOpen, onClose: handleClose, header: { title: DISPLAY_TITLES.ADD_DESTINATION }, actionComponent: React.createElement(NavigationButtons, { buttons: renderHeaderButtons() }) },
2724
- React.createElement(Container$a, null,
2724
+ React.createElement(Container$b, null,
2725
2725
  React.createElement(SideMenuWrapper, null,
2726
2726
  React.createElement(Stepper, { currentStep: selectedItem ? 2 : 1, data: [
2727
2727
  { stepNumber: 1, title: DISPLAY_TITLES.DESTINATIONS },
@@ -2732,7 +2732,7 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
2732
2732
  selectedItem && (React.createElement(DestinationForm, { categoryItem: selectedItem, formData: formData, formErrors: formErrors, handleFormChange: handleFormChange, dynamicFields: dynamicFields, setDynamicFields: setDynamicFields, validateForm: validateForm, testConnection: testConnection }))))));
2733
2733
  };
2734
2734
 
2735
- const Container$9 = styled.div `
2735
+ const Container$a = styled.div `
2736
2736
  display: flex;
2737
2737
  flex-direction: column;
2738
2738
  align-items: center;
@@ -2748,7 +2748,7 @@ const DestinationList = ({ categories, withDelete }) => {
2748
2748
  return (React.createElement(CenterThis, null,
2749
2749
  React.createElement(NoDataFound, { title: 'No destinations', subTitle: 'Please add a destination' })));
2750
2750
  }
2751
- return (React.createElement(Container$9, null, configuredDestinations.concat(configuredDestinationsUpdateOnly).map((dest, idx) => (React.createElement(ListItem, { key: `configured-destination-${dest.destinationType.type}-${idx}`, "data-id": `configured-destination-${dest.destinationType.type}`, item: dest, yamlFields: getYamlFieldsForDestination(categories, dest), isLastItem: configuredDestinations.length + configuredDestinationsUpdateOnly.length === 1, withDelete: withDelete })))));
2751
+ return (React.createElement(Container$a, null, configuredDestinations.concat(configuredDestinationsUpdateOnly).map((dest, idx) => (React.createElement(ListItem, { key: `configured-destination-${dest.destinationType.type}-${idx}`, "data-id": `configured-destination-${dest.destinationType.type}`, item: dest, yamlFields: getYamlFieldsForDestination(categories, dest), isLastItem: configuredDestinations.length + configuredDestinationsUpdateOnly.length === 1, withDelete: withDelete })))));
2752
2752
  };
2753
2753
  const ListItem = ({ item, yamlFields, isLastItem, withDelete }) => {
2754
2754
  const [deleteWarning, setDeleteWarning] = useState(false);
@@ -3160,7 +3160,7 @@ const CustomFields = ({ ruleType, value, setValue, formErrors }) => {
3160
3160
  return Component ? React.createElement(Component, { value: value, setValue: setValue, formErrors: formErrors }) : null;
3161
3161
  };
3162
3162
 
3163
- const Container$8 = styled.div `
3163
+ const Container$9 = styled.div `
3164
3164
  display: flex;
3165
3165
  flex-direction: column;
3166
3166
  gap: 24px;
@@ -3171,7 +3171,7 @@ const FieldTitle = styled(Text) `
3171
3171
  `;
3172
3172
  const InstrumentationRuleForm = ({ isUpdate, rule, formData, formErrors, handleFormChange }) => {
3173
3173
  const theme = Theme.useTheme();
3174
- return (React.createElement(Container$8, null,
3174
+ return (React.createElement(Container$9, null,
3175
3175
  React.createElement(FlexRow, null, rule.supportedLanguages.map((lang) => (React.createElement(Tag, { key: lang, icon: getProgrammingLanguageIcon(lang), type: StatusType.Info }, lang)))),
3176
3176
  isUpdate ? (React.createElement("div", null,
3177
3177
  React.createElement(FieldTitle, null, "Status"),
@@ -3439,7 +3439,7 @@ const InstrumentationRuleTable = ({ maxHeight, maxWidth }) => {
3439
3439
  React.createElement(NoDataFound, null)))));
3440
3440
  };
3441
3441
 
3442
- const Container$7 = styled.div `
3442
+ const Container$8 = styled.div `
3443
3443
  position: fixed;
3444
3444
  bottom: 0;
3445
3445
  left: 50%;
@@ -3456,7 +3456,7 @@ const Container$7 = styled.div `
3456
3456
  const MultiSourceControl = ({ totalSourceCount, uninstrumentSources, restartWorkloads }) => {
3457
3457
  const theme = Theme.useTheme();
3458
3458
  const Transition = useTransition({
3459
- container: Container$7,
3459
+ container: Container$8,
3460
3460
  animateIn: Theme.animations.slide.in['center'],
3461
3461
  animateOut: Theme.animations.slide.out['center'],
3462
3462
  });
@@ -3812,14 +3812,14 @@ const buildMapNodes = ({ sources, serviceMap, containerHeight, containerWidth })
3812
3812
  y: containerHeight / 2 - 50,
3813
3813
  },
3814
3814
  data: {
3815
- subTitle: 'Are your services instrumented & producing traces?',
3815
+ subTitle: DISPLAY_TITLES.ARE_SERVICES_INSTRUMENTED_AND_PRODUCING_TRAFFIC,
3816
3816
  },
3817
3817
  });
3818
3818
  }
3819
3819
  return nodes;
3820
3820
  };
3821
3821
 
3822
- const Container$6 = styled.div `
3822
+ const Container$7 = styled.div `
3823
3823
  width: 100%;
3824
3824
  height: ${({ $heightToRemove }) => `calc(100vh - ${$heightToRemove})`};
3825
3825
  position: relative;
@@ -3877,11 +3877,11 @@ const ServiceMap = ({ heightToRemove, serviceMap }) => {
3877
3877
  useEffect(() => {
3878
3878
  setEdges(buildEdges({ theme, nodes, serviceMap }));
3879
3879
  }, [theme, nodes, serviceMap]);
3880
- return (React.createElement(Container$6, { ref: containerRef, "$heightToRemove": heightToRemove },
3880
+ return (React.createElement(Container$7, { ref: containerRef, "$heightToRemove": heightToRemove },
3881
3881
  React.createElement(Flow, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, zoomOnScroll: true })));
3882
3882
  };
3883
3883
 
3884
- const Container$5 = styled.div `
3884
+ const Container$6 = styled.div `
3885
3885
  display: flex;
3886
3886
  flex-direction: column;
3887
3887
  align-items: center;
@@ -3939,7 +3939,7 @@ const SourceList = ({ isModal = false, withInstances = true, isFetchingEachNames
3939
3939
  return (React.createElement(CenterThis, null, namespacesLoading ? (React.createElement(FadeLoader, null)) : (React.createElement(NoDataFound, { title: DISPLAY_TITLES.NO_SOURCES, subTitle: onSelectNamespace ? DISPLAY_TITLES.PLEASE_MAKE_SURE_UNIGNORED_NAMESPACES : DISPLAY_TITLES.PLEASE_ADD_SOURCE }))));
3940
3940
  }
3941
3941
  const NamespaceIcon = getEntityIcon(EntityTypes.Namespace);
3942
- return (React.createElement(Container$5, { "$isModal": isModal },
3942
+ return (React.createElement(Container$6, { "$isModal": isModal },
3943
3943
  matrix.map(([namespace, sources]) => {
3944
3944
  const sourcesForNamespace = selectedSources?.[namespace] || [];
3945
3945
  const futureAppsForNamespace = selectedFutureApps?.[namespace]?.selected || false;
@@ -3986,7 +3986,7 @@ const SourceRow = ({ withInstances, source, namespace, isSelected, onSelect, })
3986
3986
  ` • ${source.kind}`)))));
3987
3987
  };
3988
3988
 
3989
- const Container$4 = styled.div `
3989
+ const Container$5 = styled.div `
3990
3990
  display: flex;
3991
3991
  flex-direction: column;
3992
3992
  align-items: center;
@@ -4003,7 +4003,7 @@ const SetupSummary = ({ onEditStream, onEditSources, onEditDestinations, categor
4003
4003
  return (React.createElement(ModalBody, { "$isNotModal": true },
4004
4004
  React.createElement(FlexColumn, { "$gap": 12 },
4005
4005
  React.createElement(SectionTitle, { title: DISPLAY_TITLES.SUMMARY, description: DISPLAY_TITLES.STREAM_CONFIRM }),
4006
- React.createElement(Container$4, null,
4006
+ React.createElement(Container$5, null,
4007
4007
  React.createElement(DataCard, { title: DISPLAY_TITLES.STREAM_NAME, action: () => React.createElement(EditButton, { onClick: onEditStream }), data: [{ title: '', value: selectedStreamName }] }),
4008
4008
  React.createElement(DataCard, { title: DISPLAY_TITLES.SELECTED_SOURCES, titleBadge: sourceCount, action: () => React.createElement(EditButton, { onClick: onEditSources }) },
4009
4009
  React.createElement(SourceList, { filteredNamespacesAndSources: configuredSources, withInstances: false })),
@@ -4109,14 +4109,14 @@ const buildCard = (source) => {
4109
4109
  return arr;
4110
4110
  };
4111
4111
 
4112
- const Container$3 = styled.div `
4112
+ const Container$4 = styled.div `
4113
4113
  display: flex;
4114
4114
  flex-direction: column;
4115
4115
  gap: 24px;
4116
4116
  padding: 4px;
4117
4117
  `;
4118
4118
  const SourceForm = ({ formData, handleFormChange }) => {
4119
- return (React.createElement(Container$3, null,
4119
+ return (React.createElement(Container$4, null,
4120
4120
  React.createElement(Input, { name: 'sourceName', title: 'Source name', tooltip: 'This overrides the default service name that runs in your cluster.', placeholder: 'Use a name that overrides the source name', value: formData.otelServiceName, onChange: ({ target: { value } }) => handleFormChange('otelServiceName', value) })));
4121
4121
  };
4122
4122
 
@@ -5091,7 +5091,7 @@ const SystemSettings = ({ installationMethod, fetchSettings, onSave }) => {
5091
5091
  } })));
5092
5092
  };
5093
5093
 
5094
- const Container$2 = styled.div `
5094
+ const Container$3 = styled.div `
5095
5095
  position: fixed;
5096
5096
  bottom: 12px;
5097
5097
  left: 12px;
@@ -5109,7 +5109,7 @@ const ToastList = () => {
5109
5109
  if (asSeen)
5110
5110
  markAsSeen(id);
5111
5111
  };
5112
- return (React.createElement(Container$2, null, notifications
5112
+ return (React.createElement(Container$3, null, notifications
5113
5113
  .filter(({ dismissed }) => !dismissed)
5114
5114
  .map(({ id, type, title, message, crdType, target }) => (React.createElement(NotificationNote, { key: `toast-${id}`, id: id, type: type, title: title, message: message, action: crdType && target
5115
5115
  ? {
@@ -5125,7 +5125,7 @@ const ToastList = () => {
5125
5125
  : undefined, onClose: () => onClose({ id, asSeen: true }) })))));
5126
5126
  };
5127
5127
 
5128
- const Container$1 = styled.div `
5128
+ const Container$2 = styled.div `
5129
5129
  position: relative;
5130
5130
  display: flex;
5131
5131
  align-items: center;
@@ -5162,79 +5162,12 @@ const Svg = ({ path }) => {
5162
5162
  };
5163
5163
  const ToggleDarkMode = () => {
5164
5164
  const { darkMode, setDarkMode } = useDarkMode();
5165
- return (React.createElement(Container$1, { onClick: () => setDarkMode(!darkMode) },
5165
+ return (React.createElement(Container$2, { onClick: () => setDarkMode(!darkMode) },
5166
5166
  React.createElement(Svg, { path: 'M14 7.977A4.333 4.333 0 1 1 8.023 2H8a6 6 0 1 0 6 6v-.023Z' }),
5167
5167
  React.createElement(Svg, { path: 'M8 15.333v-.666m-5.185-1.482.471-.471M.666 8h.667m1.482-5.185.471.47M8 1.334V.667m4.714 2.619.471-.471M14.667 8h.666m-2.619 4.714.471.471M12 8a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z' }),
5168
5168
  React.createElement(Background, { "$darkMode": darkMode })));
5169
5169
  };
5170
5170
 
5171
- const LEFT_MAX_WIDTH = 370;
5172
- const Container = styled.div `
5173
- display: flex;
5174
- align-items: center;
5175
- padding: 12px 2px;
5176
- `;
5177
- const Left = styled(FlexRow) `
5178
- align-items: center;
5179
- gap: 4px;
5180
- padding-left: ${({ $depth }) => $depth * 16}px;
5181
- width: calc(${LEFT_MAX_WIDTH}px - ${({ $depth }) => $depth * 16}px);
5182
- overflow: auto;
5183
- `;
5184
- const Right = styled(FlexRow) `
5185
- align-items: center;
5186
- gap: 4px;
5187
- width: calc(100% - ${LEFT_MAX_WIDTH}px);
5188
- position: relative;
5189
- `;
5190
- const DurationBar = styled.div `
5191
- position: absolute;
5192
- left: ${({ $startTime, $minStartTime, $maxEndTime }) => `${(($startTime - $minStartTime) / ($maxEndTime - $minStartTime)) * 100}%`};
5193
- width: ${({ $duration, $maxDuration }) => `${($duration / $maxDuration) * 100}%`};
5194
- height: 12px;
5195
- border-radius: 32px;
5196
- background-color: ${({ theme }) => theme.colors.majestic_blue};
5197
- `;
5198
- const Span = ({ depth, isHidden, isOpen, onToggleOpen, withToggle, span, maxDuration, minStartTime, maxEndTime }) => {
5199
- const theme = Theme.useTheme();
5200
- if (isHidden)
5201
- return null;
5202
- return (React.createElement(Container, null,
5203
- React.createElement(Left, { "$depth": depth },
5204
- withToggle ? (React.createElement(IconButton, { onClick: onToggleOpen, size: 24 },
5205
- React.createElement(ExtendArrow, { extend: isOpen }))) : (React.createElement("div", { style: { width: '24px' } })),
5206
- React.createElement(Text, null, span.processID),
5207
- React.createElement(Text, { size: 12, color: theme.text.grey }, span.operationName)),
5208
- React.createElement(Right, null,
5209
- React.createElement(DurationBar, { "$duration": span.duration, "$maxDuration": maxDuration, "$startTime": span.startTime, "$minStartTime": minStartTime, "$maxEndTime": maxEndTime }))));
5210
- };
5211
- const getChildSpanIds = (span) => {
5212
- return span.spans?.map((s) => [s.spanID, ...getChildSpanIds(s)]).flat() ?? [];
5213
- };
5214
- const renderSpans = (spans, depth, minStartTime, maxEndTime, maxDuration, openSpanIdsState) => {
5215
- if (!minStartTime) {
5216
- // is equal left: 0%;
5217
- minStartTime = spans.reduce((min, span) => Math.min(min, span.startTime), Number.MAX_SAFE_INTEGER);
5218
- }
5219
- if (!maxEndTime) {
5220
- // is equal left: 100%;
5221
- maxEndTime = spans.reduce((max, span) => Math.max(max, span.startTime + span.duration), 0);
5222
- }
5223
- return spans.map((span) => {
5224
- const id = span.spanID;
5225
- const isOpen = openSpanIdsState.value.includes(id);
5226
- const hasChildSpans = !!(span.spans?.length ?? 0);
5227
- return (React.createElement(Fragment, { key: id },
5228
- React.createElement(Span, { depth: depth, isHidden: false, isOpen: isOpen, withToggle: hasChildSpans, onToggleOpen: () => openSpanIdsState.set((prev) => {
5229
- const alreadyOpen = prev.some((st) => st === id);
5230
- if (alreadyOpen)
5231
- return prev.filter((st) => st != id);
5232
- return [...prev, id, ...getChildSpanIds(span)];
5233
- }), span: span, maxDuration: maxDuration, minStartTime: minStartTime, maxEndTime: maxEndTime }),
5234
- isOpen && hasChildSpans ? renderSpans(span.spans || [], depth + 1, minStartTime, maxEndTime, maxDuration, openSpanIdsState) : null));
5235
- });
5236
- };
5237
-
5238
5171
  // This function builds a tree structure of spans from a trace.
5239
5172
  // It does this by first creating a map of all spans for easy lookup.
5240
5173
  // Then, it builds the tree structure by iterating over each span and adding it to the tree.
@@ -5291,15 +5224,125 @@ const buildSpans = (trace) => {
5291
5224
  return rootSpans.sort((a, b) => a.startTime - b.startTime);
5292
5225
  };
5293
5226
 
5227
+ const LEFT_MAX_WIDTH = 370;
5228
+ const DURATION_COLORS = ['#33DCA7', '#50F6E8', '#444AD9', '#8B55FF', '#FF7CA9'].reverse();
5229
+ const Container$1 = styled.div `
5230
+ display: flex;
5231
+ align-items: center;
5232
+ width: ${LEFT_MAX_WIDTH}px;
5233
+ background-color: ${({ theme }) => theme.colors.dark_grey};
5234
+ border-right: 1px solid ${({ theme }) => theme.colors.dropdown_bg_2};
5235
+ `;
5236
+ const Left = styled(FlexRow) `
5237
+ align-items: center;
5238
+ gap: 4px;
5239
+ padding: 12px 0;
5240
+ padding-left: ${({ $depth }) => $depth * 12 || 4}px;
5241
+ width: calc(${LEFT_MAX_WIDTH}px - ${({ $depth }) => $depth * 12}px);
5242
+ overflow: auto;
5243
+ `;
5244
+ const Right = styled(FlexRow) `
5245
+ position: absolute;
5246
+ right: 64px;
5247
+ align-items: center;
5248
+ gap: 4px;
5249
+ width: calc(100% - ${LEFT_MAX_WIDTH + 80}px);
5250
+ `;
5251
+ const DurationBar = styled.div `
5252
+ position: absolute;
5253
+ left: ${({ $startTime, $minStartTime, $maxEndTime }) => `${(($startTime - $minStartTime) / ($maxEndTime - $minStartTime)) * 100}%`};
5254
+ width: ${({ $duration, $maxDuration }) => `${($duration / $maxDuration) * 100}%`};
5255
+ height: 12px;
5256
+ border-radius: 32px;
5257
+ background-color: ${({ $indexInMatrix }) => DURATION_COLORS[$indexInMatrix % DURATION_COLORS.length]};
5258
+ `;
5259
+ const DurationText = styled(Text) `
5260
+ padding-left: calc(100% + 8px);
5261
+ font-size: 10px;
5262
+ color: ${({ theme }) => theme.text.darker_grey};
5263
+ font-family: ${({ theme }) => theme.font_family.secondary};
5264
+ white-space: nowrap;
5265
+ `;
5266
+ const Span = ({ depth, indexInMatrix, isHidden, isOpen, onToggleOpen, withToggle, span, maxDuration, minStartTime, maxEndTime }) => {
5267
+ const theme = Theme.useTheme();
5268
+ if (isHidden)
5269
+ return null;
5270
+ return (React.createElement(Container$1, { className: 'span-container' },
5271
+ React.createElement(Left, { "$depth": depth, className: 'span-left' },
5272
+ withToggle ? (React.createElement(IconButton, { onClick: onToggleOpen, size: 24 },
5273
+ React.createElement(ExtendArrow, { extend: isOpen }))) : (React.createElement("div", { style: { width: '24px' } })),
5274
+ React.createElement(Text, null, span.processID),
5275
+ React.createElement(Text, { size: 12, color: theme.text.darker_grey }, span.operationName)),
5276
+ React.createElement(Right, { className: 'span-right' },
5277
+ React.createElement(DurationBar, { "$indexInMatrix": indexInMatrix, "$duration": span.duration, "$maxDuration": maxDuration, "$startTime": span.startTime, "$minStartTime": minStartTime, "$maxEndTime": maxEndTime },
5278
+ React.createElement(DurationText, null, formatDuration(span.duration))))));
5279
+ };
5280
+ const getChildSpanIds = (span) => {
5281
+ return span.spans?.map((s) => [s.spanID, ...getChildSpanIds(s)]).flat() ?? [];
5282
+ };
5283
+ const renderSpans = (spans, indexInMatrix, depth, minStartTime, maxEndTime, maxDuration, openSpanIdsState) => {
5284
+ if (!minStartTime) {
5285
+ // is equal left: 0%;
5286
+ minStartTime = spans.reduce((min, span) => Math.min(min, span.startTime), Number.MAX_SAFE_INTEGER);
5287
+ }
5288
+ if (!maxEndTime) {
5289
+ // is equal left: 100%;
5290
+ maxEndTime = spans.reduce((max, span) => Math.max(max, span.startTime + span.duration), 0);
5291
+ }
5292
+ return spans.map((span, i) => {
5293
+ const id = span.spanID;
5294
+ const isOpen = openSpanIdsState.value.includes(id);
5295
+ const hasChildSpans = !!(span.spans?.length ?? 0);
5296
+ return (React.createElement(Fragment, { key: id },
5297
+ React.createElement(Span, { depth: depth, indexInMatrix: indexInMatrix + i + depth, isHidden: false, isOpen: isOpen, withToggle: hasChildSpans, onToggleOpen: () => openSpanIdsState.set((prev) => {
5298
+ const alreadyOpen = prev.some((st) => st === id);
5299
+ if (alreadyOpen)
5300
+ return prev.filter((st) => st != id);
5301
+ return [...prev, id, ...getChildSpanIds(span)];
5302
+ }), span: span, maxDuration: maxDuration, minStartTime: minStartTime, maxEndTime: maxEndTime }),
5303
+ isOpen && hasChildSpans ? renderSpans(span.spans || [], indexInMatrix + i, depth + 1, minStartTime, maxEndTime, maxDuration, openSpanIdsState) : null));
5304
+ });
5305
+ };
5306
+
5307
+ const Container = styled.div `
5308
+ width: 100%;
5309
+ height: ${({ $heightToRemove }) => `calc(100vh - ${$heightToRemove})`};
5310
+ `;
5294
5311
  const ContainSpans = styled.div `
5295
5312
  display: flex;
5296
5313
  flex-direction: column;
5297
5314
  gap: 0;
5315
+ border-radius: 24px;
5316
+ overflow: hidden;
5317
+ border: 1px solid ${({ theme }) => theme.colors.dropdown_bg_2};
5318
+ position: relative;
5319
+ `;
5320
+ const ContainTitle = styled.div `
5321
+ padding: 12px 12px 12px 24px;
5322
+ width: calc(${LEFT_MAX_WIDTH}px - 36px);
5323
+ background-color: ${({ theme }) => theme.colors.dark_grey};
5324
+ `;
5325
+ const NUM_OF_DURATION_DIVIDERS = 5;
5326
+ const DurationDivider = styled.div `
5327
+ width: 1px;
5328
+ height: 100%;
5329
+ border-left: 1px dashed ${({ theme }) => theme.colors.dropdown_bg_2};
5330
+ position: absolute;
5331
+ left: calc(${LEFT_MAX_WIDTH}px + ((100% - ${LEFT_MAX_WIDTH}px) / ${NUM_OF_DURATION_DIVIDERS}) * ${({ index }) => index});
5332
+ z-index: -1;
5333
+ `;
5334
+ const DurationTitle = styled(Text) `
5335
+ color: ${({ theme }) => theme.text.darker_grey};
5336
+ font-size: 12px;
5337
+ font-family: ${({ theme }) => theme.font_family.secondary};
5338
+ padding-top: 12px;
5339
+ padding-left: 12px;
5340
+ white-space: nowrap;
5298
5341
  `;
5299
- const TraceView = ({ traces }) => {
5342
+ const TraceView = ({ heightToRemove, traces }) => {
5300
5343
  const [openSpanIds, setOpenSpanIds] = useState([]);
5301
5344
  const finalTraces = useMemo(() => {
5302
- const sorted = traces.sort((a, b) => b.spans[0].startTime - a.spans[0].startTime);
5345
+ const sorted = deepClone(traces).sort((a, b) => b.spans[0].startTime - a.spans[0].startTime);
5303
5346
  const mapped = sorted.map((trace) => ({ ...trace, spans: buildSpans(trace) }));
5304
5347
  return mapped;
5305
5348
  }, [traces]);
@@ -5308,10 +5351,16 @@ const TraceView = ({ traces }) => {
5308
5351
  return Math.max(max, trace.spans.reduce((max, span) => max + span.duration, 0));
5309
5352
  }, 0);
5310
5353
  }, [finalTraces]);
5311
- return (React.createElement(ContainSpans, null, finalTraces.map((trace) => renderSpans(trace.spans, 0, 0, 0, maxDuration, {
5312
- value: openSpanIds,
5313
- set: setOpenSpanIds,
5314
- }))));
5354
+ return (React.createElement(Container, { "$heightToRemove": heightToRemove }, finalTraces.length ? (React.createElement(ContainSpans, null,
5355
+ React.createElement(ContainTitle, null,
5356
+ React.createElement(Text, null, "Service & operation")),
5357
+ finalTraces.map((trace, i) => renderSpans(trace.spans, i, 0, 0, 0, maxDuration, {
5358
+ value: openSpanIds,
5359
+ set: setOpenSpanIds,
5360
+ })),
5361
+ new Array(NUM_OF_DURATION_DIVIDERS).fill(null).map((_, i) => (React.createElement(DurationDivider, { key: `${i}-divider`, index: i },
5362
+ React.createElement(DurationTitle, null, formatDuration((maxDuration / NUM_OF_DURATION_DIVIDERS) * i))))))) : (React.createElement(CenterThis, { "$height": '50vh' },
5363
+ React.createElement(NoDataFound, { title: DISPLAY_TITLES.NO_TRACES_FOUND, subTitle: DISPLAY_TITLES.ARE_SERVICES_INSTRUMENTED_AND_PRODUCING_TRAFFIC })))));
5315
5364
  };
5316
5365
 
5317
5366
  export { ActionDrawer, ActionForm, ActionModal, ActionTable, AwaitPipeline, ConditionDropdown, DataFlow, DataFlowActionsMenu, DataStreamDrawer, DataStreamForm, DataStreamSelectionForm, DestinationDrawer, DestinationForm, DestinationModal, DestinationSelectionForm, DestinationTable, ErrorDropdown, InstrumentationRuleDrawer, InstrumentationRuleForm, InstrumentationRuleModal, InstrumentationRuleTable, KindDropdown, LanguageDropdown, MonitorDropdown, MultiSourceControl, NamespaceDropdown, NavIconIds, NotificationManager, OverviewDrawer, ServiceMap, SetupSummary, SideNav, SlackInvite, SourceDrawer, SourceForm, SourceModal, SourceSelectionForm, SourceTable, SystemOverview, SystemSettings, TableCellConditions, ToastList, ToggleDarkMode, TraceView };
@@ -0,0 +1 @@
1
+ export declare const formatDuration: (durationNanoseconds?: number) => string;
@@ -9,6 +9,7 @@ export * from './filter-sources';
9
9
  export * from './filter-sources-by-stream';
10
10
  export * from './flatten-object-keys';
11
11
  export * from './format-bytes';
12
+ export * from './format-duration';
12
13
  export * from './get-action-icon';
13
14
  export * from './get-conditions-booleans';
14
15
  export * from './get-containers-counts';
package/lib/functions.js CHANGED
@@ -1,15 +1,15 @@
1
- export { c as capitalizeFirstLetter, f as flattenObjectKeys, g as getConditionsBooleans, a as getMonitorIcon, b as getStatusIcon, i as isStringABoolean, d as isValidVersion, m as mapConditions, n as numbersOnly, p as parseBooleanFromString, e as parseJsonStringToPrettyString, r as removeEmptyValuesFromObject, s as safeJsonStringify, h as splitCamelString } from './index-ddf36942.js';
2
- import { K as K8sLogo } from './index-9436f4a7.js';
3
- export { c as compareCondition, g as getActionIcon, d as getEntityId, e as getInstrumentationRuleIcon, f as getProgrammingLanguageIcon } from './index-9436f4a7.js';
1
+ export { c as capitalizeFirstLetter, f as flattenObjectKeys, g as getConditionsBooleans, a as getMonitorIcon, b as getStatusIcon, i as isStringABoolean, d as isValidVersion, m as mapConditions, n as numbersOnly, p as parseBooleanFromString, e as parseJsonStringToPrettyString, r as removeEmptyValuesFromObject, s as safeJsonStringify, h as splitCamelString } from './index-d92ef50b.js';
2
+ import { K as K8sLogo } from './index-40dfa720.js';
3
+ export { c as compareCondition, g as getActionIcon, d as getEntityId, e as getInstrumentationRuleIcon, f as getProgrammingLanguageIcon } from './index-40dfa720.js';
4
4
  export { d as deepClone, i as isEmpty, s as safeJsonParse } from './index-5e5f7bda.js';
5
- export { f as filterActions, a as filterDestinations, b as filterDestinationsByStream, c as filterSources, d as filterSourcesByStream, e as formatBytes, h as getContainersIcons, g as getContainersInstrumentedCount, i as getDestinationIcon, j as getEntityIcon, k as getEntityLabel, l as getMetricForEntity, m as getValueForRange, n as getWorkloadId, o as getYamlFieldsForDestination, p as hasUnhealthyInstances, q as isOverTime, r as mapDestinationFieldsForDisplay, s as sleep } from './index-5fb023f6.js';
5
+ export { f as filterActions, a as filterDestinations, b as filterDestinationsByStream, c as filterSources, d as filterSourcesByStream, e as formatBytes, g as formatDuration, i as getContainersIcons, h as getContainersInstrumentedCount, j as getDestinationIcon, k as getEntityIcon, l as getEntityLabel, m as getMetricForEntity, n as getValueForRange, o as getWorkloadId, p as getYamlFieldsForDestination, q as hasUnhealthyInstances, r as isOverTime, s as mapDestinationFieldsForDisplay, t as sleep } from './index-e21ce984.js';
6
6
  export { g as getIdFromSseTarget, i as isLegalK8sLabel, m as mapExportedSignals } from './index-6a6bea6e.js';
7
7
  import { ProgrammingLanguages, PlatformType, EntityTypes } from './types.js';
8
8
  import 'react';
9
9
  import 'styled-components';
10
- import { O as OdigosLogo } from './index-2b6ae9c8.js';
11
- import { V as VmLogo } from './index-6344746d.js';
12
- import './index-968d01e8.js';
10
+ import { O as OdigosLogo } from './index-eff01b3d.js';
11
+ import { V as VmLogo } from './index-333086d8.js';
12
+ import './index-b0883db6.js';
13
13
 
14
14
  const cleanObjectEmptyStringsValues = (obj) => {
15
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
package/lib/hooks.js CHANGED
@@ -1,10 +1,10 @@
1
- import { W as useNotificationStore, F as FORM_ALERTS, Q as useDrawerStore, X as useEntityStore, Z as useDataStreamStore, $ as useSetupStore } from './index-9436f4a7.js';
1
+ import { W as useNotificationStore, F as FORM_ALERTS, Q as useDrawerStore, X as useEntityStore, Z as useDataStreamStore, $ as useSetupStore } from './index-40dfa720.js';
2
2
  import { ActionKeyTypes, ActionType, StatusType, EntityTypes, FieldTypes } from './types.js';
3
3
  import { useState, useEffect, useMemo } from 'react';
4
4
  import 'styled-components';
5
5
  import { i as isEmpty, s as safeJsonParse } from './index-5e5f7bda.js';
6
- import { i as useGenericForm } from './useTransition-0f2cccf3.js';
7
- export { b as useClickNode, a as useContainerSize, h as useCopy, e as useInstrumentationRuleFormData, u as useKeyDown, d as useOnClickOutside, c as usePopup, g as useTimeAgo, f as useTransition } from './useTransition-0f2cccf3.js';
6
+ import { i as useGenericForm } from './useTransition-2df374a9.js';
7
+ export { b as useClickNode, a as useContainerSize, h as useCopy, e as useInstrumentationRuleFormData, u as useKeyDown, d as useOnClickOutside, c as usePopup, g as useTimeAgo, f as useTransition } from './useTransition-2df374a9.js';
8
8
  import { g as getIdFromSseTarget, i as isLegalK8sLabel, m as mapExportedSignals } from './index-6a6bea6e.js';
9
9
 
10
10
  const INITIAL$2 = {
package/lib/icons.js CHANGED
@@ -1,11 +1,11 @@
1
- import { T as Theme } from './index-9436f4a7.js';
2
- export { i as AddClusterInfoIcon, o as CPlusPlusLogo, p as CSharpLogo, C as CodeAttributesIcon, m as CustomInstrumentationIcon, j as DeleteAttributeIcon, q as DotnetLogo, E as ElixirLogo, G as GoLogo, H as HeadersCollectionIcon, l as ImageErrorIcon, J as JavaLogo, K as K8sLogo, h as KafkaLogo, r as MysqlLogo, N as NginxLogo, s as NodejsLogo, n as PayloadCollectionIcon, t as PhpLogo, P as PiiMaskingIcon, u as PostgresLogo, v as PythonLogo, w as RedisLogo, R as RenameAttributeIcon, x as RubyLogo, y as RustLogo, k as SamplerIcon, z as SwiftLogo } from './index-9436f4a7.js';
3
- export { C as CheckCircledIcon, E as ErrorTriangleIcon, I as InfoIcon, L as LogsIcon, M as MetricsIcon, O as OdigosLogo, T as TracesIcon, W as WarningTriangleIcon } from './index-2b6ae9c8.js';
4
- export { A as ArrowIcon, C as CrossCircledIcon, D as DataStreamsIcon, F as FilterIcon, G as GearIcon, K as KeyIcon, N as NotificationIcon, O as OdigosLogoText, a as OverviewIcon, R as RefreshLeftArrowIcon, S as SlackLogo, T as TerminalIcon, U as UserIcon } from './index-75412865.js';
1
+ import { T as Theme } from './index-40dfa720.js';
2
+ export { i as AddClusterInfoIcon, o as CPlusPlusLogo, p as CSharpLogo, C as CodeAttributesIcon, m as CustomInstrumentationIcon, j as DeleteAttributeIcon, q as DotnetLogo, E as ElixirLogo, G as GoLogo, H as HeadersCollectionIcon, l as ImageErrorIcon, J as JavaLogo, K as K8sLogo, h as KafkaLogo, r as MysqlLogo, N as NginxLogo, s as NodejsLogo, n as PayloadCollectionIcon, t as PhpLogo, P as PiiMaskingIcon, u as PostgresLogo, v as PythonLogo, w as RedisLogo, R as RenameAttributeIcon, x as RubyLogo, y as RustLogo, k as SamplerIcon, z as SwiftLogo } from './index-40dfa720.js';
3
+ export { C as CheckCircledIcon, E as ErrorTriangleIcon, I as InfoIcon, L as LogsIcon, M as MetricsIcon, O as OdigosLogo, T as TracesIcon, W as WarningTriangleIcon } from './index-eff01b3d.js';
4
+ export { A as ArrowIcon, C as CrossCircledIcon, D as DataStreamsIcon, F as FilterIcon, G as GearIcon, K as KeyIcon, N as NotificationIcon, O as OdigosLogoText, a as OverviewIcon, R as RefreshLeftArrowIcon, S as SlackLogo, T as TerminalIcon, U as UserIcon } from './index-a53852b3.js';
5
5
  import React from 'react';
6
- export { h as CheckIcon, C as CodeIcon, a as CopyIcon, i as CrossIcon, E as EditIcon, b as EditedIcon, c as ExtendArrowIcon, f as EyeClosedIcon, g as EyeOpenIcon, L as ListIcon, M as MinusIcon, N as NoDataIcon, d as NotebookIcon, P as PlusIcon, S as SearchIcon, e as SortArrowsIcon, T as TrashIcon, X as XIcon } from './index-430be181.js';
7
- export { V as VmLogo } from './index-6344746d.js';
8
- export { a5 as ActionsIcon, A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, i as AwsCloudwatchLogo, S as AwsS3Logo, a1 as AwsXrayLogo, c as AxiomLogo, d as BetterStackLogo, B as BlobStorageLogo, e as BonreeLogo, C as CauselyLogo, f as ChecklyLogo, g as ChronosphereLogo, h as ClickhouseLogo, j as CoralogixLogo, D as Dash0Logo, k as DatadogLogo, a4 as DestinationsIcon, l as DynatraceLogo, E as ElasticApmLogo, m as ElasticSearchLogo, F as GigapipeLogo, G as GoogleCloudPlatformLogo, n as GrafanaLogo, o as GreptimeLogo, p as GroundcoverLogo, H as HoneycombLogo, q as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, r as LightstepLogo, s as LogzioLogo, t as LokiLogo, u as LumigoLogo, M as MiddlewareLogo, a2 as NamespacesIcon, N as NewRelicLogo, v as ObserveLogo, w as OneUptimeLogo, x as OpenObserveLogo, O as OpenTelemetryLogo, y as OpsVerseLogo, z as OracleLogo, P as PrometheusLogo, Q as QrynLogo, R as QuickwitLogo, a6 as RulesIcon, T as SeqLogo, U as SignozLogo, a3 as SourcesIcon, V as SplunkLogo, W as SumoLogicLogo, X as TelemetryHubLogo, Y as TempoLogo, Z as TingyunLogo, _ as TraceloopLogo, $ as UptraceLogo, a0 as VictoriaMetricsLogo } from './index-968d01e8.js';
6
+ export { h as CheckIcon, C as CodeIcon, a as CopyIcon, i as CrossIcon, E as EditIcon, b as EditedIcon, c as ExtendArrowIcon, f as EyeClosedIcon, g as EyeOpenIcon, L as ListIcon, M as MinusIcon, N as NoDataIcon, d as NotebookIcon, P as PlusIcon, S as SearchIcon, e as SortArrowsIcon, T as TrashIcon, X as XIcon } from './index-1bc2b507.js';
7
+ export { V as VmLogo } from './index-333086d8.js';
8
+ export { a5 as ActionsIcon, A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, i as AwsCloudwatchLogo, S as AwsS3Logo, a1 as AwsXrayLogo, c as AxiomLogo, d as BetterStackLogo, B as BlobStorageLogo, e as BonreeLogo, C as CauselyLogo, f as ChecklyLogo, g as ChronosphereLogo, h as ClickhouseLogo, j as CoralogixLogo, D as Dash0Logo, k as DatadogLogo, a4 as DestinationsIcon, l as DynatraceLogo, E as ElasticApmLogo, m as ElasticSearchLogo, F as GigapipeLogo, G as GoogleCloudPlatformLogo, n as GrafanaLogo, o as GreptimeLogo, p as GroundcoverLogo, H as HoneycombLogo, q as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, r as LightstepLogo, s as LogzioLogo, t as LokiLogo, u as LumigoLogo, M as MiddlewareLogo, a2 as NamespacesIcon, N as NewRelicLogo, v as ObserveLogo, w as OneUptimeLogo, x as OpenObserveLogo, O as OpenTelemetryLogo, y as OpsVerseLogo, z as OracleLogo, P as PrometheusLogo, Q as QrynLogo, R as QuickwitLogo, a6 as RulesIcon, T as SeqLogo, U as SignozLogo, a3 as SourcesIcon, V as SplunkLogo, W as SumoLogicLogo, X as TelemetryHubLogo, Y as TempoLogo, Z as TingyunLogo, _ as TraceloopLogo, $ as UptraceLogo, a0 as VictoriaMetricsLogo } from './index-b0883db6.js';
9
9
  import './types.js';
10
10
  import 'styled-components';
11
11
 
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as Theme } from './index-9436f4a7.js';
2
+ import { T as Theme } from './index-40dfa720.js';
3
3
 
4
4
  const CodeIcon = ({ size = 16, fill: f, rotate = 0, onClick, strokeWidth = 1 }) => {
5
5
  const theme = Theme.useTheme();
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as Theme } from './index-9436f4a7.js';
2
+ import { T as Theme } from './index-40dfa720.js';
3
3
 
4
4
  const VmLogo = ({ size = 16, fill: f, rotate = 0, onClick, strokeWidth = 1 }) => {
5
5
  const theme = Theme.useTheme();
@@ -1068,6 +1068,8 @@ const DISPLAY_TITLES = {
1068
1068
  INACTIVE: 'Inactive',
1069
1069
  ENABLED: 'Enabled',
1070
1070
  DISABLED: 'Disabled',
1071
+ NO_TRACES_FOUND: 'No traces found',
1072
+ ARE_SERVICES_INSTRUMENTED_AND_PRODUCING_TRAFFIC: 'Are your services instrumented & producing traffic?',
1071
1073
  };
1072
1074
  const BUTTON_TEXTS = {
1073
1075
  ADD: 'Add',
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { a6 as WarningModal } from './index-ff2e118e.js';
2
+ import { a6 as WarningModal } from './index-651d36f3.js';
3
3
  import { StatusType, EntityTypes } from './types.js';
4
- import './index-9436f4a7.js';
4
+ import './index-40dfa720.js';
5
5
  import 'styled-components';
6
6
 
7
7
  const CancelWarning = ({ isOpen, noOverlay, name, onApprove, onDeny }) => {
@@ -1,13 +1,13 @@
1
1
  import React, { Fragment, useMemo, useState, useEffect, useRef, forwardRef, createElement, useCallback, createContext, memo, useContext, useLayoutEffect } from 'react';
2
- import { T as Theme, B as BUTTON_TEXTS, l as ImageErrorIcon, M as MONITORS_OPTIONS, a2 as styleInject, V as usePendingStore, a0 as useSelectedStore, _ as useInstrumentStore, U as useActiveNodeStore, W as useNotificationStore, b as DISPLAY_TITLES, L as LANGUAGE_OPTIONS, F as FORM_ALERTS, D as DISPLAY_LANGUAGES, f as getProgrammingLanguageIcon } from './index-9436f4a7.js';
2
+ import { T as Theme, B as BUTTON_TEXTS, l as ImageErrorIcon, M as MONITORS_OPTIONS, a2 as styleInject, V as usePendingStore, a0 as useSelectedStore, _ as useInstrumentStore, U as useActiveNodeStore, W as useNotificationStore, b as DISPLAY_TITLES, L as LANGUAGE_OPTIONS, F as FORM_ALERTS, D as DISPLAY_LANGUAGES, f as getProgrammingLanguageIcon } from './index-40dfa720.js';
3
3
  import styled, { css } from 'styled-components';
4
- import { M as MinusIcon$1, h as CheckIcon, L as ListIcon, C as CodeIcon, c as ExtendArrowIcon, P as PlusIcon$1, a as CopyIcon, E as EditIcon, b as EditedIcon, e as SortArrowsIcon, d as NotebookIcon, X as XIcon, f as EyeClosedIcon, g as EyeOpenIcon, N as NoDataIcon, i as CrossIcon, S as SearchIcon, T as TrashIcon } from './index-430be181.js';
4
+ import { M as MinusIcon$1, h as CheckIcon, L as ListIcon, C as CodeIcon, c as ExtendArrowIcon, P as PlusIcon$1, a as CopyIcon, E as EditIcon, b as EditedIcon, e as SortArrowsIcon, d as NotebookIcon, X as XIcon, f as EyeClosedIcon, g as EyeOpenIcon, N as NoDataIcon, i as CrossIcon, S as SearchIcon, T as TrashIcon } from './index-1bc2b507.js';
5
5
  import { StatusType, OtherStatus, EntityTypes, NodeTypes, AddNodeTypes, EdgeTypes, ProgrammingLanguages, IntrumentationStatus, SortDirection, InputTypes, FieldTypes } from './types.js';
6
6
  import { s as safeJsonParse, i as isEmpty } from './index-5e5f7bda.js';
7
- import { b as getStatusIcon, r as removeEmptyValuesFromObject, s as safeJsonStringify, f as flattenObjectKeys, m as mapConditions, g as getConditionsBooleans, c as capitalizeFirstLetter, a as getMonitorIcon, i as isStringABoolean, p as parseBooleanFromString, d as isValidVersion, h as splitCamelString, e as parseJsonStringToPrettyString, n as numbersOnly } from './index-ddf36942.js';
7
+ import { b as getStatusIcon, r as removeEmptyValuesFromObject, s as safeJsonStringify, f as flattenObjectKeys, m as mapConditions, g as getConditionsBooleans, c as capitalizeFirstLetter, a as getMonitorIcon, i as isStringABoolean, p as parseBooleanFromString, d as isValidVersion, h as splitCamelString, e as parseJsonStringToPrettyString, n as numbersOnly } from './index-d92ef50b.js';
8
8
  import ReactDOM, { createPortal } from 'react-dom';
9
- import { c as usePopup, h as useCopy, b as useClickNode, i as useGenericForm, a as useContainerSize, f as useTransition, u as useKeyDown, d as useOnClickOutside } from './useTransition-0f2cccf3.js';
10
- import { I as InfoIcon } from './index-2b6ae9c8.js';
9
+ import { c as usePopup, h as useCopy, b as useClickNode, i as useGenericForm, a as useContainerSize, f as useTransition, u as useKeyDown, d as useOnClickOutside } from './useTransition-2df374a9.js';
10
+ import { I as InfoIcon } from './index-eff01b3d.js';
11
11
 
12
12
  const TextWrapper$2 = styled.div `
13
13
  color: ${({ $color, theme }) => $color || theme.text.secondary};
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as Theme } from './index-9436f4a7.js';
2
+ import { T as Theme } from './index-40dfa720.js';
3
3
 
4
4
  const OdigosLogoText = ({ size = 16, fill: f, rotate = 0, onClick }) => {
5
5
  const theme = Theme.useTheme();
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as Theme } from './index-9436f4a7.js';
2
+ import { T as Theme } from './index-40dfa720.js';
3
3
 
4
4
  const AlaudaLogo = ({ size = 16, fill, rotate = 0, onClick }) => {
5
5
  return (React.createElement("svg", { width: size, height: size, viewBox: '0 0 43 43', xmlns: 'http://www.w3.org/2000/svg', fill: 'none', style: { transform: `rotate(${rotate}deg)` }, onClick: onClick },
@@ -1,8 +1,8 @@
1
1
  import { StatusType, OtherStatus, SignalType } from './types.js';
2
2
  import 'react';
3
- import './index-9436f4a7.js';
3
+ import './index-40dfa720.js';
4
4
  import 'styled-components';
5
- import { L as LogsIcon, M as MetricsIcon, T as TracesIcon, C as CheckCircledIcon, E as ErrorTriangleIcon, W as WarningTriangleIcon, I as InfoIcon, O as OdigosLogo } from './index-2b6ae9c8.js';
5
+ import { L as LogsIcon, M as MetricsIcon, T as TracesIcon, C as CheckCircledIcon, E as ErrorTriangleIcon, W as WarningTriangleIcon, I as InfoIcon, O as OdigosLogo } from './index-eff01b3d.js';
6
6
 
7
7
  const capitalizeFirstLetter = (string) => {
8
8
  return string.charAt(0).toUpperCase() + string.slice(1);
@@ -1,8 +1,8 @@
1
1
  import { StatusType, DestinationTypes, EntityTypes } from './types.js';
2
- import { a as DEFAULT_DATA_STREAM_NAME, f as getProgrammingLanguageIcon, h as KafkaLogo } from './index-9436f4a7.js';
2
+ import { a as DEFAULT_DATA_STREAM_NAME, f as getProgrammingLanguageIcon, h as KafkaLogo } from './index-40dfa720.js';
3
3
  import 'react';
4
4
  import 'styled-components';
5
- import { A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, c as AxiomLogo, B as BlobStorageLogo, d as BetterStackLogo, e as BonreeLogo, C as CauselyLogo, f as ChecklyLogo, g as ChronosphereLogo, h as ClickhouseLogo, i as AwsCloudwatchLogo, j as CoralogixLogo, D as Dash0Logo, k as DatadogLogo, O as OpenTelemetryLogo, l as DynatraceLogo, E as ElasticApmLogo, m as ElasticSearchLogo, G as GoogleCloudPlatformLogo, n as GrafanaLogo, o as GreptimeLogo, p as GroundcoverLogo, H as HoneycombLogo, q as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, r as LightstepLogo, s as LogzioLogo, t as LokiLogo, u as LumigoLogo, M as MiddlewareLogo, N as NewRelicLogo, v as ObserveLogo, w as OneUptimeLogo, x as OpenObserveLogo, y as OpsVerseLogo, z as OracleLogo, P as PrometheusLogo, Q as QrynLogo, F as GigapipeLogo, R as QuickwitLogo, S as AwsS3Logo, T as SeqLogo, U as SignozLogo, V as SplunkLogo, W as SumoLogicLogo, X as TelemetryHubLogo, Y as TempoLogo, Z as TingyunLogo, _ as TraceloopLogo, $ as UptraceLogo, a0 as VictoriaMetricsLogo, a1 as AwsXrayLogo, a2 as NamespacesIcon, a3 as SourcesIcon, a4 as DestinationsIcon, a5 as ActionsIcon, a6 as RulesIcon } from './index-968d01e8.js';
5
+ import { A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, c as AxiomLogo, B as BlobStorageLogo, d as BetterStackLogo, e as BonreeLogo, C as CauselyLogo, f as ChecklyLogo, g as ChronosphereLogo, h as ClickhouseLogo, i as AwsCloudwatchLogo, j as CoralogixLogo, D as Dash0Logo, k as DatadogLogo, O as OpenTelemetryLogo, l as DynatraceLogo, E as ElasticApmLogo, m as ElasticSearchLogo, G as GoogleCloudPlatformLogo, n as GrafanaLogo, o as GreptimeLogo, p as GroundcoverLogo, H as HoneycombLogo, q as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, r as LightstepLogo, s as LogzioLogo, t as LokiLogo, u as LumigoLogo, M as MiddlewareLogo, N as NewRelicLogo, v as ObserveLogo, w as OneUptimeLogo, x as OpenObserveLogo, y as OpsVerseLogo, z as OracleLogo, P as PrometheusLogo, Q as QrynLogo, F as GigapipeLogo, R as QuickwitLogo, S as AwsS3Logo, T as SeqLogo, U as SignozLogo, V as SplunkLogo, W as SumoLogicLogo, X as TelemetryHubLogo, Y as TempoLogo, Z as TingyunLogo, _ as TraceloopLogo, $ as UptraceLogo, a0 as VictoriaMetricsLogo, a1 as AwsXrayLogo, a2 as NamespacesIcon, a3 as SourcesIcon, a4 as DestinationsIcon, a5 as ActionsIcon, a6 as RulesIcon } from './index-b0883db6.js';
6
6
  import { s as safeJsonParse } from './index-5e5f7bda.js';
7
7
 
8
8
  const filterActions = (actions, filters) => {
@@ -60,6 +60,54 @@ const formatBytes = (bytes) => {
60
60
  return `${value.toFixed(i === 0 ? 0 : 1)} ${sizes[i]}`;
61
61
  };
62
62
 
63
+ // 1000000000000000000 ns = 1 s
64
+ // 1000000000000000 ns = 1 ms
65
+ // 1000000000 ns = 1 μs
66
+ // 1000000 ns = 1 ns
67
+ // 1000 ns = 1 ns
68
+ // 100 ns = 1 ns
69
+ // 10 ns = 1 ns
70
+ // 1 ns = 1 ns
71
+ const formatDuration = (durationNanoseconds) => {
72
+ if (!durationNanoseconds)
73
+ return '0 ns';
74
+ // Define time unit thresholds and conversion factors
75
+ if (durationNanoseconds < 1000) {
76
+ // Less than 1 microsecond - show in nanoseconds
77
+ return `${durationNanoseconds.toFixed(0)} ns`;
78
+ }
79
+ else if (durationNanoseconds < 1000000) {
80
+ // Less than 1 millisecond - show in microseconds
81
+ const microseconds = durationNanoseconds / 1000;
82
+ return `${microseconds.toFixed(microseconds < 10 ? 2 : 0)} μs`;
83
+ }
84
+ else if (durationNanoseconds < 1000000000) {
85
+ // Less than 1 second - show in milliseconds
86
+ const milliseconds = durationNanoseconds / 1000000;
87
+ return `${milliseconds.toFixed(milliseconds < 10 ? 2 : 0)} ms`;
88
+ }
89
+ else if (durationNanoseconds < 60000000000) {
90
+ // Less than 1 minute - show in seconds
91
+ const seconds = durationNanoseconds / 1000000000;
92
+ return `${seconds.toFixed(seconds < 10 ? 2 : 0)} s`;
93
+ }
94
+ else if (durationNanoseconds < 3600000000000) {
95
+ // Less than 1 hour - show in minutes
96
+ const minutes = durationNanoseconds / 60000000000;
97
+ return `${minutes.toFixed(minutes < 10 ? 2 : 0)} m`;
98
+ }
99
+ else if (durationNanoseconds < 86400000000000) {
100
+ // Less than 1 day - show in hours
101
+ const hours = durationNanoseconds / 3600000000000;
102
+ return `${hours.toFixed(hours < 10 ? 2 : 0)} h`;
103
+ }
104
+ else {
105
+ // 1 day or more - show in days
106
+ const days = durationNanoseconds / 86400000000000;
107
+ return `${days.toFixed(days < 10 ? 2 : 0)} d`;
108
+ }
109
+ };
110
+
63
111
  const getContainersInstrumentedCount = (containers) => {
64
112
  const instrumentedCount = containers?.reduce((prev, curr) => (curr.instrumented ? prev + 1 : prev), 0);
65
113
  const totalCount = containers?.length || 0;
@@ -269,4 +317,4 @@ const mapDestinationFieldsForDisplay = (destination, yamlFields) => {
269
317
 
270
318
  const sleep = async (ms = 1000) => new Promise((resolve) => setTimeout(resolve, ms));
271
319
 
272
- export { filterDestinations as a, filterDestinationsByStream as b, filterSources as c, filterSourcesByStream as d, formatBytes as e, filterActions as f, getContainersInstrumentedCount as g, getContainersIcons as h, getDestinationIcon as i, getEntityIcon as j, getEntityLabel as k, getMetricForEntity as l, getValueForRange as m, getWorkloadId as n, getYamlFieldsForDestination as o, hasUnhealthyInstances as p, isOverTime as q, mapDestinationFieldsForDisplay as r, sleep as s };
320
+ export { filterDestinations as a, filterDestinationsByStream as b, filterSources as c, filterSourcesByStream as d, formatBytes as e, filterActions as f, formatDuration as g, getContainersInstrumentedCount as h, getContainersIcons as i, getDestinationIcon as j, getEntityIcon as k, getEntityLabel as l, getMetricForEntity as m, getValueForRange as n, getWorkloadId as o, getYamlFieldsForDestination as p, hasUnhealthyInstances as q, isOverTime as r, mapDestinationFieldsForDisplay as s, sleep as t };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { T as Theme } from './index-9436f4a7.js';
2
+ import { T as Theme } from './index-40dfa720.js';
3
3
 
4
4
  const OdigosLogo = ({ size = 16, fill: f, rotate = 0, onClick }) => {
5
5
  const theme = Theme.useTheme();
package/lib/snippets.js CHANGED
@@ -1,15 +1,15 @@
1
- import { B as Button, _ as Text, L as NotificationNote } from './index-ff2e118e.js';
2
- export { al as AddButton, aq as AddNode, ar as BaseNode, an as CopyText, as as EdgedNode, aj as Flow, at as FrameNode, au as HeaderNode, az as LabeledEdge, av as MapItemNode, aw as NoDataNode, ao as PodContainer, ax as ScrollNode, ay as SkeletonNode, ap as SourceContainer, ag as nodeConfig } from './index-ff2e118e.js';
1
+ import { B as Button, _ as Text, L as NotificationNote } from './index-651d36f3.js';
2
+ export { al as AddButton, aq as AddNode, ar as BaseNode, an as CopyText, as as EdgedNode, aj as Flow, at as FrameNode, au as HeaderNode, az as LabeledEdge, av as MapItemNode, aw as NoDataNode, ao as PodContainer, ax as ScrollNode, ay as SkeletonNode, ap as SourceContainer, ag as nodeConfig } from './index-651d36f3.js';
3
3
  import React from 'react';
4
- import { T as Theme, B as BUTTON_TEXTS, b as DISPLAY_TITLES } from './index-9436f4a7.js';
5
- import { E as EditIcon } from './index-430be181.js';
4
+ import { T as Theme, B as BUTTON_TEXTS, b as DISPLAY_TITLES } from './index-40dfa720.js';
5
+ import { E as EditIcon } from './index-1bc2b507.js';
6
6
  import { StatusType } from './types.js';
7
7
  import 'styled-components';
8
- import { I as InfoIcon } from './index-2b6ae9c8.js';
8
+ import { I as InfoIcon } from './index-eff01b3d.js';
9
9
  import './index-5e5f7bda.js';
10
- import './index-ddf36942.js';
10
+ import './index-d92ef50b.js';
11
11
  import 'react-dom';
12
- import './useTransition-0f2cccf3.js';
12
+ import './useTransition-2df374a9.js';
13
13
 
14
14
  const EditButton = ({ label, onClick, variant = 'tertiary', ...props }) => {
15
15
  const theme = Theme.useTheme();
package/lib/store.js CHANGED
@@ -1,4 +1,4 @@
1
- export { U as useActiveNodeStore, a1 as useDarkMode, Z as useDataStreamStore, Q as useDrawerStore, X as useEntityStore, Y as useFilterStore, _ as useInstrumentStore, O as useModalStore, W as useNotificationStore, V as usePendingStore, a0 as useSelectedStore, $ as useSetupStore } from './index-9436f4a7.js';
1
+ export { U as useActiveNodeStore, a1 as useDarkMode, Z as useDataStreamStore, Q as useDrawerStore, X as useEntityStore, Y as useFilterStore, _ as useInstrumentStore, O as useModalStore, W as useNotificationStore, V as usePendingStore, a0 as useSelectedStore, $ as useSetupStore } from './index-40dfa720.js';
2
2
  import 'react';
3
3
  import './types.js';
4
4
  import 'styled-components';
package/lib/theme.js CHANGED
@@ -1,4 +1,4 @@
1
- export { T as default } from './index-9436f4a7.js';
1
+ export { T as default } from './index-40dfa720.js';
2
2
  import 'styled-components';
3
3
  import 'react';
4
4
  import './types.js';
@@ -1,4 +1,4 @@
1
- import { O as useModalStore, Q as useDrawerStore, U as useActiveNodeStore } from './index-9436f4a7.js';
1
+ import { O as useModalStore, Q as useDrawerStore, U as useActiveNodeStore } from './index-40dfa720.js';
2
2
  import { AddNodeTypes, EntityTypes, PayloadCollectionKeyTypes, CodeAttributesKeyTypes, CustomInstrumentationsKeyTypes } from './types.js';
3
3
  import React, { useState, useMemo, useEffect, useRef, useCallback } from 'react';
4
4
  import styled from 'styled-components';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odigos/ui-kit",
3
- "version": "0.0.89",
3
+ "version": "0.0.90",
4
4
  "author": "Odigos",
5
5
  "repository": {
6
6
  "type": "git",