@odigos/ui-kit 0.0.34 → 0.0.36

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/eslint.config.mjs +17 -0
  3. package/lib/components/data-card/index.d.ts +2 -1
  4. package/lib/components.js +8 -9
  5. package/lib/constants/strings/index.d.ts +6 -0
  6. package/lib/constants.js +1 -2
  7. package/lib/containers/data-flow/helpers/build-action-nodes.d.ts +7 -1
  8. package/lib/containers/data-flow/helpers/build-destination-nodes.d.ts +7 -1
  9. package/lib/containers/data-flow/helpers/build-edges.d.ts +2 -2
  10. package/lib/containers/data-flow/helpers/build-rule-nodes.d.ts +7 -1
  11. package/lib/containers/destination-modal/choose-destination/destinations-list/index.d.ts +1 -1
  12. package/lib/containers/destination-modal/choose-destination/index.d.ts +2 -2
  13. package/lib/containers.js +222 -97
  14. package/lib/functions.js +6 -7
  15. package/lib/hooks/index.d.ts +1 -0
  16. package/lib/hooks/useSessionStorage.d.ts +5 -0
  17. package/lib/hooks.js +4 -5
  18. package/lib/icons.js +7 -7
  19. package/lib/{index-Bd8ZAEvq.js → index-7YZOplrB.js} +1 -1
  20. package/lib/{index-Cq8NT9Hr.js → index-BGzxan6E.js} +1 -1
  21. package/lib/{index-ChYtqgBW.js → index-BbEmZ4Wj.js} +2 -2
  22. package/lib/{index-BZq0yNL-.js → index-Be0m3TUg.js} +30 -27
  23. package/lib/{index-CnZlllYu.js → index-BlZKWuxe.js} +7 -1
  24. package/lib/{index-a_WA-82O.js → index-CNbTSsNJ.js} +2 -2
  25. package/lib/{index-BBjwRlta.js → index-CrethNg6.js} +5 -12
  26. package/lib/{index-CIKkezVt.js → index-D8AnbGCE.js} +1 -1
  27. package/lib/{index--RecCPGA.js → index-DJpBLpwG.js} +1 -1
  28. package/lib/{index-DJGe2YeC.js → index-aRNtyuuU.js} +333 -232
  29. package/lib/{index-ovjVbVQq.js → index-oEjS7cX3.js} +4 -5
  30. package/lib/{index-BWZT-ipR.js → index-t3OxxFsp.js} +1 -1
  31. package/lib/mock-data/sources/index.d.ts +3 -0
  32. package/lib/snippets.js +8 -9
  33. package/lib/store.js +1 -1
  34. package/lib/theme/index.d.ts +2 -3
  35. package/lib/theme/palletes/index.d.ts +2 -105
  36. package/lib/theme.js +1 -1
  37. package/lib/types/common/index.d.ts +6 -0
  38. package/lib/types.js +8 -1
  39. package/lib/{useSourceSelectionFormData-DBNf1uEe.js → useSourceSelectionFormData-CH2xUOpu.js} +34 -16
  40. package/lib/{useTransition-dZ92VxT2.js → useTransition-0Rz0QKmh.js} +1 -1
  41. package/package.json +18 -21
  42. package/lib/index-mOgS3e5E.js +0 -101
package/lib/containers.js CHANGED
@@ -1,24 +1,23 @@
1
1
  import React, { useState, useEffect, forwardRef, useRef, useImperativeHandle, useMemo, memo, useContext, createContext, useCallback, useLayoutEffect, Fragment } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
- import { T as Theme, h as usePendingStore, g as useNotificationStore, b as useDrawerStore, c as useEntityStore, A as ACTION_OPTIONS, k as getActionIcon, f as useModalStore, d as useFilterStore, M as MONITORS_OPTIONS, s as styleInject, i as useSelectedStore, e as useInstrumentStore, m as getInstrumentationRuleIcon, a as useDataStreamStore, l as getEntityId, j as useSetupStore, I as INSTRUMENTATION_RULE_OPTIONS, u as useDarkMode } from './index-DJGe2YeC.js';
4
- import { a as DISPLAY_TITLES, B as BUTTON_TEXTS, F as FORM_ALERTS } from './index-mOgS3e5E.js';
3
+ import { k as DISPLAY_TITLES, T as Theme, h as usePendingStore, g as useNotificationStore, b as useDrawerStore, B as BUTTON_TEXTS, c as useEntityStore, A as ACTION_OPTIONS, l as getActionIcon, f as useModalStore, F as FORM_ALERTS, d as useFilterStore, M as MONITORS_OPTIONS, t as styleInject, i as useSelectedStore, e as useInstrumentStore, n as getInstrumentationRuleIcon, a as useDataStreamStore, m as getEntityId, S as STORAGE_KEYS, j as useSetupStore, I as INSTRUMENTATION_RULE_OPTIONS, u as useDarkMode } from './index-aRNtyuuU.js';
5
4
  import { ActionType, ActionKeyTypes, InputTypes, FieldTypes, EntityTypes, StatusType, Crud, OtherStatus, NodeTypes, AddNodeTypes, EdgeTypes, SignalType, HeadersCollectionKeyTypes, CodeAttributesKeyTypes, PayloadCollectionKeyTypes, InstrumentationRuleType } from './types.js';
