@odigos/ui-kit 0.0.33 → 0.0.35

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 (59) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/eslint.config.mjs +17 -0
  3. package/lib/components/data-card/index.d.ts +2 -1
  4. package/lib/components/dropdown/index.d.ts +1 -0
  5. package/lib/components/input/index.d.ts +1 -1
  6. package/lib/components/input-table/index.d.ts +3 -11
  7. package/lib/components/input-table/map-columns-to-fields/index.d.ts +15 -0
  8. package/lib/components/input-table/types.d.ts +15 -0
  9. package/lib/components.js +9 -10
  10. package/lib/constants/strings/index.d.ts +6 -0
  11. package/lib/constants.js +1 -2
  12. package/lib/containers/action-form/custom-fields/add-cluster-info.d.ts +1 -1
  13. package/lib/containers/action-form/custom-fields/delete-attributes.d.ts +1 -1
  14. package/lib/containers/action-form/custom-fields/error-sampler.d.ts +1 -1
  15. package/lib/containers/action-form/custom-fields/k8s-attributes.d.ts +1 -1
  16. package/lib/containers/action-form/custom-fields/latency-sampler.d.ts +1 -1
  17. package/lib/containers/action-form/custom-fields/pii-masking.d.ts +1 -1
  18. package/lib/containers/action-form/custom-fields/probabilistic-sampler.d.ts +1 -1
  19. package/lib/containers/action-form/custom-fields/rename-attributes.d.ts +1 -1
  20. package/lib/containers/action-form/custom-fields/service-name-sampler.d.ts +5 -0
  21. package/lib/containers/action-form/custom-fields/span-attribute-sampler.d.ts +5 -0
  22. package/lib/containers/data-flow/helpers/build-action-nodes.d.ts +7 -1
  23. package/lib/containers/data-flow/helpers/build-destination-nodes.d.ts +7 -1
  24. package/lib/containers/data-flow/helpers/build-rule-nodes.d.ts +7 -1
  25. package/lib/containers/destination-modal/choose-destination/destinations-list/index.d.ts +1 -1
  26. package/lib/containers/destination-modal/choose-destination/index.d.ts +2 -2
  27. package/lib/containers/instrumentation-rule-drawer/build-card.d.ts +1 -1
  28. package/lib/containers.js +515 -201
  29. package/lib/functions/get-action-icon/index.d.ts +2 -2
  30. package/lib/functions/index.d.ts +1 -0
  31. package/lib/functions/numbers-only/index.d.ts +1 -0
  32. package/lib/functions.js +6 -7
  33. package/lib/hooks/index.d.ts +1 -0
  34. package/lib/hooks/useSessionStorage.d.ts +5 -0
  35. package/lib/hooks.js +4 -5
  36. package/lib/icons.js +7 -7
  37. package/lib/{index-1N9wymEq.js → index-9R2N835W.js} +1 -1
  38. package/lib/{index-f8FRaVkE.js → index-BDqd3uNm.js} +1 -1
  39. package/lib/{index-Do3CYz7N.js → index-BVj4fOL3.js} +1 -1
  40. package/lib/{index-CnZlllYu.js → index-BlZKWuxe.js} +7 -1
  41. package/lib/{index-B_Gl6Qa6.js → index-CCX1HLUr.js} +9 -3
  42. package/lib/{index-CNfdJ1X8.js → index-CEWs8CTN.js} +1 -1
  43. package/lib/{index-CVH8Q8Sl.js → index-CKOBXat_.js} +360 -237
  44. package/lib/{index-CaAOgaiC.js → index-CyG_tD3y.js} +2 -2
  45. package/lib/{index-BjVl4-os.js → index-DmCjUtBQ.js} +4 -5
  46. package/lib/{index-BQQZyvRz.js → index-DqaI44fJ.js} +1 -1
  47. package/lib/{index-BedCNcwV.js → index-THrvNIPj.js} +112 -64
  48. package/lib/{index-Iq7U_fzb.js → index-dLZvpGw3.js} +5 -12
  49. package/lib/mock-data/sources/index.d.ts +2 -0
  50. package/lib/snippets.js +8 -9
  51. package/lib/store.js +1 -1
  52. package/lib/theme.js +1 -1
  53. package/lib/types/actions/index.d.ts +137 -41
  54. package/lib/types/common/index.d.ts +10 -16
  55. package/lib/types.js +85 -20
  56. package/lib/{useSourceSelectionFormData-DiwzViqL.js → useSourceSelectionFormData-DqSNROtZ.js} +73 -37
  57. package/lib/{useTransition-B0eagOib.js → useTransition-D9f1CP9n.js} +1 -1
  58. package/package.json +20 -23
  59. package/lib/index-mOgS3e5E.js +0 -101