6
- import { f as DataCardFieldTypes, o as FieldLabel, C as Checkbox, n as FieldError, u as Input, w as InputTable, K as KeyValueInputsList, v as InputList, V as Text, O as Segment, L as SectionTitle, i as DocsButton, y as MonitorsCheckboxes, W as TextArea, j as Drawer, d as ConditionDetails, D as DataCard, a0 as FlexColumn, M as Modal, N as NavigationButtons, a4 as ModalBody, J as NotificationNote, a as AutocompleteInput, h as Divider, R as Status, $ as FlexRow, Y as Tooltip, r as IconWrapped, z as MonitorsIcons, a5 as TableContainer, a6 as TableTitleWrap, q as IconTitleBadge, a7 as TableWrap, x as InteractiveTable, a1 as CenterThis, G as NoDataFound, Z as TraceLoader, b as Badge, E as ExtendArrow, a2 as VerticalScroll, P as SelectionButton, B as Button, m as Dropdown, a8 as getDefaultExportFromCjs, F as FadeLoader, g as DataTab, Q as SkeletonLoader, X as Toggle, A as AddButton$1, U as Stepper, I as IconButton, e as DataCardFields, s as IconsNav, p as IconGroup } from './index-BZq0yNL-.js';
5
+ import { f as DataCardFieldTypes, o as FieldLabel, C as Checkbox, n as FieldError, u as Input, w as InputTable, K as KeyValueInputsList, v as InputList, V as Text, O as Segment, L as SectionTitle, i as DocsButton, y as MonitorsCheckboxes, W as TextArea, j as Drawer, d as ConditionDetails, D as DataCard, a0 as FlexColumn, M as Modal, N as NavigationButtons, a4 as ModalBody, J as NotificationNote, a as AutocompleteInput, h as Divider, R as Status, $ as FlexRow, Y as Tooltip, r as IconWrapped, z as MonitorsIcons, a5 as TableContainer, a6 as TableTitleWrap, q as IconTitleBadge, a7 as TableWrap, x as InteractiveTable, a1 as CenterThis, G as NoDataFound, Z as TraceLoader, b as Badge, E as ExtendArrow, a2 as VerticalScroll, P as SelectionButton, B as Button, m as Dropdown, a8 as getDefaultExportFromCjs, F as FadeLoader, g as DataTab, Q as SkeletonLoader, X as Toggle, A as AddButton$1, U as Stepper, I as IconButton, e as DataCardFields, s as IconsNav, p as IconGroup } from './index-Be0m3TUg.js';
7
6
  import { i as isEmpty, s as safeJsonParse } from './index-BV85P9UP.js';
8
- import { i as CheckCircledIcon, O as OdigosLogo } from './index-Bd8ZAEvq.js';
9
- import { C as CrossCircledIcon, O as OdigosLogoText, a as OverviewIcon, F as FilterIcon, D as DataStreamsIcon, N as NotificationIcon, S as SlackLogo, K as KeyIcon, T as TerminalIcon } from './index--RecCPGA.js';
10
- import { u as useActionFormData, a as useClickNode, c as useDataStreamFormData, d as useDestinationFormData, b as useClickNotification, e as useSourceFormData, f as useSourceSelectionFormData } from './useSourceSelectionFormData-DBNf1uEe.js';
11
- import { d as useKeyDown, e as useOnClickOutside, u as useContainerSize, c as useInstrumentationRuleFormData, g as useTransition, f as useTimeAgo, a as useCopy } from './useTransition-dZ92VxT2.js';
12
- import { E as EditIcon } from './index-BWZT-ipR.js';
13
- import { T as TrashIcon, S as SearchIcon, P as PlusIcon$1, f as CheckIcon, A as ArrowIcon, a as CopyIcon, g as CrossIcon } from './index-CIKkezVt.js';
14
- import { D as DeleteWarning, C as CancelWarning } from './index-a_WA-82O.js';
15
- import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-ChYtqgBW.js';
16
- import { f as filterActions, i as getConditionsBooleans, n as getEntityLabel, m as getEntityIcon, x as sleep$1, p as getPlatformIcon, q as getPlatformLabel, h as formatBytes, k as getContainersIcons, r as getValueForRange, l as getDestinationIcon, w as mapExportedSignals, g as filterSourcesByStream, e as filterSources, b as filterDestinationsByStream, a as filterDestinations, v as mapDestinationFieldsForDisplay, c as compareCondition, t as getYamlFieldsForDestination, d as deepClone, o as getMetricForEntity, s as getWorkloadId, j as getContainersInstrumentedCount, u as isOverTime } from './index-BBjwRlta.js';
7
+ import { i as CheckCircledIcon, O as OdigosLogo } from './index-7YZOplrB.js';
8
+ import { C as CrossCircledIcon, O as OdigosLogoText, a as OverviewIcon, F as FilterIcon, D as DataStreamsIcon, N as NotificationIcon, S as SlackLogo, K as KeyIcon, T as TerminalIcon } from './index-DJpBLpwG.js';
9
+ import { u as useActionFormData, a as useClickNode, e as useSessionStorage, c as useDataStreamFormData, d as useDestinationFormData, b as useClickNotification, f as useSourceFormData, g as useSourceSelectionFormData } from './useSourceSelectionFormData-CH2xUOpu.js';
10
+ import { d as useKeyDown, e as useOnClickOutside, u as useContainerSize, c as useInstrumentationRuleFormData, g as useTransition, f as useTimeAgo, a as useCopy } from './useTransition-0Rz0QKmh.js';
11
+ import { E as EditIcon } from './index-t3OxxFsp.js';
12
+ import { T as TrashIcon, S as SearchIcon, P as PlusIcon$1, f as CheckIcon, A as ArrowIcon, a as CopyIcon, g as CrossIcon } from './index-D8AnbGCE.js';
13
+ import { D as DeleteWarning, C as CancelWarning } from './index-CNbTSsNJ.js';
14
+ import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-BbEmZ4Wj.js';
15
+ import { f as filterActions, i as getConditionsBooleans, n as getEntityLabel, m as getEntityIcon, w as sleep$1, p as getPlatformIcon, q as getPlatformLabel, h as formatBytes, k as getContainersIcons, r as getValueForRange, l as getDestinationIcon, g as filterSourcesByStream, e as filterSources, b as filterDestinationsByStream, a as filterDestinations, v as mapDestinationFieldsForDisplay, c as compareCondition, t as getYamlFieldsForDestination, d as deepClone, o as getMetricForEntity, s as getWorkloadId, j as getContainersInstrumentedCount, u as isOverTime } from './index-CrethNg6.js';
17
16
  import { createPortal } from 'react-dom';
18
- import { N as NoteBackToSummary, E as EditButton } from './index-ovjVbVQq.js';
17
+ import { m as mapExportedSignals } from './index-BlZKWuxe.js';
18
+ import { N as NoteBackToSummary, E as EditButton } from './index-oEjS7cX3.js';
19
19
  import { D as DESTINATION_CATEGORIES } from './index-Dqief9td.js';
20
- import { a6 as RulesIcon, a7 as SourcesIcon, a3 as ActionsIcon, a4 as DestinationsIcon } from './index-Cq8NT9Hr.js';
21
- import './index-CnZlllYu.js';
20
+ import { a6 as RulesIcon, a7 as SourcesIcon, a3 as ActionsIcon, a4 as DestinationsIcon } from './index-BGzxan6E.js';
22
21
 
23
22
  const buildCard$3 = (action) => {
24
23
  const { type, spec: { actionName, notes, signals, disabled, collectContainerAttributes, collectReplicaSetAttributes, collectWorkloadId, collectClusterId, labelsAttributes, annotationsAttributes, clusterAttributes, attributeNamesToDelete, renames, piiCategories, fallbackSamplingRatio, samplingPercentage, endpointsFilters, servicesNameFilters, attributeFilters, }, } = action;
@@ -13146,7 +13145,7 @@ const nodeConfig = {
13146
13145
  framePadding: 12,
13147
13146
  };
13148
13147
 
13149
- const { framePadding: framePadding$3 } = nodeConfig;
13148
+ const { framePadding: framePadding$5 } = nodeConfig;
13150
13149
  const Container$h = styled.div `
13151
13150
  position: relative;
13152
13151
  z-index: 1;
@@ -13158,7 +13157,7 @@ const Container$h = styled.div `
13158
13157
  overflow-x: hidden;
13159
13158
  `;
13160
13159
  const BaseNodeWrapper = styled.div `
13161
- margin: ${framePadding$3}px 0;
13160
+ margin: ${framePadding$5}px 0;
13162
13161
  `;
13163
13162
  const BottomOverlay = styled.div `
13164
13163
  position: fixed;
@@ -13390,7 +13389,7 @@ const Flow = ({ nodes, edges, onNodesChange, onEdgesChange }) => {
13390
13389
  } })))));
13391
13390
  };
13392
13391
 