package/lib/containers.js CHANGED
@@ -1,27 +1,26 @@
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-CVH8Q8Sl.js';
4
- import { a as DISPLAY_TITLES, B as BUTTON_TEXTS, F as FORM_ALERTS } from './index-mOgS3e5E.js';
5
- import { ActionType, EntityTypes, StatusType, Crud, OtherStatus, NodeTypes, AddNodeTypes, EdgeTypes, FieldTypes, SignalType, CodeAttributesKeyTypes, HeadersCollectionKeyTypes, 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-BedCNcwV.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-CKOBXat_.js';
4
+ import { ActionType, ActionKeyTypes, InputTypes, FieldTypes, EntityTypes, StatusType, Crud, OtherStatus, NodeTypes, AddNodeTypes, EdgeTypes, SignalType, HeadersCollectionKeyTypes, CodeAttributesKeyTypes, PayloadCollectionKeyTypes, InstrumentationRuleType } from './types.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-THrvNIPj.js';
7
6
  import { i as isEmpty, s as safeJsonParse } from './index-BV85P9UP.js';
8
- import { i as CheckCircledIcon, O as OdigosLogo } from './index-Do3CYz7N.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-f8FRaVkE.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-DiwzViqL.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-B0eagOib.js';
12
- import { E as EditIcon } from './index-BQQZyvRz.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-CNfdJ1X8.js';
14
- import { D as DeleteWarning, C as CancelWarning } from './index-CaAOgaiC.js';
15
- import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-B_Gl6Qa6.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-Iq7U_fzb.js';
7
+ import { i as CheckCircledIcon, O as OdigosLogo } from './index-BVj4fOL3.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-BDqd3uNm.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-DqSNROtZ.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-D9f1CP9n.js';
11
+ import { E as EditIcon } from './index-DqaI44fJ.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-CEWs8CTN.js';
13
+ import { D as DeleteWarning, C as CancelWarning } from './index-CyG_tD3y.js';
14
+ import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-CCX1HLUr.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-dLZvpGw3.js';
17
16
  import { createPortal } from 'react-dom';
18
- import { N as NoteBackToSummary, E as EditButton } from './index-BjVl4-os.js';
17
+ import { m as mapExportedSignals } from './index-BlZKWuxe.js';
18
+ import { N as NoteBackToSummary, E as EditButton } from './index-DmCjUtBQ.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-1N9wymEq.js';
21
- import './index-CnZlllYu.js';
20
+ import { a6 as RulesIcon, a7 as SourcesIcon, a3 as ActionsIcon, a4 as DestinationsIcon } from './index-9R2N835W.js';
22
21
 
23
22
  const buildCard$3 = (action) => {
24
- const { type, spec: { actionName, notes, signals, disabled, collectContainerAttributes, collectReplicaSetAttributes, collectWorkloadId, collectClusterId, labelsAttributes, annotationsAttributes, clusterAttributes, attributeNamesToDelete, renames, piiCategories, fallbackSamplingRatio, samplingPercentage, endpointsFilters, }, } = action;
23
+ const { type, spec: { actionName, notes, signals, disabled, collectContainerAttributes, collectReplicaSetAttributes, collectWorkloadId, collectClusterId, labelsAttributes, annotationsAttributes, clusterAttributes, attributeNamesToDelete, renames, piiCategories, fallbackSamplingRatio, samplingPercentage, endpointsFilters, servicesNameFilters, attributeFilters, }, } = action;
25
24
  const arr = [
26
25
  { title: DISPLAY_TITLES.TYPE, value: type },
27
26
  { type: DataCardFieldTypes.ActiveStatus, title: DISPLAY_TITLES.STATUS, value: String(!disabled) },
@@ -101,14 +100,39 @@ const buildCard$3 = (action) => {
101
100
  str += `Service Name: ${serviceName}\n`;
102
101
  str += `HTTP Route: ${httpRoute}\n`;
103
102
  str += `Min. Latency: ${minimumLatencyThreshold}\n`;
104
- str += `Sampling Ratio: ${fallbackSamplingRatio}`;
103
+ str += `Fallback Sampling Ratio: ${fallbackSamplingRatio}`;
105
104
  arr.push({ title: `Endpoint${endpointsFilters.length > 1 ? ` #${idx + 1}` : ''}`, value: str });
106
105
  });
107
106
  }
107
+ if (type === ActionType.ServiceNameSampler) {
108
+ servicesNameFilters?.forEach(({ serviceName, samplingRatio, fallbackSamplingRatio }, idx) => {
109
+ let str = '';
110
+ str += `Service Name: ${serviceName}\n`;
111
+ str += `Sampling Ratio: ${samplingRatio}\n`;
112
+ str += `Fallback Sampling Ratio: ${fallbackSamplingRatio}`;
113
+ arr.push({ title: `Filter${servicesNameFilters.length > 1 ? ` #${idx + 1}` : ''}`, value: str });
114
+ });
115
+ }
116
+ if (type === ActionType.SpanAttributeSampler) {
117
+ attributeFilters?.forEach(({ serviceName, attributeKey, fallbackSamplingRatio, condition }, idx) => {
118
+ let str = '';
119
+ str += `Service Name: ${serviceName}\n`;
120
+ str += `Attribute Key: ${attributeKey}\n`;
121
+ str += `Fallback Sampling Ratio: ${fallbackSamplingRatio}\n`;
122
+ const conditionKey = Object.keys(condition)[0];
123
+ str += `Condition: ${conditionKey}\n`;
124
+ str += `Operation: ${condition[conditionKey]?.operation}\n`;
125
+ str += `Expected Value: ${condition[conditionKey]?.expectedValue}`;
126
+ if (conditionKey === 'jsonCondition') {
127
+ str += `\nJSON Path: ${condition[conditionKey].jsonPath}`;
128
+ }
129
+ arr.push({ title: `Filter${attributeFilters.length > 1 ? ` #${idx + 1}` : ''}`, value: str });
130
+ });
131
+ }
108
132
  return arr;
109
133
  };
110
134
 
111
- const KEY$6 = 'piiCategories';
135
+ const KEY$8 = ActionKeyTypes.PiiCategories;
112
136
  const ListContainer$2 = styled.div `
113
137
  display: flex;
114
138
  flex-direction: row;
@@ -127,18 +151,18 @@ const PII_OPTIONS = [
127
151
  },
128
152
  ];
129
153
  const PiiMasking = ({ value, setValue, formErrors }) => {
130
- const errorMessage = formErrors[KEY$6];
131
- const mappedValue = value[KEY$6] || [];
154
+ const errorMessage = formErrors[KEY$8];
155
+ const mappedValue = value[KEY$8] || [];
132
156
  const [isLastSelection, setIsLastSelection] = useState(mappedValue.length === 1);
133
157
  const handleChange = (id, isAdd) => {
134
158
  const arr = isAdd ? [...mappedValue, id] : mappedValue.filter((str) => str !== id);
135
- setValue(KEY$6, arr);
159
+ setValue(KEY$8, arr);
136
160
  setIsLastSelection(arr.length === 1);
137
161
  };
138
162
  useEffect(() => {
139
163
  if (!mappedValue.length) {
140
164
  const arr = PII_OPTIONS.map(({ id }) => id);
141
- setValue(KEY$6, arr);
165
+ setValue(KEY$8, arr);
142
166
  setIsLastSelection(PII_OPTIONS.length === 1);
143
167
  }
144
168
  // eslint-disable-next-line
@@ -149,140 +173,316 @@ const PiiMasking = ({ value, setValue, formErrors }) => {
149
173
  !!errorMessage && React.createElement(FieldError, null, errorMessage)));
150
174
  };
151
175
 
152
- const KEY$5 = 'fallbackSamplingRatio', MIN$1 = 0, MAX$1 = 100;
176
+ const KEY$7 = ActionKeyTypes.FallbackSamplingRatio, MIN$1 = 0, MAX$1 = 100;
153
177
  const ErrorSampler = ({ value, setValue, formErrors }) => {
154
- const errorMessage = formErrors[KEY$5];
155
- const mappedValue = value[KEY$5];
156
- const handleChange = (val) => setValue(KEY$5, Math.max(MIN$1, Math.min(Number(val), MAX$1)) || MIN$1);
157
- return (React.createElement(Input, { title: 'Fallback sampling ratio', required: true, type: 'number', min: MIN$1, max: MAX$1, value: !isEmpty(mappedValue) ? String(mappedValue) : '', onChange: ({ target: { value: v } }) => handleChange(v), errorMessage: errorMessage }));
178
+ const errorMessage = formErrors[KEY$7];
179
+ const mappedValue = value[KEY$7];
180
+ const handleChange = (val) => setValue(KEY$7, Math.max(MIN$1, Math.min(Number(val), MAX$1)) || MIN$1);
181
+ return (React.createElement(Input, { title: 'Fallback sampling ratio', required: true, type: InputTypes.Number, min: MIN$1, max: MAX$1, value: !isEmpty(mappedValue) ? String(mappedValue) : '', onChange: ({ target: { value: v } }) => handleChange(v), errorMessage: errorMessage }));
158
182
  };
159
183
 
184
+ const LABEL_COLUMNS = [
185
+ {
186
+ title: 'Label Key',
187
+ keyName: 'labelKey',
188
+ placeholder: 'app.kubernetes.io/name',
189
+ required: true,
190
+ },
191
+ {
192
+ title: 'Attribute Key',
193
+ keyName: 'attributeKey',
194
+ placeholder: 'app.kubernetes.name',
195
+ required: true,
196
+ },
197
+ ];
198
+ const ANNOTATION_COLUMNS = [
199
+ {
200
+ title: 'Annotation Key',
201
+ keyName: 'annotationKey',
202
+ placeholder: 'kubectl.kubernetes.io/restartedAt',
203
+ required: true,
204
+ },
205
+ {
206
+ title: 'Attribute Key',
207
+ keyName: 'attributeKey',
208
+ placeholder: 'kubectl.kubernetes.restartedAt',
209
+ required: true,
210
+ },
211
+ ];
160
212
  const K8sAttributes = ({ value, setValue, formErrors }) => {
161
213
  useEffect(() => {
162
- if (!value.collectContainerAttributes && !value.collectWorkloadId && !value.collectReplicaSetAttributes && !value.collectClusterId && !value.labelsAttributes?.length && !value.annotationsAttributes?.length) {
163
- setValue('collectContainerAttributes', true);
164
- setValue('collectReplicaSetAttributes', true);
165
- setValue('collectWorkloadId', true);
166
- setValue('collectClusterId', true);
167
- setValue('labelsAttributes', []);
168
- setValue('annotationsAttributes', []);
214
+ if (!value[ActionKeyTypes.CollectContainerAttributes] &&
215
+ !value[ActionKeyTypes.CollectReplicaSetAttributes] &&
216
+ !value[ActionKeyTypes.CollectWorkloadId] &&
217
+ !value[ActionKeyTypes.CollectClusterId] &&
218
+ !value[ActionKeyTypes.LabelsAttributes]?.length &&
219
+ !value[ActionKeyTypes.AnnotationsAttributes]?.length) {
220
+ setValue(ActionKeyTypes.CollectContainerAttributes, true);
221
+ setValue(ActionKeyTypes.CollectReplicaSetAttributes, true);
222
+ setValue(ActionKeyTypes.CollectWorkloadId, true);
223
+ setValue(ActionKeyTypes.CollectClusterId, true);
224
+ setValue(ActionKeyTypes.LabelsAttributes, []);
225
+ setValue(ActionKeyTypes.AnnotationsAttributes, []);
169
226
  }
170
227
  // eslint-disable-next-line
171
228
  }, []);
172
229
  return (React.createElement(React.Fragment, null,
173
- React.createElement(Checkbox, { title: 'Collect Container Attributes', value: value['collectContainerAttributes'] || false, onChange: (bool) => setValue('collectContainerAttributes', bool), errorMessage: formErrors['collectContainerAttributes'] }),
174
- React.createElement(Checkbox, { title: 'Collect ReplicaSet Attributes', value: value['collectReplicaSetAttributes'] || false, onChange: (bool) => setValue('collectReplicaSetAttributes', bool), errorMessage: formErrors['collectReplicaSetAttributes'] }),
175
- React.createElement(Checkbox, { title: 'Collect Workload ID', value: value['collectWorkloadId'] || false, onChange: (bool) => setValue('collectWorkloadId', bool), errorMessage: formErrors['collectWorkloadId'] }),
176
- React.createElement(Checkbox, { title: 'Collect Cluster ID', value: value['collectClusterId'] || false, onChange: (bool) => setValue('collectClusterId', bool), errorMessage: formErrors['collectClusterId'] }),
177
- React.createElement(InputTable, { columns: [
178
- {
179
- title: 'Label Key',
180
- keyName: 'labelKey',
181
- placeholder: 'app.kubernetes.io/name',
182
- required: true,
183
- },
184
- {
185
- title: 'Attribute Key',
186
- keyName: 'attributeKey',
187
- placeholder: 'app.kubernetes.name',
188
- required: true,
189
- },
190
- ], value: value['labelsAttributes'] || [], onChange: (arr) => setValue('labelsAttributes', arr), errorMessage: formErrors['labelsAttributes'] }),
191
- React.createElement(InputTable, { columns: [
192
- {
193
- title: 'Annotation Key',
194
- keyName: 'annotationKey',
195
- placeholder: 'kubectl.kubernetes.io/restartedAt',
196
- required: true,
197
- },
198
- {
199
- title: 'Attribute Key',
200
- keyName: 'attributeKey',
201
- placeholder: 'kubectl.kubernetes.restartedAt',
202
- required: true,
203
- },
204
- ], value: value['annotationsAttributes'] || [], onChange: (arr) => setValue('annotationsAttributes', arr), errorMessage: formErrors['annotationsAttributes'] })));
230
+ React.createElement(Checkbox, { title: 'Collect Container Attributes', value: value[ActionKeyTypes.CollectContainerAttributes] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectContainerAttributes, bool), errorMessage: formErrors[ActionKeyTypes.CollectContainerAttributes] }),
231
+ React.createElement(Checkbox, { title: 'Collect ReplicaSet Attributes', value: value[ActionKeyTypes.CollectReplicaSetAttributes] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectReplicaSetAttributes, bool), errorMessage: formErrors[ActionKeyTypes.CollectReplicaSetAttributes] }),
232
+ React.createElement(Checkbox, { title: 'Collect Workload ID', value: value[ActionKeyTypes.CollectWorkloadId] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectWorkloadId, bool), errorMessage: formErrors[ActionKeyTypes.CollectWorkloadId] }),
233
+ React.createElement(Checkbox, { title: 'Collect Cluster ID', value: value[ActionKeyTypes.CollectClusterId] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectClusterId, bool), errorMessage: formErrors[ActionKeyTypes.CollectClusterId] }),
234
+ React.createElement(InputTable, { columns: LABEL_COLUMNS, value: value[ActionKeyTypes.LabelsAttributes] || [], onChange: (arr) => setValue(ActionKeyTypes.LabelsAttributes, arr), errorMessage: formErrors[ActionKeyTypes.LabelsAttributes] }),
235
+ React.createElement(InputTable, { columns: ANNOTATION_COLUMNS, value: value[ActionKeyTypes.AnnotationsAttributes] || [], onChange: (arr) => setValue(ActionKeyTypes.AnnotationsAttributes, arr), errorMessage: formErrors[ActionKeyTypes.AnnotationsAttributes] })));
205
236
  };
206
237
 
207
- const KEY$4 = 'endpointsFilters';
238
+ const KEY$6 = ActionKeyTypes.EndpointsFilters;
239
+ const COLUMNS$2 = [
240
+ {
241
+ title: 'Service',
242
+ keyName: 'serviceName',
243
+ placeholder: 'e.g. my-service',
244
+ tooltip: 'Service name: The rule applies to a specific service name. Only traces originating from this service’s root span will be considered.',
245
+ required: true,
246
+ },
247
+ {
248
+ title: 'HTTP route',
249
+ keyName: 'httpRoute',
250
+ placeholder: 'e.g. /api/v1/users',
251
+ tooltip: 'HTTP route: The specific HTTP route prefix to match for sampling. Only traces with routes beginning with this prefix will be considered. For instance, configuring /buy will also match /buy/product.',
252
+ required: true,
253
+ },
254
+ {
255
+ title: 'Threshold',
256
+ keyName: 'minimumLatencyThreshold',
257
+ placeholder: 'e.g. 1000',
258
+ tooltip: 'Minimum latency threshold (ms): Specifies the minimum latency in milliseconds; traces with latency below this threshold are ignored.',
259
+ required: true,
260
+ type: InputTypes.Number,
261
+ },
262
+ {
263
+ title: 'Fallback',
264
+ keyName: 'fallbackSamplingRatio',
265
+ placeholder: 'e.g. 100',
266
+ tooltip: 'Fallback sampling ratio: Specifies the percentage of traces that meet the service/http_route filter but fall below the threshold that you still want to retain. For example, if a rule is set for service A and http_route B with a minimum latency threshold of 1 second, you might still want to keep some traces below this threshold. Setting the ratio to 20% ensures that 20% of these traces will be retained.',
267
+ required: true,
268
+ type: InputTypes.Number,
269
+ },
270
+ ];
208
271
  const LatencySampler = ({ value, setValue, formErrors }) => {
209
- const errorMessage = formErrors[KEY$4];
210
- const mappedValue = value[KEY$4] || [];
211
- const handleChange = (arr) => setValue(KEY$4, arr);
212
- return (React.createElement(InputTable, { columns: [
213
- {
214
- title: 'Service',
215
- keyName: 'serviceName',
216
- placeholder: 'Choose service',
217
- required: true,
218
- tooltip: 'Service name: The rule applies to a specific service name. Only traces originating from this service’s root span will be considered.',
219
- },
220
- {
221
- title: 'HTTP route',
222
- keyName: 'httpRoute',
223
- placeholder: 'e.g. /api/v1/users',
224
- required: true,
225
- tooltip: 'HTTP route: The specific HTTP route prefix to match for sampling. Only traces with routes beginning with this prefix will be considered. For instance, configuring /buy will also match /buy/product.',
226
- },
227
- {
228
- title: 'Threshold',
229
- keyName: 'minimumLatencyThreshold',
230
- placeholder: 'e.g. 1000',
231
- required: true,
232
- type: 'number',
233
- tooltip: 'Minimum latency threshold (ms): Specifies the minimum latency in milliseconds; traces with latency below this threshold are ignored.',
234
- },
235
- {
236
- title: 'Fallback',
237
- keyName: 'fallbackSamplingRatio',
238
- placeholder: 'e.g. 20',
239
- required: true,
240
- type: 'number',
241
- tooltip: 'Fallback sampling ratio: Specifies the percentage of traces that meet the service/http_route filter but fall below the threshold that you still want to retain. For example, if a rule is set for service A and http_route B with a minimum latency threshold of 1 second, you might still want to keep some traces below this threshold. Setting the ratio to 20% ensures that 20% of these traces will be retained.',
242
- },
243
- ], value: mappedValue, onChange: handleChange, errorMessage: errorMessage }));
272
+ const errorMessage = formErrors[KEY$6];
273
+ const mappedValue = value[KEY$6] || [];
274
+ const handleChange = (arr) => {
275
+ const mapped = arr.map(({ serviceName, httpRoute, minimumLatencyThreshold, fallbackSamplingRatio }) => {
276
+ const row = {
277
+ serviceName,
278
+ httpRoute,
279
+ minimumLatencyThreshold: Number(minimumLatencyThreshold),
280
+ fallbackSamplingRatio: Number(fallbackSamplingRatio),
281
+ };
282
+ return row;
283
+ });
284
+ setValue(KEY$6, mapped);
285
+ };
286
+ return React.createElement(InputTable, { columns: COLUMNS$2, value: mappedValue, onChange: handleChange, errorMessage: errorMessage });
244
287
  };
245
288
 
246
- const KEY$3 = 'clusterAttributes';
289
+ const KEY$5 = ActionKeyTypes.ClusterAttributes;
247
290
  const AddClusterInfo = ({ value, setValue, formErrors }) => {
248
- const errorMessage = formErrors[KEY$3];
249
- const mappedValue = value[KEY$3]?.map((obj) => ({
291
+ const errorMessage = formErrors[KEY$5];
292
+ const mappedValue = value[KEY$5]?.map((obj) => ({
250
293
  key: obj.attributeName,
251
294
  value: obj.attributeStringValue,
252
295
  })) || [];
253
- const handleChange = (arr) => setValue(KEY$3, arr.map((obj) => ({
296
+ const handleChange = (arr) => setValue(KEY$5, arr.map((obj) => ({
254
297
  attributeName: obj.key,
255
298
  attributeStringValue: obj.value,
256
299
  })));
257
300
  return React.createElement(KeyValueInputsList, { title: 'Resource Attributes', value: mappedValue, onChange: handleChange, required: true, errorMessage: errorMessage });
258
301
  };
259
302
 
260
- const KEY$2 = 'attributeNamesToDelete';
303
+ const KEY$4 = ActionKeyTypes.AttributeNamesToDelete;
261
304
  const DeleteAttributes = ({ value, setValue, formErrors }) => {
262
- const errorMessage = formErrors[KEY$2];
263
- const mappedValue = value[KEY$2] || [];
264
- const handleChange = (arr) => setValue(KEY$2, arr);
305
+ const errorMessage = formErrors[KEY$4];
306
+ const mappedValue = value[KEY$4] || [];
307
+ const handleChange = (arr) => setValue(KEY$4, arr);
265
308
  return React.createElement(InputList, { title: 'Attributes to delete', value: mappedValue, onChange: handleChange, required: true, errorMessage: errorMessage });
266
309
  };
267
310
 
268
- const KEY$1 = 'renames';
311
+ const KEY$3 = ActionKeyTypes.Renames;
269
312
  const RenameAttributes = ({ value, setValue, formErrors }) => {
270
- const errorMessage = formErrors[KEY$1];
271
- const mappedValue = Object.entries(value[KEY$1] || {}).map(([k, v]) => ({ key: k, value: v }));
313
+ const errorMessage = formErrors[KEY$3];
314
+ const mappedValue = Object.entries(value[KEY$3] || {}).map(([k, v]) => ({ key: k, value: v }));
272
315
  const handleChange = (arr) => {
273
316
  const payload = {};
274
317
  arr.forEach((obj) => (payload[obj.key] = obj.value));
275
- setValue(KEY$1, payload);
318
+ setValue(KEY$3, payload);
276
319
  };
277
320
  return React.createElement(KeyValueInputsList, { title: 'Attributes to rename', value: mappedValue, onChange: handleChange, required: true, errorMessage: errorMessage });
278
321
  };
279
322
 
280
- const KEY = 'samplingPercentage', MIN = 0, MAX = 100;
323
+ const KEY$2 = ActionKeyTypes.ServicesNameFilters;
324
+ const COLUMNS$1 = [
325
+ {
326
+ title: 'Service Name',
327
+ keyName: 'serviceName',
328
+ placeholder: 'e.g. my-service',
329
+ tooltip: 'Specifies the service name to search within the trace (Across all available spans).',
330
+ required: true,
331
+ },
332
+ {
333
+ title: 'Sampling Ratio',
334
+ keyName: 'samplingRatio',
335
+ placeholder: 'e.g. 10',
336
+ tooltip: 'Specifies the sample rate for all traces.',
337
+ required: true,
338
+ type: InputTypes.Number,
339
+ },
340
+ {
341
+ title: 'Fallback Sampling Ratio',
342
+ keyName: 'fallbackSamplingRatio',
343
+ placeholder: 'e.g. 100',
344
+ tooltip: 'Specifies the percentage of traces that don’t meet the service name filter and that you still like to retain.',
345
+ required: true,
346
+ type: InputTypes.Number,
347
+ },
348
+ ];
349
+ const ServiceNameSampler = ({ value, setValue, formErrors }) => {
350
+ const errorMessage = formErrors[KEY$2];
351
+ const mappedValue = value[KEY$2] || [];
352
+ const handleChange = (arr) => {
353
+ const mapped = arr.map(({ serviceName, samplingRatio, fallbackSamplingRatio }) => {
354
+ const row = {
355
+ serviceName,
356
+ samplingRatio: Number(samplingRatio),
357
+ fallbackSamplingRatio: Number(fallbackSamplingRatio),
358
+ };
359
+ return row;
360
+ });
361
+ setValue(KEY$2, mapped);
362
+ };
363
+ return React.createElement(InputTable, { columns: COLUMNS$1, value: mappedValue, onChange: handleChange, errorMessage: errorMessage });
364
+ };
365
+
366
+ const KEY$1 = ActionKeyTypes.SamplingPercentage, MIN = 0, MAX = 100;
281
367
  const ProbabilisticSampler = ({ value, setValue, formErrors }) => {
368
+ const errorMessage = formErrors[KEY$1];
369
+ const mappedValue = value[KEY$1];
370
+ const handleChange = (val) => setValue(KEY$1, Math.max(MIN, Math.min(Number(val), MAX)) || MIN);
371
+ return (React.createElement(Input, { title: 'Sampling percentage', required: true, type: InputTypes.Number, min: MIN, max: MAX, value: !isEmpty(mappedValue) ? String(mappedValue) : '', onChange: ({ target: { value: v } }) => handleChange(v), errorMessage: errorMessage }));
372
+ };
373
+
374
+ const KEY = ActionKeyTypes.AttributeFilters;
375
+ const COLUMNS = [
376
+ {
377
+ title: 'Service Name',
378
+ keyName: 'serviceName',
379
+ placeholder: 'e.g. my-service',
380
+ tooltip: 'Specifies the service name to search within the trace (across all available spans).',
381
+ required: true,
382
+ },
383
+ {
384
+ title: 'Attribute Key',
385
+ keyName: 'attributeKey',
386
+ placeholder: 'e.g. http.request.method',
387
+ tooltip: 'Specifies the attribute key inside of the span.',
388
+ required: true,
389
+ },
390
+ {
391
+ title: 'Fallback Sampling Ratio',
392
+ keyName: 'fallbackSamplingRatio',
393
+ placeholder: 'e.g. 100',
394
+ tooltip: 'Specifies the percentage of traces that don’t meet the service name filter and that you still like to retain.',
395
+ required: true,
396
+ type: InputTypes.Number,
397
+ },
398
+ {
399
+ title: 'Condition',
400
+ keyName: 'condition',
401
+ tooltip: 'An object representing the filters for span attributes filters.',
402
+ required: true,
403
+ componentType: FieldTypes.Dropdown,
404
+ options: [
405
+ { id: 'stringCondition', value: 'String Condition' },
406
+ { id: 'numberCondition', value: 'Number Condition' },
407
+ { id: 'booleanCondition', value: 'Boolean Condition' },
408
+ { id: 'jsonCondition', value: 'JSON Condition' },
409
+ ],
410
+ },
411
+ {
412
+ title: 'Operation',
413
+ keyName: 'operation',
414
+ tooltip: 'Specifies the operation to run against the attribute.',
415
+ required: true,
416
+ componentType: FieldTypes.Dropdown,
417
+ options: [
418
+ { id: 'exists', value: 'Exists' },
419
+ { id: 'equals', value: 'Equals' },
420
+ { id: 'not_equals', value: 'Not Equals' },
421
+ { id: 'contains', value: 'Contains' },
422
+ { id: 'not_contains', value: 'Not Contains' },
423
+ { id: 'regex', value: 'Regex' },
424
+ { id: 'greater_than', value: 'Greater Than' },
425
+ { id: 'less_than', value: 'Less Than' },
426
+ { id: 'greater_than_or_equal', value: 'Greater Than Or Equal' },
427
+ { id: 'less_than_or_equal', value: 'Less Than Or Equal' },
428
+ { id: 'is_valid_json', value: 'Is Valid JSON' },
429
+ { id: 'is_invalid_json', value: 'Is Invalid JSON' },
430
+ { id: 'jsonpath_exists', value: 'JSON Path Exists' },
431
+ { id: 'key_equals', value: 'Key Equals' },
432
+ { id: 'key_not_equals', value: 'Key Not Equals' },
433
+ ],
434
+ },
435
+ {
436
+ title: 'Expected Value',
437
+ keyName: 'expectedValue',
438
+ placeholder: 'e.g. GET',
439
+ tooltip: 'The values to test the attribute against.',
440
+ required: true,
441
+ },
442
+ {
443
+ title: 'JSON Path',
444
+ keyName: 'jsonPath',
445
+ placeholder: 'e.g. $.user.role',
446
+ tooltip: 'An expression used to navigate the JSON structure.',
447
+ required: false,
448
+ renderCondition: (row) => row.condition === 'jsonCondition',
449
+ },
450
+ ];
451
+ const SpanAttributeSampler = ({ value, setValue, formErrors }) => {
282
452
  const errorMessage = formErrors[KEY];
283
- const mappedValue = value[KEY];
284
- const handleChange = (val) => setValue(KEY, Math.max(MIN, Math.min(Number(val), MAX)) || MIN);
285
- return (React.createElement(Input, { title: 'Sampling percentage', required: true, type: 'number', min: MIN, max: MAX, value: !isEmpty(mappedValue) ? String(mappedValue) : '', onChange: ({ target: { value: v } }) => handleChange(v), errorMessage: errorMessage }));
453
+ const mappedValue = (value[KEY] || []).map(({ serviceName, attributeKey, fallbackSamplingRatio, condition }) => {
454
+ const conditionKey = Object.entries(condition).filter(([k, v]) => v)[0][0];
455
+ return {
456
+ serviceName,
457
+ attributeKey,
458
+ fallbackSamplingRatio,
459
+ condition: conditionKey,
460
+ operation: condition[conditionKey]?.operation,
461
+ expectedValue: condition[conditionKey]?.expectedValue,
462
+ jsonPath: condition[conditionKey]?.jsonPath,
463
+ };
464
+ });
465
+ const handleChange = (arr) => {
466
+ const mapped = arr.map(({ serviceName, attributeKey, fallbackSamplingRatio, condition, operation, expectedValue, jsonPath }) => {
467
+ const row = {
468
+ serviceName,
469
+ attributeKey,
470
+ fallbackSamplingRatio: Number(fallbackSamplingRatio),
471
+ condition: {
472
+ [condition]: {
473
+ operation,
474
+ expectedValue,
475
+ },
476
+ },
477
+ };
478
+ if (jsonPath) {
479
+ row.condition[condition].jsonPath = jsonPath;
480
+ }
481
+ return row;
482
+ });
483
+ setValue(KEY, mapped);
484
+ };
485
+ return React.createElement(InputTable, { columns: COLUMNS, value: mappedValue, onChange: handleChange, errorMessage: errorMessage, limitFieldsPerRow: 3 });
286
486
  };
287
487
 
288
488
  const componentsMap$1 = {
@@ -294,6 +494,8 @@ const componentsMap$1 = {
294
494
  [ActionType.ErrorSampler]: ErrorSampler,
295
495
  [ActionType.ProbabilisticSampler]: ProbabilisticSampler,
296
496
  [ActionType.LatencySampler]: LatencySampler,
497
+ [ActionType.ServiceNameSampler]: ServiceNameSampler,
498
+ [ActionType.SpanAttributeSampler]: SpanAttributeSampler,
297
499
  };
298
500
  const CustomFields$1 = ({ actionType, value, setValue, formErrors }) => {
299
501
  if (!actionType)
@@ -7115,8 +7317,8 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
7115
7317
  // from stays the same
7116
7318
  ...previousConnection,
7117
7319
  isValid,
7118
- to: closestHandle && isValid
7119
- ? rendererPointToPoint({ x: closestHandle.x, y: closestHandle.y }, transform)
7320
+ to: result.toHandle && isValid
7321
+ ? rendererPointToPoint({ x: result.toHandle.x, y: result.toHandle.y }, transform)
7120
7322
  : position,
7121
7323
  toHandle: result.toHandle,
7122
7324
  toPosition: isValid && result.toHandle ? result.toHandle.position : oppositePosition[fromHandle.position],
@@ -7216,7 +7418,7 @@ function isValidHandle(event, { handle, connectionMode, fromNodeId, fromHandleId
7216
7418
  ? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target')
7217
7419
  : handleNodeId !== fromNodeId || handleId !== fromHandleId);
7218
7420
  result.isValid = isValid && isValidConnection(connection);
7219
- result.toHandle = getHandle(handleNodeId, handleType, handleId, nodeLookup, connectionMode, false);
7421
+ result.toHandle = getHandle(handleNodeId, handleType, handleId, nodeLookup, connectionMode, true);
7220
7422
  }
7221
7423
  return result;
7222
7424
  }
@@ -9017,11 +9219,12 @@ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true
9017
9219
  return [[], []];
9018
9220
  }, [keyCode]);
9019
9221
  useEffect(() => {
9020
- const target = options?.target || defaultDoc;
9222
+ const target = options?.target ?? defaultDoc;
9223
+ const actInsideInputWithModifier = options?.actInsideInputWithModifier ?? true;
9021
9224
  if (keyCode !== null) {
9022
9225
  const downHandler = (event) => {
9023
9226
  modifierPressed.current = event.ctrlKey || event.metaKey || event.shiftKey || event.altKey;
9024
- const preventAction = (!modifierPressed.current || (modifierPressed.current && !options.actInsideInputWithModifier)) &&
9227
+ const preventAction = (!modifierPressed.current || (modifierPressed.current && !actInsideInputWithModifier)) &&
9025
9228
  isInputDOMNode(event);
9026
9229
  if (preventAction) {
9027
9230
  return false;
@@ -9806,7 +10009,6 @@ function useReactFlow() {
9806
10009
  }
9807
10010
 
9808
10011
  const selected = (item) => item.selected;
9809
- const deleteKeyOptions = { actInsideInputWithModifier: false };
9810
10012
  const win$1 = typeof window !== 'undefined' ? window : undefined;
9811
10013
  /**
9812
10014
  * Hook for handling global key events.
@@ -9816,7 +10018,7 @@ const win$1 = typeof window !== 'undefined' ? window : undefined;
9816
10018
  function useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode, }) {
9817
10019
  const store = useStoreApi();
9818
10020
  const { deleteElements } = useReactFlow();
9819
- const deleteKeyPressed = useKeyPress(deleteKeyCode, deleteKeyOptions);
10021
+ const deleteKeyPressed = useKeyPress(deleteKeyCode, { actInsideInputWithModifier: false });
9820
10022
  const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode, { target: win$1 });
9821
10023
  useEffect(() => {
9822
10024
  if (deleteKeyPressed) {
@@ -12943,7 +13145,7 @@ const nodeConfig = {
12943
13145
  framePadding: 12,
12944
13146
  };
12945
13147
 
12946
- const { framePadding: framePadding$3 } = nodeConfig;
13148
+ const { framePadding: framePadding$5 } = nodeConfig;
12947
13149
  const Container$h = styled.div `
12948
13150
  position: relative;
12949
13151
  z-index: 1;
@@ -12955,7 +13157,7 @@ const Container$h = styled.div `
12955
13157
  overflow-x: hidden;
12956
13158
  `;
12957
13159
  const BaseNodeWrapper = styled.div `
12958
- margin: ${framePadding$3}px 0;
13160
+ margin: ${framePadding$5}px 0;
12959
13161
  `;
12960
13162
  const BottomOverlay = styled.div `
12961
13163
  position: fixed;
@@ -13187,7 +13389,7 @@ const Flow = ({ nodes, edges, onNodesChange, onEdgesChange }) => {
13187
13389
  } })))));
13188
13390
  };
13189
13391
 
13190
- const { nodeHeight: nodeHeight$3, framePadding: framePadding$2 } = nodeConfig;
13392
+ const { nodeHeight: nodeHeight$5, framePadding: framePadding$4 } = nodeConfig;
13191
13393
  const createEdge = (edgeId, params) => {
13192
13394
  const { theme, label, isMultiTarget, isError, animated } = params || {};
13193
13395
  const [sourceNodeId, targetNodeId] = edgeId.split('-to-');
@@ -13208,8 +13410,8 @@ const buildEdges = ({ theme, nodes, metrics, containerHeight }) => {
13208
13410
  if (nodeType === NodeTypes.Edged && entityType === EntityTypes.Source) {
13209
13411
  const { namespace, name, kind } = entityId;
13210
13412
  const metric = metrics?.sources.find((m) => m.kind === kind && m.name === name && m.namespace === namespace);
13211
- const topLimit = -80 / 2 + framePadding$2;
13212
- const bottomLimit = Math.floor(containerHeight / nodeHeight$3) * nodeHeight$3 - (nodeHeight$3 / 2 + framePadding$2);
13413
+ const topLimit = -80 / 2 + framePadding$4;
13414
+ const bottomLimit = Math.floor(containerHeight / nodeHeight$5) * nodeHeight$5 - (nodeHeight$5 / 2 + framePadding$4);
13213
13415
  if (position.y >= topLimit && position.y <= bottomLimit) {
13214
13416
  edges.push(createEdge(`${nodeId}-to-${actionNodeId}`, {
13215
13417
  theme,
@@ -13234,7 +13436,7 @@ const buildEdges = ({ theme, nodes, metrics, containerHeight }) => {
13234
13436
  return edges;
13235
13437
  };
13236
13438
 
13237
- const { nodeWidth: nodeWidth$4 } = nodeConfig;
13439
+ const { nodeWidth: nodeWidth$4, nodeHeight: nodeHeight$4, framePadding: framePadding$3 } = nodeConfig;
13238
13440
  const mapToNodeData$3 = (entity) => {
13239
13441
  return {
13240
13442
  nodeWidth: nodeWidth$4,
@@ -13248,7 +13450,7 @@ const mapToNodeData$3 = (entity) => {
13248
13450
  raw: entity,
13249
13451
  };
13250
13452
  };
13251
- const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }) => {
13453
+ const buildRuleNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }) => {
13252
13454
  const nodes = [];
13253
13455
  const position = positions[EntityTypes.InstrumentationRule];
13254
13456
  nodes.push({
@@ -13267,13 +13469,38 @@ const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }) => {
13267
13469
  },
13268
13470
  });
13269
13471
  if (!!entities.length) {
13472
+ nodes.push({
13473
+ id: `${EntityTypes.InstrumentationRule}-${NodeTypes.Scroll}`,
13474
+ type: NodeTypes.Scroll,
13475
+ position: {
13476
+ x: position['x'],
13477
+ y: position['y']() - framePadding$3,
13478
+ },
13479
+ style: {
13480
+ zIndex: 1,
13481
+ },
13482
+ data: {
13483
+ nodeWidth: nodeWidth$4,
13484
+ nodeHeight: containerHeight - nodeHeight$4 + framePadding$3 * 2,
13485
+ items: entities.map((rule, idx) => ({
13486
+ id: `${EntityTypes.InstrumentationRule}-${idx}`,
13487
+ data: mapToNodeData$3(rule),
13488
+ })),
13489
+ onScroll,
13490
+ },
13491
+ });
13270
13492
  entities.forEach((rule, idx) => {
13271
13493
  nodes.push({
13272
- id: `${EntityTypes.InstrumentationRule}-${idx}`,
13273
- type: NodeTypes.Base,
13494
+ id: `${EntityTypes.InstrumentationRule}-${idx}-hidden`,
13495
+ type: NodeTypes.Edged,
13496
+ extent: 'parent',
13497
+ parentId: `${EntityTypes.InstrumentationRule}-${NodeTypes.Scroll}`,
13274
13498
  position: {
13275
- x: position['x'],
13276
- y: position['y'](idx),
13499
+ x: framePadding$3,
13500
+ y: position['y'](idx) - (nodeHeight$4 - framePadding$3 / 2),
13501
+ },
13502
+ style: {
13503
+ zIndex: -1,
13277
13504
  },
13278
13505
  data: mapToNodeData$3(rule),
13279
13506
  });
@@ -13311,7 +13538,7 @@ const buildRuleNodes = ({ loading, entities, positions, unfilteredCount }) => {
13311
13538
  return nodes;
13312
13539
  };
13313
13540
 
13314
- const { nodeWidth: nodeWidth$3, nodeHeight: nodeHeight$2, framePadding: framePadding$1 } = nodeConfig;
13541
+ const { nodeWidth: nodeWidth$3, nodeHeight: nodeHeight$3, framePadding: framePadding$2 } = nodeConfig;
13315
13542
  const mapToNodeData$2 = (entity) => {
13316
13543
  const { hasDisableds, priorotizedStatus } = getConditionsBooleans(entity.conditions || []);
13317
13544
  return {
@@ -13328,7 +13555,7 @@ const mapToNodeData$2 = (entity) => {
13328
13555
  raw: entity,
13329
13556
  };
13330
13557
  };
13331
- const buildActionNodes = ({ loading, entities, positions, unfilteredCount }) => {
13558
+ const buildActionNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }) => {
13332
13559
  const nodes = [];
13333
13560
  const position = positions[EntityTypes.Action];
13334
13561
  nodes.push({
@@ -13348,30 +13575,53 @@ const buildActionNodes = ({ loading, entities, positions, unfilteredCount }) =>
13348
13575
  });
13349
13576
  if (!!entities.length) {
13350
13577
  nodes.push({
13351
- id: `${EntityTypes.Action}-${NodeTypes.Frame}`,
13352
- type: NodeTypes.Frame,
13578
+ id: `${EntityTypes.Action}-${NodeTypes.Scroll}`,
13579
+ type: NodeTypes.Scroll,
13353
13580
  position: {
13354
- x: position['x'] - framePadding$1,
13355
- y: position['y']() - framePadding$1,
13581
+ x: position['x'],
13582
+ y: position['y']() - framePadding$2,
13583
+ },
13584
+ style: {
13585
+ zIndex: 1,
13356
13586
  },
13357
13587
  data: {
13358
- nodeWidth: nodeWidth$3 + 2 * framePadding$1,
13359
- nodeHeight: nodeHeight$2 * entities.length + framePadding$1,
13588
+ nodeWidth: nodeWidth$3,
13589
+ nodeHeight: containerHeight - nodeHeight$3 + framePadding$2 * 2,
13590
+ items: entities.map((action, idx) => ({
13591
+ id: `${EntityTypes.Action}-${idx}`,
13592
+ data: mapToNodeData$2(action),
13593
+ })),
13594
+ onScroll,
13360
13595
  },
13361
13596
  });
13362
13597
  entities.forEach((action, idx) => {
13363
13598
  nodes.push({
13364
- id: `${EntityTypes.Action}-${idx}`,
13365
- type: NodeTypes.Base,
13599
+ id: `${EntityTypes.Action}-${idx}-hidden`,
13600
+ type: NodeTypes.Edged,
13366
13601
  extent: 'parent',
13367
- parentId: `${EntityTypes.Action}-${NodeTypes.Frame}`,
13602
+ parentId: `${EntityTypes.Action}-${NodeTypes.Scroll}`,
13368
13603
  position: {
13369
- x: framePadding$1,
13370
- y: position['y'](idx) - (nodeHeight$2 - framePadding$1),
13604
+ x: framePadding$2,
13605
+ y: position['y'](idx) - (nodeHeight$3 - framePadding$2 / 2),
13606
+ },
13607
+ style: {
13608
+ zIndex: -1,
13371
13609
  },
13372
13610
  data: mapToNodeData$2(action),
13373
13611
  });
13374
13612
  });
13613
+ nodes.push({
13614
+ id: `${EntityTypes.Action}-${NodeTypes.Frame}`,
13615
+ type: NodeTypes.Frame,
13616
+ position: {
13617
+ x: position['x'] - framePadding$2,
13618
+ y: position['y']() - framePadding$2,
13619
+ },
13620
+ data: {
13621
+ nodeWidth: nodeWidth$3 + 2 * framePadding$2,
13622
+ nodeHeight: Math.min(containerHeight, nodeHeight$3 * entities.length + framePadding$2),
13623
+ },
13624
+ });
13375
13625
  }
13376
13626
  else if (loading) {
13377
13627
  nodes.push({
@@ -13405,12 +13655,12 @@ const buildActionNodes = ({ loading, entities, positions, unfilteredCount }) =>
13405
13655
  return nodes;
13406
13656
  };
13407
13657
 
13408
- const { nodeWidth: nodeWidth$2, nodeHeight: nodeHeight$1, framePadding } = nodeConfig;
13658
+ const { nodeWidth: nodeWidth$2, nodeHeight: nodeHeight$2, framePadding: framePadding$1 } = nodeConfig;
13409
13659
  const mapToNodeData$1 = (entity) => {
13410
13660
  const { priorotizedStatus, hasDisableds } = getConditionsBooleans(entity.conditions || []);
13411
13661
  return {
13412
13662
  nodeWidth: nodeWidth$2,
13413
- nodeHeight: nodeHeight$1, // for edged node
13663
+ nodeHeight: nodeHeight$2, // for edged node
13414
13664
  id: {
13415
13665
  namespace: entity.namespace,
13416
13666
  name: entity.name,
@@ -13452,14 +13702,14 @@ const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, conta
13452
13702
  type: NodeTypes.Scroll,
13453
13703
  position: {
13454
13704
  x: position['x'],
13455
- y: position['y']() - framePadding,
13705
+ y: position['y']() - framePadding$1,
13456
13706
  },
13457
13707
  style: {
13458
13708
  zIndex: 1,
13459
13709
  },
13460
13710
  data: {
13461
13711
  nodeWidth: nodeWidth$2,
13462
- nodeHeight: containerHeight - nodeHeight$1 + framePadding * 2,
13712
+ nodeHeight: containerHeight - nodeHeight$2 + framePadding$1 * 2,
13463
13713
  items: entities.map((source, idx) => ({
13464
13714
  id: `${EntityTypes.Source}-${idx}`,
13465
13715
  data: mapToNodeData$1(source),
@@ -13474,8 +13724,8 @@ const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, conta
13474
13724
  extent: 'parent',
13475
13725
  parentId: `${EntityTypes.Source}-${NodeTypes.Scroll}`,
13476
13726
  position: {
13477
- x: framePadding,
13478
- y: position['y'](idx) - (nodeHeight$1 - framePadding / 2),
13727
+ x: framePadding$1,
13728
+ y: position['y'](idx) - (nodeHeight$2 - framePadding$1 / 2),
13479
13729
  },
13480
13730
  style: {
13481
13731
  zIndex: -1,
@@ -13516,11 +13766,11 @@ const buildSourceNodes = ({ loading, entities, positions, unfilteredCount, conta
13516
13766
  return nodes;
13517
13767
  };
13518
13768
 
13519
- const { nodeWidth: nodeWidth$1, nodeHeight } = nodeConfig;
13769
+ const { nodeWidth: nodeWidth$1, nodeHeight: nodeHeight$1 } = nodeConfig;
13520
13770
  const getNodePositions = ({ containerWidth }) => {
13521
13771
  const startX = 24;
13522
13772
  const endX = (containerWidth <= 1500 ? 1500 : containerWidth) - nodeWidth$1 - startX;
13523
- const getY = (idx) => nodeHeight * ((idx || 0) + 1);
13773
+ const getY = (idx) => nodeHeight$1 * ((idx || 0) + 1);
13524
13774
  const positions = {
13525
13775
  [EntityTypes.Namespace]: {
13526
13776
  x: 0,
@@ -13552,7 +13802,7 @@ const getNodePositions = ({ containerWidth }) => {
13552
13802
  return positions;
13553
13803
  };
13554
13804
 
13555
- const { nodeWidth } = nodeConfig;
13805
+ const { nodeWidth, nodeHeight, framePadding } = nodeConfig;
13556
13806
  const mapToNodeData = (entity) => {
13557
13807
  const { hasDisableds, priorotizedStatus } = getConditionsBooleans(entity.conditions || []);
13558
13808
  const { icon, iconSrc } = getDestinationIcon(entity.destinationType.type);
@@ -13570,7 +13820,7 @@ const mapToNodeData = (entity) => {
13570
13820
  raw: entity,
13571
13821
  };
13572
13822
  };
13573
- const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount }) => {
13823
+ const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount, containerHeight, onScroll }) => {
13574
13824
  const nodes = [];
13575
13825
  const position = positions[EntityTypes.Destination];
13576
13826
  nodes.push({
@@ -13589,13 +13839,38 @@ const buildDestinationNodes = ({ loading, entities, positions, unfilteredCount }
13589
13839
  },
13590
13840
  });
13591
13841
  if (!!entities.length) {
13842
+ nodes.push({
13843
+ id: `${EntityTypes.Destination}-${NodeTypes.Scroll}`,
13844
+ type: NodeTypes.Scroll,
13845
+ position: {
13846
+ x: position['x'],
13847
+ y: position['y']() - framePadding,
13848
+ },
13849
+ style: {
13850
+ zIndex: 1,
13851
+ },
13852
+ data: {
13853
+ nodeWidth,
13854
+ nodeHeight: containerHeight - nodeHeight + framePadding * 2,
13855
+ items: entities.map((destination, idx) => ({
13856
+ id: `${EntityTypes.Destination}-${idx}`,
13857
+ data: mapToNodeData(destination),
13858
+ })),
13859
+ onScroll,
13860
+ },
13861
+ });
13592
13862
  entities.forEach((destination, idx) => {
13593
13863
  nodes.push({
13594
- id: `${EntityTypes.Destination}-${idx}`,
13595
- type: NodeTypes.Base,
13864
+ id: `${EntityTypes.Destination}-${idx}-hidden`,
13865
+ type: NodeTypes.Edged,
13866
+ extent: 'parent',
13867
+ parentId: `${EntityTypes.Destination}-${NodeTypes.Scroll}`,
13596
13868
  position: {
13597
- x: position['x'],
13598
- y: position['y'](idx),
13869
+ x: framePadding,
13870
+ y: position['y'](idx) - (nodeHeight - framePadding / 2),
13871
+ },
13872
+ style: {
13873
+ zIndex: -1,
13599
13874
  },
13600
13875
  data: mapToNodeData(destination),
13601
13876
  });
@@ -13687,28 +13962,34 @@ const DataFlow = ({ heightToRemove, metrics }) => {
13687
13962
  loading: destinationsLoading,
13688
13963
  unfilteredCount: destinationsByStream.length,
13689
13964
  positions,
13965
+ containerHeight,
13966
+ onScroll: ({ scrollTop }) => handleNodesScrolled(destinationNodes, EntityTypes.Destination, scrollTop),
13690
13967
  });
13691
13968
  handleNodesChanged(destinationNodes, EntityTypes.Destination);
13692
- }, [selectedStreamName, destinations, destinationsLoading, positions[EntityTypes.Destination], filters]);
13969
+ }, [selectedStreamName, destinations, destinationsLoading, positions[EntityTypes.Destination], filters, containerHeight]);
13693
13970
  useEffect(() => {
13694
13971
  const actionNodes = buildActionNodes({
13695
13972
  entities: filterActions(actions, filters),
13696
13973
  loading: actionsLoading,
13697
13974
  unfilteredCount: actions.length,
13698
13975
  positions,
13976
+ containerHeight,
13977
+ onScroll: ({ scrollTop }) => handleNodesScrolled(actionNodes, EntityTypes.Action, scrollTop),
13699
13978
  });
13700
13979
  handleNodesChanged(actionNodes, EntityTypes.Action);
13701
- }, [actions, actionsLoading, positions[EntityTypes.Action], filters]);
13980
+ }, [actions, actionsLoading, positions[EntityTypes.Action], filters, containerHeight]);
13702
13981
  useEffect(() => {
13703
- // note: rules do not have filters yet
13704
13982
  const ruleNodes = buildRuleNodes({
13983
+ // note: rules do not have filters yet
13705
13984
  entities: instrumentationRules,
13706
13985
  loading: instrumentationRulesLoading,
13707
13986
  unfilteredCount: instrumentationRules.length,
13708
13987
  positions,
13988
+ containerHeight,
13989
+ onScroll: ({ scrollTop }) => handleNodesScrolled(ruleNodes, EntityTypes.InstrumentationRule, scrollTop),
13709
13990
  });
13710
13991
  handleNodesChanged(ruleNodes, EntityTypes.InstrumentationRule);
13711
- }, [instrumentationRules, instrumentationRulesLoading, positions[EntityTypes.InstrumentationRule]]);
13992
+ }, [instrumentationRules, instrumentationRulesLoading, positions[EntityTypes.InstrumentationRule], containerHeight]);
13712
13993
  return (React.createElement(Container$e, { ref: containerRef, "$heightToRemove": heightToRemove },
13713
13994
  React.createElement(Flow, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange })));
13714
13995
  };
@@ -13879,6 +14160,7 @@ const Filters$1 = () => {
13879
14160
  const theme = Theme.useTheme();
13880
14161
  const { namespaces, sources } = useEntityStore();
13881
14162
  const { selectedStreamName } = useDataStreamStore();
14163
+ const { getItemSS, setItemSS, removeItemSS } = useSessionStorage();
13882
14164
  const { namespaces: namespaceFilters, kinds, monitors, languages, errors, onlyErrors, setAll, clearAll, getEmptyState } = useFilterStore();
13883
14165
  const sourcesByStream = useMemo(() => filterSourcesByStream(sources, selectedStreamName), [sources, selectedStreamName]);
13884
14166
  // We need local state, because we want to keep the filters in the store only when the user clicks on apply
@@ -13886,6 +14168,10 @@ const Filters$1 = () => {
13886
14168
  const [filterCount, setFilterCount] = useState(getFilterCount(filters));
13887
14169
  const [focused, setFocused] = useState(false);
13888
14170
  const toggleFocused = () => setFocused((prev) => !prev);
14171
+ useEffect(() => {
14172
+ const storedFilters = getItemSS(STORAGE_KEYS.OVERVIEW_FILTERS, getEmptyState());
14173
+ setAll(storedFilters);
14174
+ }, []);
13889
14175
  useEffect(() => {
13890
14176
  if (!focused) {
13891
14177
  const payload = { namespaces: namespaceFilters, kinds, monitors, languages, errors, onlyErrors };
@@ -13894,17 +14180,13 @@ const Filters$1 = () => {
13894
14180
  }
13895
14181
  }, [focused, namespaceFilters, kinds, monitors, errors, onlyErrors]);
13896
14182
  const onApply = () => {
13897
- // TODO: remove trycatch after debugging
13898
- try {
13899
- setAll(filters);
13900
- setFilterCount(getFilterCount(filters));
13901
- setFocused(false);
13902
- }
13903
- catch (error) {
13904
- console.error(error);
13905
- }
14183
+ setItemSS(STORAGE_KEYS.OVERVIEW_FILTERS, filters);
14184
+ setAll(filters);
14185
+ setFilterCount(getFilterCount(filters));
14186
+ setFocused(false);
13906
14187
  };
13907
14188
  const onReset = () => {
14189
+ removeItemSS(STORAGE_KEYS.OVERVIEW_FILTERS);
13908
14190
  clearAll();
13909
14191
  setFilters(getEmptyState());
13910
14192
  setFilterCount(0);
@@ -14240,10 +14522,6 @@ const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validat
14240
14522
  setAutoFilled(didAutoFill);
14241
14523
  }
14242
14524
  }, [dynamicFields, isFormDirty]);
14243
- const dirtyForm = () => {
14244
- setIsFormDirty(true);
14245
- setConnection(undefined);
14246
- };
14247
14525
  const supportedMonitors = useMemo(() => {
14248
14526
  const { logs, metrics, traces } = supportedSignals || {};
14249
14527
  const arr = [];
@@ -14265,7 +14543,11 @@ const DestinationForm = ({ isUpdate, categoryItem, formData, formErrors, validat
14265
14543
  if (traces)
14266
14544
  arr.push(SignalType.Traces);
14267
14545
  return arr;
14268
- }, [formData['exportedSignals']]);
14546
+ }, [formData]);
14547
+ const dirtyForm = () => {
14548
+ setIsFormDirty(true);
14549
+ setConnection(undefined);
14550
+ };
14269
14551
  const handleSelectedSignals = (signals) => {
14270
14552
  dirtyForm();
14271
14553
  handleFormChange('exportedSignals', {
@@ -14397,7 +14679,7 @@ const ListsWrapper = styled.div `
14397
14679
  flex-direction: column;
14398
14680
  gap: 12px;
14399
14681
  `;
14400
- const DestinationsList = ({ items, onSelectOption, onSelectConfigured }) => {
14682
+ const DestinationsList = ({ items, onSelectNew, onSelectConfigured }) => {
14401
14683
  const { configuredDestinationsUpdateOnly } = useSetupStore();
14402
14684
  return items.map((category) => {
14403
14685
  const isAlreadyExisting = category.name === DESTINATION_CATEGORIES['EXISTS']['TITLE'];
@@ -14408,7 +14690,7 @@ const DestinationsList = ({ items, onSelectOption, onSelectConfigured }) => {
14408
14690
  const key = `select-${category.name.replaceAll(' ', '')}-destination-${item.type}`;
14409
14691
  const isChecked = item.selected || configuredDestinationsUpdateOnly.some((dest) => dest.id === item.id);
14410
14692
  const monitors = Object.keys(item.supportedSignals).filter((signal) => item.supportedSignals[signal].supported);
14411
- const onClick = isAlreadyExisting ? () => onSelectConfigured(item.id) : () => onSelectOption(item);
14693
+ const onClick = isAlreadyExisting ? () => onSelectConfigured(item.id) : () => onSelectNew(item);
14412
14694
  const { icon, iconSrc } = getDestinationIcon(item.type);
14413
14695
  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: {
14414
14696
  withCheckbox: isAlreadyExisting,
@@ -14476,7 +14758,7 @@ const createConfiguredItems = (destinations, selectedStreamName, configuredDesti
14476
14758
  },
14477
14759
  };
14478
14760
  });
14479
- const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSelectOption, onSelectConfigured }) => {
14761
+ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSelectNew, onSelectConfigured }) => {
14480
14762
  const { destinations } = useEntityStore();
14481
14763
  const { selectedStreamName } = useDataStreamStore();
14482
14764
  const { configuredDestinations, configuredDestinationsUpdateOnly } = useSetupStore();
@@ -14509,7 +14791,7 @@ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSe
14509
14791
  return { ...category, items: filteredItems };
14510
14792
  })
14511
14793
  .filter(({ items }) => !!items.length); // Filter out empty categories
14512
- }, [categories, potentialDestinations, destinations, search, selectedCategory, selectedMonitors, selectedStreamName, configuredDestinations]);
14794
+ }, [categories, potentialDestinations, destinations, search, selectedCategory, selectedMonitors, selectedStreamName, configuredDestinations, configuredDestinationsUpdateOnly]);
14513
14795
  if (hidden)
14514
14796
  return null;
14515
14797
  return (React.createElement(Container$9, null,
@@ -14523,7 +14805,7 @@ const ChooseDestinationBody = ({ hidden, categories, potentialDestinations, onSe
14523
14805
  React.createElement(Divider, null),
14524
14806
  !filteredDestinations.length ? (React.createElement(NoDataFoundWrapper, null,
14525
14807
  React.createElement(NoDataFound, { title: 'No destinations found' }))) : (React.createElement(ListsContainer, null,
14526
- React.createElement(DestinationsList, { items: filteredDestinations, onSelectOption: onSelectOption, onSelectConfigured: onSelectConfigured })))));
14808
+ React.createElement(DestinationsList, { items: filteredDestinations, onSelectNew: (dest) => onSelectNew(dest, selectedMonitors), onSelectConfigured: onSelectConfigured })))));
14527
14809
  };
14528
14810
 
14529
14811
  const Container$8 = styled.div `
@@ -14607,10 +14889,17 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
14607
14889
  resetFormData();
14608
14890
  setSelectedItem(undefined);
14609
14891
  };
14610
- const handleSelectOption = (item) => {
14892
+ const handleSelectNew = (item, selectedMonitors) => {
14611
14893
  resetFormData();
14612
14894
  handleFormChange('type', item?.type || '');
14613
14895
  handleFormChange('currentStreamName', selectedStreamName);
14896
+ const exportedSignals = {
14897
+ logs: false,
14898
+ metrics: false,
14899
+ traces: false,
14900
+ };
14901
+ selectedMonitors.filter((monitor) => item.supportedSignals[monitor].supported).forEach((monitor) => (exportedSignals[monitor] = true));
14902
+ handleFormChange('exportedSignals', exportedSignals);
14614
14903
  setYamlFields(item?.fields || []);
14615
14904
  setSelectedItem(item);
14616
14905
  };
@@ -14656,7 +14945,7 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
14656
14945
  { stepNumber: 2, title: DISPLAY_TITLES.CONNECTION },
14657
14946
  ] })),
14658
14947
  React.createElement(ModalBody, { style: { margin: '32px 24px 12px 24px' } },
14659
- React.createElement(ChooseDestinationBody, { hidden: selectedItem !== undefined, categories: categories, potentialDestinations: potentialDestinations, onSelectOption: handleSelectOption, onSelectConfigured: handleSelectConfigured }),
14948
+ React.createElement(ChooseDestinationBody, { hidden: selectedItem !== undefined, categories: categories, potentialDestinations: potentialDestinations, onSelectNew: handleSelectNew, onSelectConfigured: handleSelectConfigured }),
14660
14949
  selectedItem && (React.createElement(DestinationForm, { categoryItem: selectedItem, formData: formData, formErrors: formErrors, handleFormChange: handleFormChange, dynamicFields: dynamicFields, setDynamicFields: setDynamicFields, validateForm: validateForm, testConnection: testConnection }))))));