13393
- const { nodeHeight: nodeHeight$3, framePadding: framePadding$2 } = nodeConfig;
13392
+ const { nodeHeight: nodeHeight$5, framePadding: framePadding$4 } = nodeConfig;
13394
13393
  const createEdge = (edgeId, params) => {
13395
13394
  const { theme, label, isMultiTarget, isError, animated } = params || {};
13396
13395
  const [sourceNodeId, targetNodeId] = edgeId.split('-to-');
@@ -13407,13 +13406,14 @@ const createEdge = (edgeId, params) => {
13407
13406
  const buildEdges = ({ theme, nodes, metrics, containerHeight }) => {
13408
13407
  const edges = [];
13409
13408
  const actionNodeId = nodes.find(({ id: nodeId }) => [`${EntityTypes.Action}-${NodeTypes.Frame}`, `${EntityTypes.Action}-${NodeTypes.Add}`].includes(nodeId))?.id;
13409
+ const scrollTopLimit = -80 / 2 + framePadding$4;
13410
+ const scrollBottomLimit = Math.floor(containerHeight / nodeHeight$5) * nodeHeight$5 - (nodeHeight$5 / 2 + framePadding$4);
13411
+ const isBaseNode = (nodeType) => nodeType === NodeTypes.Base || nodeType === NodeTypes.Edged;
13410
13412
  nodes.forEach(({ type: nodeType, id: nodeId, data: { type: entityType, id: entityId, status }, position }) => {
13411
- if (nodeType === NodeTypes.Edged && entityType === EntityTypes.Source) {
13413
+ if (entityType === EntityTypes.Source && isBaseNode(nodeType)) {
13412
13414
  const { namespace, name, kind } = entityId;
13413
13415
  const metric = metrics?.sources.find((m) => m.kind === kind && m.name === name && m.namespace === namespace);
13414
- const topLimit = -80 / 2 + framePadding$2;
13415
- const bottomLimit = Math.floor(containerHeight / nodeHeight$3) * nodeHeight$3 - (nodeHeight$3 / 2 + framePadding$2);
13416
- if (position.y >= topLimit && position.y <= bottomLimit) {
13416
+ if (position.y >= scrollTopLimit && position.y <= scrollBottomLimit) {
13417
13417
  edges.push(createEdge(`${nodeId}-to-${actionNodeId}`, {
13418
13418
  theme,
13419
13419
  animated: false,
@@ -13423,24 +13423,27 @@ const buildEdges = ({ theme, nodes, metrics, containerHeight }) => {
13423
13423
  }));
13424
13424
  }
13425
13425
  }
13426
- if (nodeType === NodeTypes.Base && entityType === EntityTypes.Destination) {
13426
+ if (entityType === EntityTypes.Destination && isBaseNode(nodeType)) {
13427
13427
  const metric = metrics?.destinations.find((m) => m.id === entityId);
13428
- edges.push(createEdge(`${actionNodeId}-to-${nodeId}`, {
13429
- theme,
13430
- animated: false,
13431
- isMultiTarget: true,
13432
- label: formatBytes(metric?.throughput),
13433
- isError: status === StatusType.Error,
13434
- }));
13428
+ if (position.y >= scrollTopLimit && position.y <= scrollBottomLimit) {
13429
+ edges.push(createEdge(`${actionNodeId}-to-${nodeId}`, {
13430
+ theme,
13431
+ animated: false,
13432
+ isMultiTarget: true,
13433
+ label: formatBytes(metric?.throughput),
13434
+ isError: status === StatusType.Error,
13435
+ }));
13436
+ }
13435
13437
  }
13436
13438
  });
13437
13439
  return edges;
13438
13440
  };
13439
13441
 
13440
- const { nodeWidth: nodeWidth$4 } = nodeConfig;
13442
+ const { nodeWidth: nodeWidth$4, nodeHeight: nodeHeight$4, framePadding: framePadding$3 } = nodeConfig;
13441
13443
  const mapToNodeData$3 = (entity) => {
13442
13444
  return {
13443
13445
  nodeWidth: nodeWidth$4,
13446
+ nodeHeight: nodeHeight$4, // for edged node
13444
13447
  id: entity.ruleId,
13445
13448
  type: EntityTypes.InstrumentationRule,
13446
13449
  status: undefined,
@@ -13451,7 +13454,7 @@ const mapToNodeData$3 = (entity) => {
13451
13454
  raw: entity,
13452
13455
  };
13453
13456
  };
13454
- const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }) => {
13457
+ const buildRuleNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }) => {
13455
13458
  const nodes = [];
13456
13459
  const position = positions[EntityTypes.InstrumentationRule];
13457
13460
  nodes.push({
@@ -13470,13 +13473,38 @@ const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }) => {
13470
13473
  },
13471
13474
  });
13472
13475
  if (!!entities.length) {
13476
+ nodes.push({
13477
+ id: `${EntityTypes.InstrumentationRule}-${NodeTypes.Scroll}`,
13478
+ type: NodeTypes.Scroll,
13479
+ position: {
13480
+ x: position['x'],
13481
+ y: position['y']() - framePadding$3,
13482
+ },
13483
+ style: {
13484
+ zIndex: 1,
13485
+ },
13486
+ data: {
13487
+ nodeWidth: nodeWidth$4,
13488
+ nodeHeight: containerHeight - nodeHeight$4 + framePadding$3 * 2,
13489
+ items: entities.map((rule, idx) => ({
13490
+ id: `${EntityTypes.InstrumentationRule}-${idx}`,
13491
+ data: mapToNodeData$3(rule),
13492
+ })),
13493
+ onScroll,
13494
+ },
13495
+ });
13473
13496
  entities.forEach((rule, idx) => {
13474
13497
  nodes.push({
13475
- id: `${EntityTypes.InstrumentationRule}-${idx}`,
13476
- type: NodeTypes.Base,
13498
+ id: `${EntityTypes.InstrumentationRule}-${idx}-hidden`,
13499
+ type: NodeTypes.Edged,
13500
+ extent: 'parent',
13501
+ parentId: `${EntityTypes.InstrumentationRule}-${NodeTypes.Scroll}`,
13477
13502
  position: {
13478
- x: position['x'],
13479
- y: position['y'](idx),
13503
+ x: framePadding$3,
13504
+ y: position['y'](idx) - (nodeHeight$4 - framePadding$3 / 2),
13505
+ },
13506
+ style: {
13507
+ zIndex: -1,
13480
13508
  },
13481
13509
  data: mapToNodeData$3(rule),
13482
13510
  });
@@ -13514,11 +13542,12 @@ const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }) => {
13514
13542
  return nodes;
13515
13543
  };
13516
13544
 
13517
- const { nodeWidth: nodeWidth$3, nodeHeight: nodeHeight$2, framePadding: framePadding$1 } = nodeConfig;
13545
+ const { nodeWidth: nodeWidth$3, nodeHeight: nodeHeight$3, framePadding: framePadding$2 } = nodeConfig;
13518
13546
  const mapToNodeData$2 = (entity) => {
13519
13547
  const { hasDisableds, priorotizedStatus } = getConditionsBooleans(entity.conditions || []);
13520
13548
  return {
13521
13549
  nodeWidth: nodeWidth$3,
13550
+ nodeHeight: nodeHeight$3, // for edged node
13522
13551
  id: entity.id,
13523
13552
  type: EntityTypes.Action,
13524
13553
  status: priorotizedStatus,
@@ -13531,7 +13560,7 @@ const mapToNodeData$2 = (entity) => {
13531
13560
  raw: entity,
13532
13561
  };
13533
13562
  };
13534
- const buildActionNodes = ({ loading, entities, positions, unfilteredCount }) => {
13563
+ const buildActionNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }) => {
13535
13564
  const nodes = [];
13536
13565
  const position = positions[EntityTypes.Action];
13537
13566
  nodes.push({
@@ -13551,30 +13580,53 @@ const buildActionNodes = ({ loading, entities, positions, unfilteredCount }) =>
13551
13580
  });
13552
13581
  if (!!entities.length) {
13553
13582
  nodes.push({
13554
- id: `${EntityTypes.Action}-${NodeTypes.Frame}`,
13555
- type: NodeTypes.Frame,
13583
+ id: `${EntityTypes.Action}-${NodeTypes.Scroll}`,
13584
+ type: NodeTypes.Scroll,
13556
13585
  position: {
13557
- x: position['x'] - framePadding$1,
13558
- y: position['y']() - framePadding$1,
13586
+ x: position['x'],
13587
+ y: position['y']() - framePadding$2,
13588
+ },
13589
+ style: {
13590
+ zIndex: 1,
13559
13591
  },
13560
13592
  data: {
13561
- nodeWidth: nodeWidth$3 + 2 * framePadding$1,
13562
- nodeHeight: nodeHeight$2 * entities.length + framePadding$1,
13593
+ nodeWidth: nodeWidth$3,
13594
+ nodeHeight: containerHeight - nodeHeight$3 + framePadding$2 * 2,
13595
+ items: entities.map((action, idx) => ({
13596
+ id: `${EntityTypes.Action}-${idx}`,
13597
+ data: mapToNodeData$2(action),
13598
+ })),
13599
+ onScroll,
13563
13600
  },
13564
13601
  });
13565
13602
  entities.forEach((action, idx) => {
13566
13603
  nodes.push({
13567
- id: `${EntityTypes.Action}-${idx}`,
13568
- type: NodeTypes.Base,
13604
+ id: `${EntityTypes.Action}-${idx}-hidden`,
13605
+ type: NodeTypes.Edged,
13569
13606
  extent: 'parent',
13570
- parentId: `${EntityTypes.Action}-${NodeTypes.Frame}`,
13607
+ parentId: `${EntityTypes.Action}-${NodeTypes.Scroll}`,
13571
13608
  position: {
13572
- x: framePadding$1,
13573
- y: position['y'](idx) - (nodeHeight$2 - framePadding$1),
13609
+ x: framePadding$2,
13610
+ y: position['y'](idx) - (nodeHeight$3 - framePadding$2 / 2),
13611
+ },
13612
+ style: {
13613
+ zIndex: -1,
13574
13614
  },
13575
13615
  data: mapToNodeData$2(action),
13576
13616
  });
13577
13617
  });
13618
+ nodes.push({
13619
+ id: `${EntityTypes.Action}-${NodeTypes.Frame}`,
13620
+ type: NodeTypes.Frame,
13621
+ position: {
13622
+ x: position['x'] - framePadding$2,
13623
+ y: position['y']() - framePadding$2,
13624
+ },
13625
+ data: {
13626
+ nodeWidth: nodeWidth$3 + 2 * framePadding$2,
13627
+ nodeHeight: Math.min(containerHeight, nodeHeight$3 * entities.length + framePadding$2),
13628
+ },
13629
+ });
13578
13630
  }
13579
13631
  else if (loading) {
13580
13632
  nodes.push({
@@ -13608,12 +13660,12 @@ const buildActionNodes = ({ loading, entities, positions, unfilteredCount }) =>
13608
13660
  return nodes;
13609
13661
  };
13610
13662
 
13611
- const { nodeWidth: nodeWidth$2, nodeHeight: nodeHeight$1, framePadding } = nodeConfig;
13663
+ const { nodeWidth: nodeWidth$2, nodeHeight: nodeHeight$2, framePadding: framePadding$1 } = nodeConfig;
13612
13664
  const mapToNodeData$1 = (entity) => {
13613
13665
  const { priorotizedStatus, hasDisableds } = getConditionsBooleans(entity.conditions || []);
13614
13666
  return {
13615
13667
  nodeWidth: nodeWidth$2,
13616
- nodeHeight: nodeHeight$1, // for edged node
13668
+ nodeHeight: nodeHeight$2, // for edged node
13617
13669
  id: {
13618
13670
  namespace: entity.namespace,
13619
13671
  name: entity.name,
@@ -13655,14 +13707,14 @@ const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, conta
13655
13707
  type: NodeTypes.Scroll,
13656
13708
  position: {
13657
13709
  x: position['x'],
13658
- y: position['y']() - framePadding,
13710
+ y: position['y']() - framePadding$1,
13659
13711
  },
13660
13712
  style: {
13661
13713
  zIndex: 1,
13662
13714
  },
13663
13715
  data: {
13664
13716
  nodeWidth: nodeWidth$2,
13665
- nodeHeight: containerHeight - nodeHeight$1 + framePadding * 2,
13717
+ nodeHeight: containerHeight - nodeHeight$2 + framePadding$1 * 2,
13666
13718
  items: entities.map((source, idx) => ({
13667
13719
  id: `${EntityTypes.Source}-${idx}`,
13668
13720
  data: mapToNodeData$1(source),
@@ -13677,8 +13729,8 @@ const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, conta
13677
13729
  extent: 'parent',
13678
13730
  parentId: `${EntityTypes.Source}-${NodeTypes.Scroll}`,
13679
13731
  position: {
13680
- x: framePadding,
13681
- y: position['y'](idx) - (nodeHeight$1 - framePadding / 2),
13732
+ x: framePadding$1,
13733
+ y: position['y'](idx) - (nodeHeight$2 - framePadding$1 / 2),
13682
13734
  },
13683
13735
  style: {
13684
13736
  zIndex: -1,
@@ -13719,11 +13771,11 @@ const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, conta
13719
13771
  return nodes;
13720
13772
  };
13721
13773
 
13722
- const { nodeWidth: nodeWidth$1, nodeHeight } = nodeConfig;
13774
+ const { nodeWidth: nodeWidth$1, nodeHeight: nodeHeight$1 } = nodeConfig;
13723
13775
  const getNodePositions = ({ containerWidth }) => {
13724
13776
  const startX = 24;
13725
13777
  const endX = (containerWidth <= 1500 ? 1500 : containerWidth) - nodeWidth$1 - startX;
13726
- const getY = (idx) => nodeHeight * ((idx || 0) + 1);
13778
+ const getY = (idx) => nodeHeight$1 * ((idx || 0) + 1);
13727
13779
  const positions = {
13728
13780
  [EntityTypes.Namespace]: {
13729
13781
  x: 0,
@@ -13755,12 +13807,13 @@ const getNodePositions = ({ containerWidth }) => {
13755
13807
  return positions;
13756
13808
  };
13757
13809
 
13758
- const { nodeWidth } = nodeConfig;
13810
+ const { nodeWidth, nodeHeight, framePadding } = nodeConfig;
13759
13811
  const mapToNodeData = (entity) => {
13760
13812
  const { hasDisableds, priorotizedStatus } = getConditionsBooleans(entity.conditions || []);
13761
13813
  const { icon, iconSrc } = getDestinationIcon(entity.destinationType.type);
13762
13814
  return {
13763
13815
  nodeWidth,
13816
+ nodeHeight, // for edged node
13764
13817
  id: entity.id,
13765
13818
  type: EntityTypes.Destination,
13766
13819
  status: priorotizedStatus,
@@ -13773,7 +13826,7 @@ const mapToNodeData = (entity) => {
13773
13826
  raw: entity,
13774
13827
  };
13775
13828
  };
13776
- const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount }) => {
13829
+ const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }) => {
13777
13830
  const nodes = [];
13778
13831
  const position = positions[EntityTypes.Destination];
13779
13832
  nodes.push({
@@ -13792,13 +13845,38 @@ const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount }
13792
13845
  },
13793
13846
  });
13794
13847
  if (!!entities.length) {
13848
+ nodes.push({
13849
+ id: `${EntityTypes.Destination}-${NodeTypes.Scroll}`,
13850
+ type: NodeTypes.Scroll,
13851
+ position: {
13852
+ x: position['x'],
13853
+ y: position['y']() - framePadding,
13854
+ },
13855
+ style: {
13856
+ zIndex: 1,
13857
+ },
13858
+ data: {
13859
+ nodeWidth,
13860
+ nodeHeight: containerHeight - nodeHeight + framePadding * 2,
13861
+ items: entities.map((destination, idx) => ({
13862
+ id: `${EntityTypes.Destination}-${idx}`,
13863
+ data: mapToNodeData(destination),
13864
+ })),
13865
+ onScroll,
13866
+ },
13867
+ });
13795
13868
  entities.forEach((destination, idx) => {
13796
13869
  nodes.push({
13797
- id: `${EntityTypes.Destination}-${idx}`,
13798
- type: NodeTypes.Base,
13870
+ id: `${EntityTypes.Destination}-${idx}-hidden`,
13871
+ type: NodeTypes.Edged,
13872
+ extent: 'parent',
13873
+ parentId: `${EntityTypes.Destination}-${NodeTypes.Scroll}`,
13799
13874
  position: {
13800
- x: position['x'],
13801
- y: position['y'](idx),
13875
+ x: framePadding,
13876
+ y: position['y'](idx) - (nodeHeight - framePadding / 2),
13877
+ },
13878
+ style: {
13879
+ zIndex: -1,
13802
13880
  },
13803
13881
  data: mapToNodeData(destination),
13804
13882
  });
@@ -13890,28 +13968,34 @@ const DataFlow = ({ heightToRemove, metrics }) => {
13890
13968
  loading: destinationsLoading,
13891
13969
  unfilteredCount: destinationsByStream.length,
13892
13970
  positions,
13971
+ containerHeight,
13972
+ onScroll: ({ scrollTop }) => handleNodesScrolled(destinationNodes, EntityTypes.Destination, scrollTop),
13893
13973
  });
13894
13974
  handleNodesChanged(destinationNodes, EntityTypes.Destination);
13895
- }, [selectedStreamName, destinations, destinationsLoading, positions[EntityTypes.Destination], filters]);
13975
+ }, [selectedStreamName, destinations, destinationsLoading, positions[EntityTypes.Destination], filters, containerHeight]);
13896
13976
  useEffect(() => {
13897
13977
  const actionNodes = buildActionNodes({
13898
13978
  entities: filterActions(actions, filters),
13899
13979
  loading: actionsLoading,
13900
13980
  unfilteredCount: actions.length,
13901
13981
  positions,
13982
+ containerHeight,
13983
+ onScroll: ({ scrollTop }) => handleNodesScrolled(actionNodes, EntityTypes.Action, scrollTop),
13902
13984
  });
13903
13985
  handleNodesChanged(actionNodes, EntityTypes.Action);
13904
- }, [actions, actionsLoading, positions[EntityTypes.Action], filters]);
13986
+ }, [actions, actionsLoading, positions[EntityTypes.Action], filters, containerHeight]);
13905
13987
  useEffect(() => {
13906
- // note: rules do not have filters yet
13907
13988
  const ruleNodes = buildRuleNodes({
13989
+ // note: rules do not have filters yet
13908
13990
  entities: instrumentationRules,
13909
13991
  loading: instrumentationRulesLoading,
13910
13992
  unfilteredCount: instrumentationRules.length,
13911
13993
  positions,
13994
+ containerHeight,
13995
+ onScroll: ({ scrollTop }) => handleNodesScrolled(ruleNodes, EntityTypes.InstrumentationRule, scrollTop),
13912
13996
  });
13913
13997
  handleNodesChanged(ruleNodes, EntityTypes.InstrumentationRule);
13914
- }, [instrumentationRules, instrumentationRulesLoading, positions[EntityTypes.InstrumentationRule]]);
13998
+ }, [instrumentationRules, instrumentationRulesLoading, positions[EntityTypes.InstrumentationRule], containerHeight]);
13915
13999
  return (React.createElement(Container$e, { ref: containerRef, "$heightToRemove": heightToRemove },
13916
14000
  React.createElement(Flow, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange })));
13917
14001
  };
@@ -14082,6 +14166,7 @@ const Filters$1 = () => {
14082
14166
  const theme = Theme.useTheme();
14083
14167
  const { namespaces, sources } = useEntityStore();
14084
14168
  const { selectedStreamName } = useDataStreamStore();
14169
+ const { getItemSS, setItemSS, removeItemSS } = useSessionStorage();
14085
14170
  const { namespaces: namespaceFilters, kinds, monitors, languages, errors, onlyErrors, setAll, clearAll, getEmptyState } = useFilterStore();
14086
14171
  const sourcesByStream = useMemo(() => filterSourcesByStream(sources, selectedStreamName), [sources, selectedStreamName]);
14087
14172
  // We need local state, because we want to keep the filters in the store only when the user clicks on apply
@@ -14089,6 +14174,10 @@ const Filters$1 = () => {
14089
14174
  const [filterCount, setFilterCount] = useState(getFilterCount(filters));
14090
14175
  const [focused, setFocused] = useState(false);
14091
14176
  const toggleFocused = () => setFocused((prev) => !prev);
14177
+ useEffect(() => {
14178
+ const storedFilters = getItemSS(STORAGE_KEYS.OVERVIEW_FILTERS, getEmptyState());
14179
+ setAll(storedFilters);
14180
+ }, []);
14092
14181
  useEffect(() => {
14093
14182
  if (!focused) {
14094
14183
  const payload = { namespaces: namespaceFilters, kinds, monitors, languages, errors, onlyErrors };
@@ -14097,17 +14186,13 @@ const Filters$1 = () => {
14097
14186
  }
14098
14187
  }, [focused, namespaceFilters, kinds, monitors, errors, onlyErrors]);
14099
14188
  const onApply = () => {
14100
- // TODO: remove trycatch after debugging
14101
- try {
14102
- setAll(filters);
14103
- setFilterCount(getFilterCount(filters));
14104
- setFocused(false);
14105
- }
14106
- catch (error) {
14107
- console.error(error);
14108
- }
14189
+ setItemSS(STORAGE_KEYS.OVERVIEW_FILTERS, filters);
14190
+ setAll(filters);
14191
+ setFilterCount(getFilterCount(filters));
14192
+ setFocused(false);
14109
14193
  };
14110
14194
  const onReset = () => {
14195
+ removeItemSS(STORAGE_KEYS.OVERVIEW_FILTERS);
14111
14196
  clearAll();
14112
14197
  setFilters(getEmptyState());
14113
14198
  setFilterCount(0);
@@ -14397,8 +14482,15 @@ const TestConnection = ({ destination, disabled, validateForm, status, testConne
14397
14482
  if (validateForm()) {
14398
14483
  setLoading(true);
14399
14484
  const testResult = await testConnection(destination);
14485
+ // 1st if - check if we got a response (if undefined, then Apollo Client caught an error)
14400
14486
  if (testResult) {
14401
- testResult.succeeded ? onSuccess(testResult) : onError(testResult);
14487
+ // 2nd if - check if the test was successful or not
14488
+ if (testResult.succeeded) {
14489
+ onSuccess(testResult);
14490
+ }
14491
+ else {
14492
+ onError(testResult);
14493
+ }
14402
14494
  }
14403
14495
  setLoading(false);
14404
14496
  }
@@ -14418,8 +14510,11 @@ const NotesWrapper = styled.div `
14418
14510
  flex-direction: column;
14419
14511
  gap: 12px;
14420
14512
  `;
14513
+ const SignalsAndDocsWrapper = styled(FlexRow) `
14514
+ justify-content: space-between;
14515
+ `;
14421
14516
  const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validateForm, handleFormChange, dynamicFields, setDynamicFields, testConnection }) => {
14422
- const { supportedSignals, testConnectionSupported, displayName } = categoryItem || {};
14517
+ const { type, displayName, supportedSignals, testConnectionSupported } = categoryItem || {};
14423
14518
  const [autoFilled, setAutoFilled] = useState(false);
14424
14519
  const [isFormDirty, setIsFormDirty] = useState(false);
14425
14520
  const [connection, setConnection] = useState(undefined);
@@ -14443,10 +14538,6 @@ const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validat
14443
14538
  setAutoFilled(didAutoFill);
14444
14539
  }
14445
14540
  }, [dynamicFields, isFormDirty]);
14446
- const dirtyForm = () => {
14447
- setIsFormDirty(true);
14448
- setConnection(undefined);
14449
- };
14450
14541
  const supportedMonitors = useMemo(() => {
14451
14542
  const { logs, metrics, traces } = supportedSignals || {};
14452
14543
  const arr = [];
@@ -14468,7 +14559,12 @@ const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validat
14468
14559
  if (traces)
14469
14560
  arr.push(SignalType.Traces);
14470
14561
  return arr;
14471
- }, [formData['exportedSignals']]);
14562
+ }, [formData]);
14563
+ const dirtyForm = () => {
14564
+ setAutoFilled(false);
14565
+ setIsFormDirty(true);
14566
+ setConnection(undefined);
14567
+ };
14472
14568
  const handleSelectedSignals = (signals) => {
14473
14569
  dirtyForm();
14474
14570
  handleFormChange('exportedSignals', {
@@ -14495,12 +14591,14 @@ const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validat
14495
14591
  };
14496
14592
  return (React.createElement(Container$a, { "$gap": 24 },
14497
14593
  React.createElement(Container$a, { "$gap": 12 },
14498
- React.createElement(SectionTitle, { title: isUpdate ? 'Update destination' : 'Create destination', description: `Connect ${displayName} with Odigos.`, actionButton: testConnectionSupported && (React.createElement(TestConnection, { destination: formData, disabled: !isFormDirty, validateForm: validateForm, status: connection?.type, testConnection: testConnection, onError: onTestConnectionError, onSuccess: onTestConnectionSuccess })) }),
14594
+ React.createElement(SectionTitle, { title: isUpdate ? 'Update destination' : 'Create destination', description: `Connect ${displayName} with Odigos.`, actionButton: testConnectionSupported && (React.createElement(TestConnection, { destination: formData, disabled: !isFormDirty && !autoFilled, validateForm: validateForm, status: connection?.type, testConnection: testConnection, onError: onTestConnectionError, onSuccess: onTestConnectionSuccess })) }),
14499
14595
  React.createElement(NotesWrapper, null,
14500
14596
  testConnectionSupported && connection && React.createElement(NotificationNote, { type: connection.type, title: connection.title, message: connection.message }),
14501
14597
  autoFilled && !connection && !isUpdate && React.createElement(NotificationNote, { type: StatusType.Default, message: `Odigos autocompleted ${displayName} destination details.` })),
14502
14598
  React.createElement(Divider, null)),
14503
- React.createElement(MonitorsCheckboxes, { title: isUpdate ? '' : 'This connection will monitor:', required: true, allowedSignals: supportedMonitors, selectedSignals: selectedMonitors, setSelectedSignals: handleSelectedSignals, errorMessage: formErrors['exportedSignals'] }),
14599
+ React.createElement(SignalsAndDocsWrapper, null,
14600
+ React.createElement(MonitorsCheckboxes, { title: isUpdate ? '' : 'This connection will monitor:', required: true, allowedSignals: supportedMonitors, selectedSignals: selectedMonitors, setSelectedSignals: handleSelectedSignals, errorMessage: formErrors['exportedSignals'] }),
14601
+ !isUpdate && React.createElement(DocsButton, { endpoint: `/backends/${type}` })),
14504
14602
  !isUpdate && (React.createElement(Input, { title: 'Destination name', placeholder: 'Enter destination name', value: formData['name'], onChange: (e) => {
14505
14603
  dirtyForm();
14506
14604
  handleFormChange('name', e.target.value);
@@ -14600,7 +14698,7 @@ const ListsWrapper = styled.div `
14600
14698
  flex-direction: column;
14601
14699
  gap: 12px;
14602
14700
  `;
14603
- const DestinationsList = ({ items, onSelectOption, onSelectConfigured }) => {
14701
+ const DestinationsList = ({ items, onSelectNew, onSelectConfigured }) => {
14604
14702
  const { configuredDestinationsUpdateOnly } = useSetupStore();
14605
14703
  return items.map((category) => {
14606
14704
  const isAlreadyExisting = category.name === DESTINATION_CATEGORIES['EXISTS']['TITLE'];
@@ -14611,7 +14709,7 @@ const DestinationsList = ({ items, onSelectOption, onSelectConfigured }) => {
14611
14709
  const key = `select-${category.name.replaceAll(' ', '')}-destination-${item.type}`;
14612
14710
  const isChecked = item.selected || configuredDestinationsUpdateOnly.some((dest) => dest.id === item.id);
14613
14711
  const monitors = Object.keys(item.supportedSignals).filter((signal) => item.supportedSignals[signal].supported);
14614
- const onClick = isAlreadyExisting ? () => onSelectConfigured(item.id) : () => onSelectOption(item);
14712
+ const onClick = isAlreadyExisting ? () => onSelectConfigured(item.id) : () => onSelectNew(item);
14615
14713
  const { icon, iconSrc } = getDestinationIcon(item.type);
14616
14714
  return (React.createElement(DataTab, { key: key, "data-id": key, title: item.displayName, hoverText: BUTTON_TEXTS.SELECT, onClick: onClick, iconProps: { icon, iconSrc }, visualProps: { monitors, monitorsWithLabels: true }, checkboxProps: {
14617
14715
  withCheckbox: isAlreadyExisting,
@@ -14679,7 +14777,7 @@ const createConfiguredItems = (destinations, selectedStreamName, configuredDesti
14679
14777
  },
14680
14778
  };
14681
14779
  });
14682
- const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSelectOption, onSelectConfigured }) => {
14780
+ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSelectNew, onSelectConfigured }) => {
14683
14781
  const { destinations } = useEntityStore();
14684
14782
  const { selectedStreamName } = useDataStreamStore();
14685
14783
  const { configuredDestinations, configuredDestinationsUpdateOnly } = useSetupStore();
@@ -14712,7 +14810,7 @@ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSe
14712
14810
  return { ...category, items: filteredItems };
14713
14811
  })
14714
14812
  .filter(({ items }) => !!items.length); // Filter out empty categories
14715
- }, [categories, potentialDestinations, destinations, search, selectedCategory, selectedMonitors, selectedStreamName, configuredDestinations]);
14813
+ }, [categories, potentialDestinations, destinations, search, selectedCategory, selectedMonitors, selectedStreamName, configuredDestinations, configuredDestinationsUpdateOnly]);
14716
14814
  if (hidden)
14717
14815
  return null;
14718
14816
  return (React.createElement(Container$9, null,
@@ -14726,7 +14824,7 @@ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSe
14726
14824
  React.createElement(Divider, null),
14727
14825
  !filteredDestinations.length ? (React.createElement(NoDataFoundWrapper, null,
14728
14826
  React.createElement(NoDataFound, { title: 'No destinations found' }))) : (React.createElement(ListsContainer, null,
14729
- React.createElement(DestinationsList, { items: filteredDestinations, onSelectOption: onSelectOption, onSelectConfigured: onSelectConfigured })))));
14827
+ React.createElement(DestinationsList, { items: filteredDestinations, onSelectNew: (dest) => onSelectNew(dest, selectedMonitors), onSelectConfigured: onSelectConfigured })))));
14730
14828
  };
14731
14829
 
14732
14830
  const Container$8 = styled.div `
@@ -14810,10 +14908,17 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
14810
14908
  resetFormData();
14811
14909
  setSelectedItem(undefined);
14812
14910
  };
14813
- const handleSelectOption = (item) => {
14911
+ const handleSelectNew = (item, selectedMonitors) => {
14814
14912
  resetFormData();
14815
14913
  handleFormChange('type', item?.type || '');
14816
14914
  handleFormChange('currentStreamName', selectedStreamName);
14915
+ const exportedSignals = {
14916
+ logs: false,
14917
+ metrics: false,
14918
+ traces: false,
14919
+ };
14920
+ selectedMonitors.filter((monitor) => item.supportedSignals[monitor].supported).forEach((monitor) => (exportedSignals[monitor] = true));
14921
+ handleFormChange('exportedSignals', exportedSignals);
14817
14922
  setYamlFields(item?.fields || []);
14818
14923
  setSelectedItem(item);
14819
14924
  };
@@ -14859,7 +14964,7 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
14859
14964
  { stepNumber: 2, title: DISPLAY_TITLES.CONNECTION },
14860
14965
  ] })),
14861
14966
  React.createElement(ModalBody, { style: { margin: '32px 24px 12px 24px' } },
14862
- React.createElement(ChooseDestinationBody, { hidden: selectedItem !== undefined, categories: categories, potentialDestinations: potentialDestinations, onSelectOption: handleSelectOption, onSelectConfigured: handleSelectConfigured }),
14967
+ React.createElement(ChooseDestinationBody, { hidden: selectedItem !== undefined, categories: categories, potentialDestinations: potentialDestinations, onSelectNew: handleSelectNew, onSelectConfigured: handleSelectConfigured }),
14863
14968
  selectedItem && (React.createElement(DestinationForm, { categoryItem: selectedItem, formData: formData, formErrors: formErrors, handleFormChange: handleFormChange, dynamicFields: dynamicFields, setDynamicFields: setDynamicFields, validateForm: validateForm, testConnection: testConnection }))))));
14864
14969
  };
14865
14970
 
@@ -15975,6 +16080,11 @@ const buildCard = (source) => {
15975
16080
  { title: DISPLAY_TITLES.NAMESPACE, value: namespace },
15976
16081
  { title: DISPLAY_TITLES.KIND, value: kind },
15977
16082
  { title: DISPLAY_TITLES.NAME, value: name, tooltip: 'K8s resource name' },
16083
+ { type: DataCardFieldTypes.Divider },
16084
+ {
16085
+ type: DataCardFieldTypes.CopyText,
16086
+ value: `kubectl get ${kind} ${name} -n ${namespace}`,
16087
+ },
15978
16088
  ];
15979
16089
  return arr;
15980
16090
  };
@@ -16026,12 +16136,27 @@ const SourceDrawer = ({ persistSources, updateSource, fetchDescribeSource }) =>
16026
16136
  loadFormWithDrawerItem(found);
16027
16137
  return found;
16028
16138
  }, [isOpen, drawerEntityId, sourcesByStream]);
16139
+ const containersData = useMemo(() => {
16140
+ const isDisabled = thisItem?.conditions?.some(({ status }) => status === OtherStatus.Disabled);
16141
+ const runtimeCondition = thisItem?.conditions?.find(({ type }) => type === 'RuntimeDetection');
16142
+ const mappedContainers = thisItem?.containers?.map((container) => {
16143
+ const value = {
16144
+ ...container,
16145
+ isDisabled,
16146
+ };
16147
+ return {
16148
+ type: DataCardFieldTypes.SourceContainer,
16149
+ value: JSON.stringify(value),
16150
+ };
16151
+ }) || [];
16152
+ return {
16153
+ description: runtimeCondition?.message,
16154
+ isLoading: runtimeCondition?.status === OtherStatus.Loading,
16155
+ items: mappedContainers,
16156
+ };
16157
+ }, [thisItem]);
16029
16158
  if (!thisItem)
16030
16159
  return null;
16031
- const containersData = thisItem.containers?.map((container) => ({
16032
- type: DataCardFieldTypes.SourceContainer,
16033
- value: JSON.stringify(container),
16034
- })) || [];
16035
16160
  const handleEdit = (bool) => {
16036
16161
  setIsEditing(typeof bool === 'boolean' ? bool : true);
16037
16162
  };
@@ -16075,7 +16200,7 @@ const SourceDrawer = ({ persistSources, updateSource, fetchDescribeSource }) =>
16075
16200
  } }))) : (React.createElement(DataContainer$1, null,
16076
16201
  React.createElement(ConditionDetails, { conditions: thisItem.conditions || [] }),
16077
16202
  React.createElement(DataCard, { title: DISPLAY_TITLES.SOURCE_DETAILS, data: !!thisItem ? buildCard(thisItem) : [] }),
16078
- React.createElement(DataCard, { title: DISPLAY_TITLES.DETECTED_CONTAINERS, titleBadge: containersData.length, description: DISPLAY_TITLES.DETECTED_CONTAINERS_DESCRIPTION, data: containersData })))) : (React.createElement(Describe$1, { source: thisItem, fetchDescribeSource: fetchDescribeSource }))));
16203
+ React.createElement(DataCard, { title: DISPLAY_TITLES.DETECTED_CONTAINERS, titleBadge: containersData.isLoading ? OtherStatus.Loading : containersData.items.length, description: containersData.description || DISPLAY_TITLES.DETECTED_CONTAINERS_DESCRIPTION, data: containersData.items })))) : (React.createElement(Describe$1, { source: thisItem, fetchDescribeSource: fetchDescribeSource }))));
16079
16204
  };
16080
16205
 
16081
16206
  const ActionsRow = styled(FlexRow) `