14661
14950
  };
14662
14951
 
@@ -14814,7 +15103,7 @@ const DestinationTable = ({ metrics, maxHeight, maxWidth }) => {
14814
15103
  };
14815
15104
 
14816
15105
  const buildCard$1 = (rule) => {
14817
- const { type, ruleName, notes, disabled, profileName, payloadCollection, codeAttributes } = rule;
15106
+ const { type, ruleName, notes, disabled, profileName, payloadCollection, codeAttributes, headersCollection } = rule;
14818
15107
  const arr = [
14819
15108
  { title: DISPLAY_TITLES.TYPE, value: type },
14820
15109
  { type: DataCardFieldTypes.ActiveStatus, title: DISPLAY_TITLES.STATUS, value: String(!disabled) },
@@ -14823,20 +15112,25 @@ const buildCard$1 = (rule) => {
14823
15112
  { title: DISPLAY_TITLES.MANAGED_BY_PROFILE, value: profileName },
14824
15113
  { type: DataCardFieldTypes.Divider },
14825
15114
  ];
14826
- if (!!payloadCollection) {
15115
+ if (payloadCollection) {
14827
15116
  const str = Object.entries(payloadCollection)
14828
- .filter(([key, val]) => !!val)
15117
+ .filter(([key, val]) => val)
14829
15118
  .map(([key, val]) => key)
14830
15119
  .join(', ');
14831
- if (!!str)
15120
+ if (str)
14832
15121
  arr.push({ title: 'Collect', value: str });
14833
15122
  }
14834
- if (!!codeAttributes) {
15123
+ if (codeAttributes) {
14835
15124
  const str = Object.entries(codeAttributes)
14836
- .filter(([key, val]) => !!val)
15125
+ .filter(([key, val]) => val)
14837
15126
  .map(([key, val]) => key)
14838
15127
  .join(', ');
14839
- if (!!str)
15128
+ if (str)
15129
+ arr.push({ title: 'Collect', value: str });
15130
+ }
15131
+ if (headersCollection) {
15132
+ const str = (headersCollection[HeadersCollectionKeyTypes.HeaderKeys] || []).filter((val) => val).join(', ');
15133
+ if (str)
14840
15134
  arr.push({ title: 'Collect', value: str });
14841
15135
  }
14842
15136
  return arr;
@@ -15767,6 +16061,11 @@ const buildCard = (source) => {
15767
16061
  { title: DISPLAY_TITLES.NAMESPACE, value: namespace },
15768
16062
  { title: DISPLAY_TITLES.KIND, value: kind },
15769
16063
  { title: DISPLAY_TITLES.NAME, value: name, tooltip: 'K8s resource name' },
16064
+ { type: DataCardFieldTypes.Divider },
16065
+ {
16066
+ type: DataCardFieldTypes.CopyText,
16067
+ value: `kubectl get ${kind} ${name} -n ${namespace}`,
16068
+ },
15770
16069
  ];
15771
16070
  return arr;
15772
16071
  };
@@ -15818,12 +16117,27 @@ const SourceDrawer = ({ persistSources, updateSource, fetchDescribeSource }) =>
15818
16117
  loadFormWithDrawerItem(found);
15819
16118
  return found;
15820
16119
  }, [isOpen, drawerEntityId, sourcesByStream]);
16120
+ const containersData = useMemo(() => {
16121
+ const isDisabled = thisItem?.conditions?.some(({ status }) => status === OtherStatus.Disabled);
16122
+ const runtimeCondition = thisItem?.conditions?.find(({ type }) => type === 'RuntimeDetection');
16123
+ const mappedContainers = thisItem?.containers?.map((container) => {
16124
+ const value = {
16125
+ ...container,
16126
+ isDisabled,
16127
+ };
16128
+ return {
16129
+ type: DataCardFieldTypes.SourceContainer,
16130
+ value: JSON.stringify(value),
16131
+ };
16132
+ }) || [];
16133
+ return {
16134
+ description: runtimeCondition?.message,
16135
+ isLoading: runtimeCondition?.status === OtherStatus.Loading,
16136
+ items: mappedContainers,
16137
+ };
16138
+ }, [thisItem]);
15821
16139
  if (!thisItem)
15822
16140
  return null;
15823
- const containersData = thisItem.containers?.map((container) => ({
15824
- type: DataCardFieldTypes.SourceContainer,
15825
- value: JSON.stringify(container),
15826
- })) || [];
15827
16141
  const handleEdit = (bool) => {
15828
16142
  setIsEditing(typeof bool === 'boolean' ? bool : true);
15829
16143
  };
@@ -15867,7 +16181,7 @@ const SourceDrawer = ({ persistSources, updateSource, fetchDescribeSource }) =>
15867
16181
  } }))) : (React.createElement(DataContainer$1, null,
15868
16182
  React.createElement(ConditionDetails, { conditions: thisItem.conditions || [] }),
15869
16183
  React.createElement(DataCard, { title: DISPLAY_TITLES.SOURCE_DETAILS, data: !!thisItem ? buildCard(thisItem) : [] }),
15870
- 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 }))));
16184
+ 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 }))));
15871
16185
  };
15872
16186
 
15873
16187
  const ActionsRow = styled(FlexRow) `