@odigos/ui-kit 0.0.32 → 0.0.34

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 (57) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/lib/components/dropdown/index.d.ts +1 -0
  3. package/lib/components/input/index.d.ts +1 -1
  4. package/lib/components/input-table/index.d.ts +3 -11
  5. package/lib/components/input-table/map-columns-to-fields/index.d.ts +15 -0
  6. package/lib/components/input-table/types.d.ts +15 -0
  7. package/lib/components.js +11 -11
  8. package/lib/constants/strings/index.d.ts +1 -0
  9. package/lib/constants.js +2 -2
  10. package/lib/containers/action-form/custom-fields/add-cluster-info.d.ts +1 -1
  11. package/lib/containers/action-form/custom-fields/delete-attributes.d.ts +1 -1
  12. package/lib/containers/action-form/custom-fields/error-sampler.d.ts +1 -1
  13. package/lib/containers/action-form/custom-fields/k8s-attributes.d.ts +1 -1
  14. package/lib/containers/action-form/custom-fields/latency-sampler.d.ts +1 -1
  15. package/lib/containers/action-form/custom-fields/pii-masking.d.ts +1 -1
  16. package/lib/containers/action-form/custom-fields/probabilistic-sampler.d.ts +1 -1
  17. package/lib/containers/action-form/custom-fields/rename-attributes.d.ts +1 -1
  18. package/lib/containers/action-form/custom-fields/service-name-sampler.d.ts +5 -0
  19. package/lib/containers/action-form/custom-fields/span-attribute-sampler.d.ts +5 -0
  20. package/lib/containers/data-stream-drawer/index.d.ts +1 -1
  21. package/lib/containers/data-stream-form/index.d.ts +1 -0
  22. package/lib/containers/destination-selection-form/destination-list/index.d.ts +2 -0
  23. package/lib/containers/instrumentation-rule-drawer/build-card.d.ts +1 -1
  24. package/lib/containers/setup-summary/index.d.ts +2 -0
  25. package/lib/containers.js +379 -189
  26. package/lib/functions/get-action-icon/index.d.ts +2 -2
  27. package/lib/functions/get-yaml-fields-for-destination/index.d.ts +2 -0
  28. package/lib/functions/index.d.ts +4 -0
  29. package/lib/functions/is-legal-k8s-label/index.d.ts +1 -0
  30. package/lib/functions/map-destination-fields-for-display/index.d.ts +6 -0
  31. package/lib/functions/numbers-only/index.d.ts +1 -0
  32. package/lib/functions.js +8 -8
  33. package/lib/hooks.js +6 -6
  34. package/lib/icons.js +7 -7
  35. package/lib/{index-DR5ryS5d.js → index--RecCPGA.js} +1 -1
  36. package/lib/{index-cG2lNgzz.js → index-BBjwRlta.js} +41 -6
  37. package/lib/{index-B3j_QWzh.js → index-BWZT-ipR.js} +1 -1
  38. package/lib/{index-BxckQJom.js → index-BZq0yNL-.js} +90 -45
  39. package/lib/{index-DuSmjoDs.js → index-Bd8ZAEvq.js} +1 -1
  40. package/lib/{index-DAbcw-wM.js → index-CIKkezVt.js} +1 -1
  41. package/lib/{index-C7YDojNh.js → index-ChYtqgBW.js} +9 -3
  42. package/lib/{index-7-KCQK-x.js → index-CnZlllYu.js} +10 -1
  43. package/lib/{index-PfG5pvFK.js → index-Cq8NT9Hr.js} +1 -1
  44. package/lib/{index-ivnS3eWW.js → index-DJGe2YeC.js} +128 -111
  45. package/lib/{index-rbphz5kH.js → index-a_WA-82O.js} +2 -2
  46. package/lib/{index-B9cvsYnj.js → index-mOgS3e5E.js} +1 -0
  47. package/lib/{index-DeD-SIlN.js → index-ovjVbVQq.js} +5 -5
  48. package/lib/snippets.js +10 -10
  49. package/lib/store.js +1 -1
  50. package/lib/theme.js +1 -1
  51. package/lib/types/actions/index.d.ts +137 -41
  52. package/lib/types/common/index.d.ts +4 -16
  53. package/lib/types.js +78 -20
  54. package/lib/{useSourceSelectionFormData-A5_zhn1C.js → useSourceSelectionFormData-DBNf1uEe.js} +48 -26
  55. package/lib/{useTransition-9tDdAS9s.js → useTransition-dZ92VxT2.js} +1 -1
  56. package/package.json +12 -12
  57. package/lib/{index-BZS1ijMm.js → index-BV85P9UP.js} +14 -14
package/lib/containers.js CHANGED
@@ -1,27 +1,27 @@
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-ivnS3eWW.js';
4
- import { a as DISPLAY_TITLES, B as BUTTON_TEXTS, F as FORM_ALERTS, D as DEFAULT_DATA_STREAM_NAME } from './index-B9cvsYnj.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, I as IconButton, A as AddButton$1, U as Stepper, e as DataCardFields, s as IconsNav, p as IconGroup } from './index-BxckQJom.js';
7
- import { i as isEmpty, s as safeJsonParse } from './index-BZS1ijMm.js';
8
- import { i as CheckCircledIcon, O as OdigosLogo } from './index-DuSmjoDs.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-DR5ryS5d.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-A5_zhn1C.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-9tDdAS9s.js';
12
- import { E as EditIcon } from './index-B3j_QWzh.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-DAbcw-wM.js';
14
- import { D as DeleteWarning, C as CancelWarning } from './index-rbphz5kH.js';
15
- import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-C7YDojNh.js';
16
- import { f as filterActions, i as getConditionsBooleans, n as getEntityLabel, m as getEntityIcon, v as sleep$1, p as getPlatformIcon, q as getPlatformLabel, h as formatBytes, k as getContainersIcons, r as getValueForRange, l as getDestinationIcon, u as mapExportedSignals, g as filterSourcesByStream, e as filterSources, b as filterDestinationsByStream, a as filterDestinations, c as compareCondition, d as deepClone, o as getMetricForEntity, s as getWorkloadId, j as getContainersInstrumentedCount, t as isOverTime } from './index-cG2lNgzz.js';
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';
5
+ 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';
7
+ 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';
17
17
  import { createPortal } from 'react-dom';
18
- import { N as NoteBackToSummary, E as EditButton } from './index-DeD-SIlN.js';
18
+ import { N as NoteBackToSummary, E as EditButton } from './index-ovjVbVQq.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-PfG5pvFK.js';
21
- import './index-7-KCQK-x.js';
20
+ import { a6 as RulesIcon, a7 as SourcesIcon, a3 as ActionsIcon, a4 as DestinationsIcon } from './index-Cq8NT9Hr.js';
21
+ import './index-CnZlllYu.js';
22
22
 
23
23
  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;
24
+ const { type, spec: { actionName, notes, signals, disabled, collectContainerAttributes, collectReplicaSetAttributes, collectWorkloadId, collectClusterId, labelsAttributes, annotationsAttributes, clusterAttributes, attributeNamesToDelete, renames, piiCategories, fallbackSamplingRatio, samplingPercentage, endpointsFilters, servicesNameFilters, attributeFilters, }, } = action;
25
25
  const arr = [
26
26
  { title: DISPLAY_TITLES.TYPE, value: type },
27
27
  { type: DataCardFieldTypes.ActiveStatus, title: DISPLAY_TITLES.STATUS, value: String(!disabled) },
@@ -101,14 +101,39 @@ const buildCard$3 = (action) => {
101
101
  str += `Service Name: ${serviceName}\n`;
102
102
  str += `HTTP Route: ${httpRoute}\n`;
103
103
  str += `Min. Latency: ${minimumLatencyThreshold}\n`;
104
- str += `Sampling Ratio: ${fallbackSamplingRatio}`;
104
+ str += `Fallback Sampling Ratio: ${fallbackSamplingRatio}`;
105
105
  arr.push({ title: `Endpoint${endpointsFilters.length > 1 ? ` #${idx + 1}` : ''}`, value: str });
106
106
  });
107
107
  }
108
+ if (type === ActionType.ServiceNameSampler) {
109
+ servicesNameFilters?.forEach(({ serviceName, samplingRatio, fallbackSamplingRatio }, idx) => {
110
+ let str = '';
111
+ str += `Service Name: ${serviceName}\n`;
112
+ str += `Sampling Ratio: ${samplingRatio}\n`;
113
+ str += `Fallback Sampling Ratio: ${fallbackSamplingRatio}`;
114
+ arr.push({ title: `Filter${servicesNameFilters.length > 1 ? ` #${idx + 1}` : ''}`, value: str });
115
+ });
116
+ }
117
+ if (type === ActionType.SpanAttributeSampler) {
118
+ attributeFilters?.forEach(({ serviceName, attributeKey, fallbackSamplingRatio, condition }, idx) => {
119
+ let str = '';
120
+ str += `Service Name: ${serviceName}\n`;
121
+ str += `Attribute Key: ${attributeKey}\n`;
122
+ str += `Fallback Sampling Ratio: ${fallbackSamplingRatio}\n`;
123
+ const conditionKey = Object.keys(condition)[0];
124
+ str += `Condition: ${conditionKey}\n`;
125
+ str += `Operation: ${condition[conditionKey]?.operation}\n`;
126
+ str += `Expected Value: ${condition[conditionKey]?.expectedValue}`;
127
+ if (conditionKey === 'jsonCondition') {
128
+ str += `\nJSON Path: ${condition[conditionKey].jsonPath}`;
129
+ }
130
+ arr.push({ title: `Filter${attributeFilters.length > 1 ? ` #${idx + 1}` : ''}`, value: str });
131
+ });
132
+ }
108
133
  return arr;
109
134
  };
110
135
 
111
- const KEY$6 = 'piiCategories';
136
+ const KEY$8 = ActionKeyTypes.PiiCategories;
112
137
  const ListContainer$2 = styled.div `
113
138
  display: flex;
114
139
  flex-direction: row;
@@ -127,18 +152,18 @@ const PII_OPTIONS = [
127
152
  },
128
153
  ];
129
154
  const PiiMasking = ({ value, setValue, formErrors }) => {
130
- const errorMessage = formErrors[KEY$6];
131
- const mappedValue = value[KEY$6] || [];
155
+ const errorMessage = formErrors[KEY$8];
156
+ const mappedValue = value[KEY$8] || [];
132
157
  const [isLastSelection, setIsLastSelection] = useState(mappedValue.length === 1);
133
158
  const handleChange = (id, isAdd) => {
134
159
  const arr = isAdd ? [...mappedValue, id] : mappedValue.filter((str) => str !== id);
135
- setValue(KEY$6, arr);
160
+ setValue(KEY$8, arr);
136
161
  setIsLastSelection(arr.length === 1);
137
162
  };
138
163
  useEffect(() => {
139
164
  if (!mappedValue.length) {
140
165
  const arr = PII_OPTIONS.map(({ id }) => id);
141
- setValue(KEY$6, arr);
166
+ setValue(KEY$8, arr);
142
167
  setIsLastSelection(PII_OPTIONS.length === 1);
143
168
  }
144
169
  // eslint-disable-next-line
@@ -149,140 +174,316 @@ const PiiMasking = ({ value, setValue, formErrors }) => {
149
174
  !!errorMessage && React.createElement(FieldError, null, errorMessage)));
150
175
  };
151
176
 
152
- const KEY$5 = 'fallbackSamplingRatio', MIN$1 = 0, MAX$1 = 100;
177
+ const KEY$7 = ActionKeyTypes.FallbackSamplingRatio, MIN$1 = 0, MAX$1 = 100;
153
178
  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 }));
179
+ const errorMessage = formErrors[KEY$7];
180
+ const mappedValue = value[KEY$7];
181
+ const handleChange = (val) => setValue(KEY$7, Math.max(MIN$1, Math.min(Number(val), MAX$1)) || MIN$1);
182
+ 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
183
  };
159
184
 
185
+ const LABEL_COLUMNS = [
186
+ {
187
+ title: 'Label Key',
188
+ keyName: 'labelKey',
189
+ placeholder: 'app.kubernetes.io/name',
190
+ required: true,
191
+ },
192
+ {
193
+ title: 'Attribute Key',
194
+ keyName: 'attributeKey',
195
+ placeholder: 'app.kubernetes.name',
196
+ required: true,
197
+ },
198
+ ];
199
+ const ANNOTATION_COLUMNS = [
200
+ {
201
+ title: 'Annotation Key',
202
+ keyName: 'annotationKey',
203
+ placeholder: 'kubectl.kubernetes.io/restartedAt',
204
+ required: true,
205
+ },
206
+ {
207
+ title: 'Attribute Key',
208
+ keyName: 'attributeKey',
209
+ placeholder: 'kubectl.kubernetes.restartedAt',
210
+ required: true,
211
+ },
212
+ ];
160
213
  const K8sAttributes = ({ value, setValue, formErrors }) => {
161
214
  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', []);
215
+ if (!value[ActionKeyTypes.CollectContainerAttributes] &&
216
+ !value[ActionKeyTypes.CollectReplicaSetAttributes] &&
217
+ !value[ActionKeyTypes.CollectWorkloadId] &&
218
+ !value[ActionKeyTypes.CollectClusterId] &&
219
+ !value[ActionKeyTypes.LabelsAttributes]?.length &&
220
+ !value[ActionKeyTypes.AnnotationsAttributes]?.length) {
221
+ setValue(ActionKeyTypes.CollectContainerAttributes, true);
222
+ setValue(ActionKeyTypes.CollectReplicaSetAttributes, true);
223
+ setValue(ActionKeyTypes.CollectWorkloadId, true);
224
+ setValue(ActionKeyTypes.CollectClusterId, true);
225
+ setValue(ActionKeyTypes.LabelsAttributes, []);
226
+ setValue(ActionKeyTypes.AnnotationsAttributes, []);
169
227
  }
170
228
  // eslint-disable-next-line
171
229
  }, []);
172
230
  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'] })));
231
+ React.createElement(Checkbox, { title: 'Collect Container Attributes', value: value[ActionKeyTypes.CollectContainerAttributes] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectContainerAttributes, bool), errorMessage: formErrors[ActionKeyTypes.CollectContainerAttributes] }),
232
+ React.createElement(Checkbox, { title: 'Collect ReplicaSet Attributes', value: value[ActionKeyTypes.CollectReplicaSetAttributes] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectReplicaSetAttributes, bool), errorMessage: formErrors[ActionKeyTypes.CollectReplicaSetAttributes] }),
233
+ React.createElement(Checkbox, { title: 'Collect Workload ID', value: value[ActionKeyTypes.CollectWorkloadId] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectWorkloadId, bool), errorMessage: formErrors[ActionKeyTypes.CollectWorkloadId] }),
234
+ React.createElement(Checkbox, { title: 'Collect Cluster ID', value: value[ActionKeyTypes.CollectClusterId] || false, onChange: (bool) => setValue(ActionKeyTypes.CollectClusterId, bool), errorMessage: formErrors[ActionKeyTypes.CollectClusterId] }),
235
+ React.createElement(InputTable, { columns: LABEL_COLUMNS, value: value[ActionKeyTypes.LabelsAttributes] || [], onChange: (arr) => setValue(ActionKeyTypes.LabelsAttributes, arr), errorMessage: formErrors[ActionKeyTypes.LabelsAttributes] }),
236
+ React.createElement(InputTable, { columns: ANNOTATION_COLUMNS, value: value[ActionKeyTypes.AnnotationsAttributes] || [], onChange: (arr) => setValue(ActionKeyTypes.AnnotationsAttributes, arr), errorMessage: formErrors[ActionKeyTypes.AnnotationsAttributes] })));
205
237
  };
206
238
 
207
- const KEY$4 = 'endpointsFilters';
239
+ const KEY$6 = ActionKeyTypes.EndpointsFilters;
240
+ const COLUMNS$2 = [
241
+ {
242
+ title: 'Service',
243
+ keyName: 'serviceName',
244
+ placeholder: 'e.g. my-service',
245
+ tooltip: 'Service name: The rule applies to a specific service name. Only traces originating from this service’s root span will be considered.',
246
+ required: true,
247
+ },
248
+ {
249
+ title: 'HTTP route',
250
+ keyName: 'httpRoute',
251
+ placeholder: 'e.g. /api/v1/users',
252
+ 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.',
253
+ required: true,
254
+ },
255
+ {
256
+ title: 'Threshold',
257
+ keyName: 'minimumLatencyThreshold',
258
+ placeholder: 'e.g. 1000',
259
+ tooltip: 'Minimum latency threshold (ms): Specifies the minimum latency in milliseconds; traces with latency below this threshold are ignored.',
260
+ required: true,
261
+ type: InputTypes.Number,
262
+ },
263
+ {
264
+ title: 'Fallback',
265
+ keyName: 'fallbackSamplingRatio',
266
+ placeholder: 'e.g. 100',
267
+ 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.',
268
+ required: true,
269
+ type: InputTypes.Number,
270
+ },
271
+ ];
208
272
  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 }));
273
+ const errorMessage = formErrors[KEY$6];
274
+ const mappedValue = value[KEY$6] || [];
275
+ const handleChange = (arr) => {
276
+ const mapped = arr.map(({ serviceName, httpRoute, minimumLatencyThreshold, fallbackSamplingRatio }) => {
277
+ const row = {
278
+ serviceName,
279
+ httpRoute,
280
+ minimumLatencyThreshold: Number(minimumLatencyThreshold),
281
+ fallbackSamplingRatio: Number(fallbackSamplingRatio),
282
+ };
283
+ return row;
284
+ });
285
+ setValue(KEY$6, mapped);
286
+ };
287
+ return React.createElement(InputTable, { columns: COLUMNS$2, value: mappedValue, onChange: handleChange, errorMessage: errorMessage });
244
288
  };
245
289
 
246
- const KEY$3 = 'clusterAttributes';
290
+ const KEY$5 = ActionKeyTypes.ClusterAttributes;
247
291
  const AddClusterInfo = ({ value, setValue, formErrors }) => {
248
- const errorMessage = formErrors[KEY$3];
249
- const mappedValue = value[KEY$3]?.map((obj) => ({
292
+ const errorMessage = formErrors[KEY$5];
293
+ const mappedValue = value[KEY$5]?.map((obj) => ({
250
294
  key: obj.attributeName,
251
295
  value: obj.attributeStringValue,
252
296
  })) || [];
253
- const handleChange = (arr) => setValue(KEY$3, arr.map((obj) => ({
297
+ const handleChange = (arr) => setValue(KEY$5, arr.map((obj) => ({
254
298
  attributeName: obj.key,
255
299
  attributeStringValue: obj.value,
256
300
  })));
257
301
  return React.createElement(KeyValueInputsList, { title: 'Resource Attributes', value: mappedValue, onChange: handleChange, required: true, errorMessage: errorMessage });
258
302
  };
259
303
 
260
- const KEY$2 = 'attributeNamesToDelete';
304
+ const KEY$4 = ActionKeyTypes.AttributeNamesToDelete;
261
305
  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);
306
+ const errorMessage = formErrors[KEY$4];
307
+ const mappedValue = value[KEY$4] || [];
308
+ const handleChange = (arr) => setValue(KEY$4, arr);
265
309
  return React.createElement(InputList, { title: 'Attributes to delete', value: mappedValue, onChange: handleChange, required: true, errorMessage: errorMessage });
266
310
  };
267
311
 
268
- const KEY$1 = 'renames';
312
+ const KEY$3 = ActionKeyTypes.Renames;
269
313
  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 }));
314
+ const errorMessage = formErrors[KEY$3];
315
+ const mappedValue = Object.entries(value[KEY$3] || {}).map(([k, v]) => ({ key: k, value: v }));
272
316
  const handleChange = (arr) => {
273
317
  const payload = {};
274
318
  arr.forEach((obj) => (payload[obj.key] = obj.value));
275
- setValue(KEY$1, payload);
319
+ setValue(KEY$3, payload);
276
320
  };
277
321
  return React.createElement(KeyValueInputsList, { title: 'Attributes to rename', value: mappedValue, onChange: handleChange, required: true, errorMessage: errorMessage });
278
322
  };
279
323
 
280
- const KEY = 'samplingPercentage', MIN = 0, MAX = 100;
324
+ const KEY$2 = ActionKeyTypes.ServicesNameFilters;
325
+ const COLUMNS$1 = [
326
+ {
327
+ title: 'Service Name',
328
+ keyName: 'serviceName',
329
+ placeholder: 'e.g. my-service',
330
+ tooltip: 'Specifies the service name to search within the trace (Across all available spans).',
331
+ required: true,
332
+ },
333
+ {
334
+ title: 'Sampling Ratio',
335
+ keyName: 'samplingRatio',
336
+ placeholder: 'e.g. 10',
337
+ tooltip: 'Specifies the sample rate for all traces.',
338
+ required: true,
339
+ type: InputTypes.Number,
340
+ },
341
+ {
342
+ title: 'Fallback Sampling Ratio',
343
+ keyName: 'fallbackSamplingRatio',
344
+ placeholder: 'e.g. 100',
345
+ tooltip: 'Specifies the percentage of traces that don’t meet the service name filter and that you still like to retain.',
346
+ required: true,
347
+ type: InputTypes.Number,
348
+ },
349
+ ];
350
+ const ServiceNameSampler = ({ value, setValue, formErrors }) => {
351
+ const errorMessage = formErrors[KEY$2];
352
+ const mappedValue = value[KEY$2] || [];
353
+ const handleChange = (arr) => {
354
+ const mapped = arr.map(({ serviceName, samplingRatio, fallbackSamplingRatio }) => {
355
+ const row = {
356
+ serviceName,
357
+ samplingRatio: Number(samplingRatio),
358
+ fallbackSamplingRatio: Number(fallbackSamplingRatio),
359
+ };
360
+ return row;
361
+ });
362
+ setValue(KEY$2, mapped);
363
+ };
364
+ return React.createElement(InputTable, { columns: COLUMNS$1, value: mappedValue, onChange: handleChange, errorMessage: errorMessage });
365
+ };
366
+
367
+ const KEY$1 = ActionKeyTypes.SamplingPercentage, MIN = 0, MAX = 100;
281
368
  const ProbabilisticSampler = ({ value, setValue, formErrors }) => {
369
+ const errorMessage = formErrors[KEY$1];
370
+ const mappedValue = value[KEY$1];
371
+ const handleChange = (val) => setValue(KEY$1, Math.max(MIN, Math.min(Number(val), MAX)) || MIN);
372
+ 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 }));
373
+ };
374
+
375
+ const KEY = ActionKeyTypes.AttributeFilters;
376
+ const COLUMNS = [
377
+ {
378
+ title: 'Service Name',
379
+ keyName: 'serviceName',
380
+ placeholder: 'e.g. my-service',
381
+ tooltip: 'Specifies the service name to search within the trace (across all available spans).',
382
+ required: true,
383
+ },
384
+ {
385
+ title: 'Attribute Key',
386
+ keyName: 'attributeKey',
387
+ placeholder: 'e.g. http.request.method',
388
+ tooltip: 'Specifies the attribute key inside of the span.',
389
+ required: true,
390
+ },
391
+ {
392
+ title: 'Fallback Sampling Ratio',
393
+ keyName: 'fallbackSamplingRatio',
394
+ placeholder: 'e.g. 100',
395
+ tooltip: 'Specifies the percentage of traces that don’t meet the service name filter and that you still like to retain.',
396
+ required: true,
397
+ type: InputTypes.Number,
398
+ },
399
+ {
400
+ title: 'Condition',
401
+ keyName: 'condition',
402
+ tooltip: 'An object representing the filters for span attributes filters.',
403
+ required: true,
404
+ componentType: FieldTypes.Dropdown,
405
+ options: [
406
+ { id: 'stringCondition', value: 'String Condition' },
407
+ { id: 'numberCondition', value: 'Number Condition' },
408
+ { id: 'booleanCondition', value: 'Boolean Condition' },
409
+ { id: 'jsonCondition', value: 'JSON Condition' },
410
+ ],
411
+ },
412
+ {
413
+ title: 'Operation',
414
+ keyName: 'operation',
415
+ tooltip: 'Specifies the operation to run against the attribute.',
416
+ required: true,
417
+ componentType: FieldTypes.Dropdown,
418
+ options: [
419
+ { id: 'exists', value: 'Exists' },
420
+ { id: 'equals', value: 'Equals' },
421
+ { id: 'not_equals', value: 'Not Equals' },
422
+ { id: 'contains', value: 'Contains' },
423
+ { id: 'not_contains', value: 'Not Contains' },
424
+ { id: 'regex', value: 'Regex' },
425
+ { id: 'greater_than', value: 'Greater Than' },
426
+ { id: 'less_than', value: 'Less Than' },
427
+ { id: 'greater_than_or_equal', value: 'Greater Than Or Equal' },
428
+ { id: 'less_than_or_equal', value: 'Less Than Or Equal' },
429
+ { id: 'is_valid_json', value: 'Is Valid JSON' },
430
+ { id: 'is_invalid_json', value: 'Is Invalid JSON' },
431
+ { id: 'jsonpath_exists', value: 'JSON Path Exists' },
432
+ { id: 'key_equals', value: 'Key Equals' },
433
+ { id: 'key_not_equals', value: 'Key Not Equals' },
434
+ ],
435
+ },
436
+ {
437
+ title: 'Expected Value',
438
+ keyName: 'expectedValue',
439
+ placeholder: 'e.g. GET',
440
+ tooltip: 'The values to test the attribute against.',
441
+ required: true,
442
+ },
443
+ {
444
+ title: 'JSON Path',
445
+ keyName: 'jsonPath',
446
+ placeholder: 'e.g. $.user.role',
447
+ tooltip: 'An expression used to navigate the JSON structure.',
448
+ required: false,
449
+ renderCondition: (row) => row.condition === 'jsonCondition',
450
+ },
451
+ ];
452
+ const SpanAttributeSampler = ({ value, setValue, formErrors }) => {
282
453
  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 }));
454
+ const mappedValue = (value[KEY] || []).map(({ serviceName, attributeKey, fallbackSamplingRatio, condition }) => {
455
+ const conditionKey = Object.entries(condition).filter(([k, v]) => v)[0][0];
456
+ return {
457
+ serviceName,
458
+ attributeKey,
459
+ fallbackSamplingRatio,
460
+ condition: conditionKey,
461
+ operation: condition[conditionKey]?.operation,
462
+ expectedValue: condition[conditionKey]?.expectedValue,
463
+ jsonPath: condition[conditionKey]?.jsonPath,
464
+ };
465
+ });
466
+ const handleChange = (arr) => {
467
+ const mapped = arr.map(({ serviceName, attributeKey, fallbackSamplingRatio, condition, operation, expectedValue, jsonPath }) => {
468
+ const row = {
469
+ serviceName,
470
+ attributeKey,
471
+ fallbackSamplingRatio: Number(fallbackSamplingRatio),
472
+ condition: {
473
+ [condition]: {
474
+ operation,
475
+ expectedValue,
476
+ },
477
+ },
478
+ };
479
+ if (jsonPath) {
480
+ row.condition[condition].jsonPath = jsonPath;
481
+ }
482
+ return row;
483
+ });
484
+ setValue(KEY, mapped);
485
+ };
486
+ return React.createElement(InputTable, { columns: COLUMNS, value: mappedValue, onChange: handleChange, errorMessage: errorMessage, limitFieldsPerRow: 3 });
286
487
  };
287
488
 
288
489
  const componentsMap$1 = {
@@ -294,6 +495,8 @@ const componentsMap$1 = {
294
495
  [ActionType.ErrorSampler]: ErrorSampler,
295
496
  [ActionType.ProbabilisticSampler]: ProbabilisticSampler,
296
497
  [ActionType.LatencySampler]: LatencySampler,
498
+ [ActionType.ServiceNameSampler]: ServiceNameSampler,
499
+ [ActionType.SpanAttributeSampler]: SpanAttributeSampler,
297
500
  };
298
501
  const CustomFields$1 = ({ actionType, value, setValue, formErrors }) => {
299
502
  if (!actionType)
@@ -7115,8 +7318,8 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
7115
7318
  // from stays the same
7116
7319
  ...previousConnection,
7117
7320
  isValid,
7118
- to: closestHandle && isValid
7119
- ? rendererPointToPoint({ x: closestHandle.x, y: closestHandle.y }, transform)
7321
+ to: result.toHandle && isValid
7322
+ ? rendererPointToPoint({ x: result.toHandle.x, y: result.toHandle.y }, transform)
7120
7323
  : position,
7121
7324
  toHandle: result.toHandle,
7122
7325
  toPosition: isValid && result.toHandle ? result.toHandle.position : oppositePosition[fromHandle.position],
@@ -7216,7 +7419,7 @@ function isValidHandle(event, { handle, connectionMode, fromNodeId, fromHandleId
7216
7419
  ? (isTarget && handleType === 'source') || (!isTarget && handleType === 'target')
7217
7420
  : handleNodeId !== fromNodeId || handleId !== fromHandleId);
7218
7421
  result.isValid = isValid && isValidConnection(connection);
7219
- result.toHandle = getHandle(handleNodeId, handleType, handleId, nodeLookup, connectionMode, false);
7422
+ result.toHandle = getHandle(handleNodeId, handleType, handleId, nodeLookup, connectionMode, true);
7220
7423
  }
7221
7424
  return result;
7222
7425
  }
@@ -9017,11 +9220,12 @@ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true
9017
9220
  return [[], []];
9018
9221
  }, [keyCode]);
9019
9222
  useEffect(() => {
9020
- const target = options?.target || defaultDoc;
9223
+ const target = options?.target ?? defaultDoc;
9224
+ const actInsideInputWithModifier = options?.actInsideInputWithModifier ?? true;
9021
9225
  if (keyCode !== null) {
9022
9226
  const downHandler = (event) => {
9023
9227
  modifierPressed.current = event.ctrlKey || event.metaKey || event.shiftKey || event.altKey;
9024
- const preventAction = (!modifierPressed.current || (modifierPressed.current && !options.actInsideInputWithModifier)) &&
9228
+ const preventAction = (!modifierPressed.current || (modifierPressed.current && !actInsideInputWithModifier)) &&
9025
9229
  isInputDOMNode(event);
9026
9230
  if (preventAction) {
9027
9231
  return false;
@@ -9806,7 +10010,6 @@ function useReactFlow() {
9806
10010
  }
9807
10011
 
9808
10012
  const selected = (item) => item.selected;
9809
- const deleteKeyOptions = { actInsideInputWithModifier: false };
9810
10013
  const win$1 = typeof window !== 'undefined' ? window : undefined;
9811
10014
  /**
9812
10015
  * Hook for handling global key events.
@@ -9816,7 +10019,7 @@ const win$1 = typeof window !== 'undefined' ? window : undefined;
9816
10019
  function useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode, }) {
9817
10020
  const store = useStoreApi();
9818
10021
  const { deleteElements } = useReactFlow();
9819
- const deleteKeyPressed = useKeyPress(deleteKeyCode, deleteKeyOptions);
10022
+ const deleteKeyPressed = useKeyPress(deleteKeyCode, { actInsideInputWithModifier: false });
9820
10023
  const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode, { target: win$1 });
9821
10024
  useEffect(() => {
9822
10025
  if (deleteKeyPressed) {
@@ -13940,9 +14143,9 @@ const Container$d = styled.div `
13940
14143
  gap: 24px;
13941
14144
  padding: 4px;
13942
14145
  `;
13943
- const DataStreamForm = ({ formData, handleFormChange }) => {
14146
+ const DataStreamForm = ({ formData, handleFormChange, formErrors }) => {
13944
14147
  return (React.createElement(Container$d, null,
13945
- React.createElement(Input, { name: 'name', title: DISPLAY_TITLES.STREAM_NAME, required: true, value: formData.name, onChange: ({ target: { value } }) => handleFormChange('name', value) })));
14148
+ React.createElement(Input, { name: 'name', title: DISPLAY_TITLES.STREAM_NAME, placeholder: DISPLAY_TITLES.NAME_YOUR_STREAM_PLACEHOLDER, required: true, value: formData.name, onChange: ({ target: { value } }) => handleFormChange('name', value), errorMessage: formErrors['name'] })));
13946
14149
  };
13947
14150
 
13948
14151
  const FormContainer$3 = styled.div `
@@ -13956,7 +14159,7 @@ const DataStreamDrawer = ({ isOpen, onClose, dataStreamName, updateDataStream })
13956
14159
  const { dataStreams } = useDataStreamStore();
13957
14160
  const drawerRef = useRef(null);
13958
14161
  const [isFormDirty, setIsFormDirty] = useState(false);
13959
- const { formData, handleFormChange, resetFormData, loadFormWithDrawerItem } = useDataStreamFormData({ name: dataStreamName });
14162
+ const { formData, handleFormChange, formErrors, validateForm, resetFormData, loadFormWithDrawerItem } = useDataStreamFormData({ name: dataStreamName });
13960
14163
  const thisItem = useMemo(() => {
13961
14164
  if (!isOpen)
13962
14165
  return null;
@@ -13977,13 +14180,15 @@ const DataStreamDrawer = ({ isOpen, onClose, dataStreamName, updateDataStream })
13977
14180
  onClose();
13978
14181
  };
13979
14182
  const handleSave = () => {
13980
- updateDataStream(dataStreamName, formData);
13981
- setIsFormDirty(false);
13982
- onClose();
14183
+ if (validateForm({ withAlert: true, alertTitle: Crud.Update })) {
14184
+ updateDataStream(dataStreamName, formData);
14185
+ setIsFormDirty(false);
14186
+ onClose();
14187
+ }
13983
14188
  };
13984
14189
  return (React.createElement(OverviewDrawer, { ref: drawerRef, title: thisItem.name, icons: [DataStreamsIcon], hideEditTitleFromEdit: true, isEdit: true, isFormDirty: isFormDirty, onSave: handleSave, onCancel: handleCancel },
13985
14190
  React.createElement(FormContainer$3, null,
13986
- React.createElement(DataStreamForm, { formData: formData, handleFormChange: memoizedHandleFormChange }))));
14191
+ React.createElement(DataStreamForm, { formData: formData, handleFormChange: memoizedHandleFormChange, formErrors: formErrors }))));
13987
14192
  };
13988
14193
 
13989
14194
  const RelativeContainer$1 = styled.div `
@@ -14023,7 +14228,9 @@ const SelectionRow = styled(FlexRow) `
14023
14228
  const Stretch = styled.div `
14024
14229
  width: 100%;
14025
14230
  `;
14026
- const DataStreamSelect = ({ onClickNewDataStream, updateDataStream, deleteDataStream }) => {
14231
+ const DataStreamSelect = ({
14232
+ // onClickNewDataStream,
14233
+ updateDataStream, deleteDataStream, }) => {
14027
14234
  const theme = Theme.useTheme();
14028
14235
  const { dataStreams, selectedStreamName, setSelectedStreamName } = useDataStreamStore();
14029
14236
  const [popupOpen, setPopupOpen] = useState(false);
@@ -14038,11 +14245,7 @@ const DataStreamSelect = ({ onClickNewDataStream, updateDataStream, deleteDataSt
14038
14245
  React.createElement(SelectionButton, { label: name, isSelected: selectedStreamName === name, onClick: () => {
14039
14246
  setSelectedStreamName(name);
14040
14247
  setPopupOpen(false);
14041
- }, color: 'transparent', style: { width: '100%', justifyContent: 'flex-start' } })),
14042
- name !== DEFAULT_DATA_STREAM_NAME && (React.createElement(IconButton, { onClick: () => setDeleteOpenForDataStreamName(name), tooltip: BUTTON_TEXTS.DELETE },
14043
- React.createElement(TrashIcon, null))),
14044
- React.createElement(IconButton, { onClick: () => setEditOpenForDataStreamName(name), tooltip: BUTTON_TEXTS.EDIT },
14045
- React.createElement(EditIcon, null))))), [filteredDataStreams, selectedStreamName]);
14248
+ }, color: 'transparent', style: { width: '100%', justifyContent: 'flex-start' } }))))), [filteredDataStreams, selectedStreamName]);
14046
14249
  return (React.createElement(React.Fragment, null,
14047
14250
  React.createElement(RelativeContainer$1, null,
14048
14251
  React.createElement(Container$c, { "$gap": 0 },
@@ -14052,9 +14255,7 @@ const DataStreamSelect = ({ onClickNewDataStream, updateDataStream, deleteDataSt
14052
14255
  "Data Stream: ",
14053
14256
  selectedStreamName),
14054
14257
  React.createElement(ExtendArrow, { extend: popupOpen }),
14055
- React.createElement(Badge, { label: dataStreams.length })),
14056
- React.createElement(Divider, { orientation: 'vertical', length: '32px', thickness: 2, margin: '0' }),
14057
- React.createElement(AddButton$1, { onClick: onClickNewDataStream, label: BUTTON_TEXTS.NEW })),
14258
+ React.createElement(Badge, { label: dataStreams.length }))),
14058
14259
  popupOpen && (React.createElement(AbsoluteContainer$1, { ref: containerRef },
14059
14260
  React.createElement(SelectionMenuHeader, null,
14060
14261
  React.createElement(Input, { placeholder: 'Search...', icon: SearchIcon, value: searchText, onChange: (e) => setSearchText(e.target.value) })),
@@ -14092,8 +14293,7 @@ const DataFlowActionsMenu = ({ addEntity, onClickNewDataStream, updateDataStream
14092
14293
  };
14093
14294
 
14094
14295
  const DataStreamSelectionForm = forwardRef(({ isModal, onClickSummary }, ref) => {
14095
- const { dataStreams, selectedStreamName } = useDataStreamStore();
14096
- const dataStreamOptions = useMemo(() => dataStreams.map(({ name }) => ({ label: name })), [dataStreams]);
14296
+ const { selectedStreamName } = useDataStreamStore();
14097
14297
  const { formData, handleFormChange, formErrors, validateForm } = useDataStreamFormData({ name: selectedStreamName });
14098
14298
  useImperativeHandle(ref, () => ({
14099
14299
  validateForm,
@@ -14103,7 +14303,7 @@ const DataStreamSelectionForm = forwardRef(({ isModal, onClickSummary }, ref) =>
14103
14303
  React.createElement(FlexColumn, { "$gap": 24 },
14104
14304
  onClickSummary && React.createElement(NoteBackToSummary, { onClick: onClickSummary }),
14105
14305
  React.createElement(SectionTitle, { title: DISPLAY_TITLES.NAME_YOUR_STREAM, description: DISPLAY_TITLES.STREAM_DESCRIPTION }),
14106
- React.createElement(AutocompleteInput, { placeholder: DISPLAY_TITLES.NAME_YOUR_STREAM_PLACEHOLDER, required: true, autoFocus: true, options: dataStreamOptions, defaultText: formData['name'], onTextChange: (v) => handleFormChange('name', v), errorMessage: formErrors['name'] }))));
14306
+ React.createElement(DataStreamForm, { formData: formData, handleFormChange: handleFormChange, formErrors: formErrors }))));
14107
14307
  });
14108
14308
 
14109
14309
  const buildMonitorsList = (exportedSignals) => Object.keys(exportedSignals)
@@ -14116,17 +14316,14 @@ const buildCard$2 = (destination, yamlFields) => {
14116
14316
  { title: DISPLAY_TITLES.TYPE, value: destinationType.type },
14117
14317
  { type: DataCardFieldTypes.Monitors, title: DISPLAY_TITLES.MONITORS, value: buildMonitorsList(exportedSignals) },
14118
14318
  ];
14119
- const parsedFields = safeJsonParse(fields, {});
14120
- const sortedParsedFields = yamlFields.map((field) => ({ key: field.name, value: parsedFields[field.name] ?? null })).filter((item) => item.value !== null) ||
14121
- Object.entries(parsedFields).map(([key, value]) => ({ key, value }));
14122
- sortedParsedFields.map(({ key, value }) => {
14123
- const { displayName, secret, componentProperties, hideFromReadData, customReadDataLabels } = yamlFields.find((field) => field.name === key) || {};
14124
- const shouldHide = !!hideFromReadData?.length
14125
- ? compareCondition(hideFromReadData, yamlFields.map((field) => ({ name: field.name, value: parsedFields[field.name] ?? null })))
14126
- : false;
14319
+ const mappedFields = mapDestinationFieldsForDisplay(destination, yamlFields);
14320
+ const mappedFieldsForConditionCompare = mappedFields.map((field) => ({ name: field.key, value: field.value }));
14321
+ mappedFields.map(({ key, name, value }) => {
14322
+ const { secret, componentProperties, hideFromReadData, customReadDataLabels } = yamlFields.find((field) => field.name === key) || {};
14323
+ const shouldHide = !!hideFromReadData?.length ? compareCondition(hideFromReadData, mappedFieldsForConditionCompare) : false;
14127
14324
  if (!shouldHide) {
14128
14325
  const { type } = safeJsonParse(componentProperties, { type: '' });
14129
- const isSecret = (secret || type === 'password') && !!value.length ? new Array(10).fill('•').join('') : '';
14326
+ const secretPlaceholder = (secret || type === 'password') && !!value.length ? new Array(10).fill('•').join('') : '';
14130
14327
  arr.push({ type: DataCardFieldTypes.Divider });
14131
14328
  if (!!customReadDataLabels?.length) {
14132
14329
  customReadDataLabels.forEach(({ condition, ...custom }) => {
@@ -14140,8 +14337,8 @@ const buildCard$2 = (destination, yamlFields) => {
14140
14337
  }
14141
14338
  else {
14142
14339
  arr.push({
14143
- title: displayName || key,
14144
- value: isSecret || value,
14340
+ title: name,
14341
+ value: secretPlaceholder || value,
14145
14342
  });
14146
14343
  }
14147
14344
  }
@@ -14342,7 +14539,6 @@ const DestinationDrawer = ({ categories, updateDestination, deleteDestination, t
14342
14539
  const isOpen = drawerType !== EntityTypes.Destination;
14343
14540
  const [isEditing, setIsEditing] = useState(false);
14344
14541
  const [isFormDirty, setIsFormDirty] = useState(false);
14345
- // const [thisItem, setThisItem] = useState<Destination | undefined>(undefined)
14346
14542
  const { formData, formErrors, handleFormChange, resetFormData, validateForm, loadFormWithDrawerItem, yamlFields, setYamlFields, dynamicFields, setDynamicFields } = useDestinationFormData({
14347
14543
  // preLoadedFields: thisItem?.fields,
14348
14544
  // TODO: supportedSignals: thisDestination?.supportedSignals,
@@ -14354,19 +14550,7 @@ const DestinationDrawer = ({ categories, updateDestination, deleteDestination, t
14354
14550
  const found = destinationsByStream?.find((x) => x.id === drawerEntityId);
14355
14551
  if (!!found) {
14356
14552
  loadFormWithDrawerItem(found);
14357
- const fields = [];
14358
- const parsedCategories = JSON.parse(JSON.stringify(categories));
14359
- for (const category of parsedCategories) {
14360
- const autoFilledFields = safeJsonParse(found.fields, {});
14361
- const idx = category.items.findIndex((item) => item.type === found.destinationType.type);
14362
- if (idx !== -1) {
14363
- fields.push(...category.items[idx].fields.map((field) => ({
14364
- ...field,
14365
- initialValue: autoFilledFields[field.name],
14366
- })));
14367
- }
14368
- }
14369
- setYamlFields(fields);
14553
+ setYamlFields(getYamlFieldsForDestination(categories, found));
14370
14554
  }
14371
14555
  return found;
14372
14556
  }, [isOpen, drawerEntityId, destinationsByStream]);
@@ -14689,21 +14873,21 @@ const Container$7 = styled.div `
14689
14873
  height: fit-content;
14690
14874
  overflow-y: scroll;
14691
14875
  `;
14692
- const DestinationList = ({ withDelete }) => {
14876
+ const DestinationList = ({ categories, withDelete }) => {
14693
14877
  const { configuredDestinations, configuredDestinationsUpdateOnly } = useSetupStore();
14694
14878
  if (!configuredDestinations.length && !configuredDestinationsUpdateOnly.length) {
14695
14879
  return (React.createElement(CenterThis, null,
14696
14880
  React.createElement(NoDataFound, { title: 'No destinations', subTitle: 'Please add a destination' })));
14697
14881
  }
14698
- return (React.createElement(Container$7, null, configuredDestinations.concat(configuredDestinationsUpdateOnly).map((dest, idx) => (React.createElement(ListItem, { key: `configured-destination-${dest.destinationType.type}-${idx}`, "data-id": `configured-destination-${dest.destinationType.type}`, item: dest, isLastItem: configuredDestinations.length + configuredDestinationsUpdateOnly.length === 1, withDelete: withDelete })))));
14882
+ return (React.createElement(Container$7, null, configuredDestinations.concat(configuredDestinationsUpdateOnly).map((dest, idx) => (React.createElement(ListItem, { key: `configured-destination-${dest.destinationType.type}-${idx}`, "data-id": `configured-destination-${dest.destinationType.type}`, item: dest, yamlFields: getYamlFieldsForDestination(categories, dest), isLastItem: configuredDestinations.length + configuredDestinationsUpdateOnly.length === 1, withDelete: withDelete })))));
14699
14883
  };
14700
- const ListItem = ({ item, isLastItem, withDelete }) => {
14884
+ const ListItem = ({ item, yamlFields, isLastItem, withDelete }) => {
14701
14885
  const [deleteWarning, setDeleteWarning] = useState(false);
14702
14886
  const { icon, iconSrc } = getDestinationIcon(item.destinationType.type);
14703
14887
  const { removeConfiguredDestination, removeConfiguredDestinationUpdateOnly } = useSetupStore();
14704
- const mappedFields = useMemo(() => Object.entries(safeJsonParse(item.fields, {})).map(([k, v]) => ({ title: k, value: v })) || [], [item.fields]);
14888
+ const mappedFields = useMemo(() => mapDestinationFieldsForDisplay(item, yamlFields).map((f) => ({ title: f.name, value: f.value })), [item, yamlFields]);
14705
14889
  return (React.createElement(React.Fragment, null,
14706
- React.createElement(DataTab, { title: item.destinationType.displayName || item.name, subTitle: item.destinationType.type, iconProps: { icon, iconSrc }, visualProps: {
14890
+ React.createElement(DataTab, { title: item.name || item.destinationType.displayName, subTitle: item.destinationType.type, iconProps: { icon, iconSrc }, visualProps: {
14707
14891
  monitors: mapExportedSignals(item.exportedSignals),
14708
14892
  monitorsWithLabels: true,
14709
14893
  }, extendableProps: {
@@ -14751,7 +14935,7 @@ const DestinationSelectionForm = ({ isSourcesListEmpty, goToSources, categories,
14751
14935
  React.createElement(LargeAndWideAddButton, { variant: 'secondary', onClick: onOpen },
14752
14936
  React.createElement(PlusIcon$1, null),
14753
14937
  React.createElement(Text, { color: theme.colors.secondary, size: 14, decoration: 'underline', family: 'secondary' }, DISPLAY_TITLES.ADD_DESTINATION))),
14754
- React.createElement(DestinationList, { withDelete: true }))),
14938
+ React.createElement(DestinationList, { categories: categories, withDelete: true }))),
14755
14939
  React.createElement(DestinationModal, { isOnboarding: true, categories: categories, potentialDestinations: potentialDestinations, updateDestination: () => { }, createDestination: () => { }, testConnection: testConnection })));
14756
14940
  };
14757
14941
 
@@ -14833,7 +15017,7 @@ const DestinationTable = ({ metrics, maxHeight, maxWidth }) => {
14833
15017
  };
14834
15018
 
14835
15019
  const buildCard$1 = (rule) => {
14836
- const { type, ruleName, notes, disabled, profileName, payloadCollection, codeAttributes } = rule;
15020
+ const { type, ruleName, notes, disabled, profileName, payloadCollection, codeAttributes, headersCollection } = rule;
14837
15021
  const arr = [
14838
15022
  { title: DISPLAY_TITLES.TYPE, value: type },
14839
15023
  { type: DataCardFieldTypes.ActiveStatus, title: DISPLAY_TITLES.STATUS, value: String(!disabled) },
@@ -14842,20 +15026,25 @@ const buildCard$1 = (rule) => {
14842
15026
  { title: DISPLAY_TITLES.MANAGED_BY_PROFILE, value: profileName },
14843
15027
  { type: DataCardFieldTypes.Divider },
14844
15028
  ];
14845
- if (!!payloadCollection) {
15029
+ if (payloadCollection) {
14846
15030
  const str = Object.entries(payloadCollection)
14847
- .filter(([key, val]) => !!val)
15031
+ .filter(([key, val]) => val)
14848
15032
  .map(([key, val]) => key)
14849
15033
  .join(', ');
14850
- if (!!str)
15034
+ if (str)
14851
15035
  arr.push({ title: 'Collect', value: str });
14852
15036
  }
14853
- if (!!codeAttributes) {
15037
+ if (codeAttributes) {
14854
15038
  const str = Object.entries(codeAttributes)
14855
- .filter(([key, val]) => !!val)
15039
+ .filter(([key, val]) => val)
14856
15040
  .map(([key, val]) => key)
14857
15041
  .join(', ');
14858
- if (!!str)
15042
+ if (str)
15043
+ arr.push({ title: 'Collect', value: str });
15044
+ }
15045
+ if (headersCollection) {
15046
+ const str = (headersCollection[HeadersCollectionKeyTypes.HeaderKeys] || []).filter((val) => val).join(', ');
15047
+ if (str)
14859
15048
  arr.push({ title: 'Collect', value: str });
14860
15049
  }
14861
15050
  return arr;
@@ -15576,7 +15765,7 @@ const SourceList = ({ isModal = false, withInstances = true, filteredNamespacesA
15576
15765
  (isNamespaceSelected || !onSelectNamespace) &&
15577
15766
  (hasSources ? (React.createElement(RelativeWrapper, { "$addPadding": !onSelectSource },
15578
15767
  React.createElement(AbsoluteWrapper, null,
15579
- React.createElement(Divider, { orientation: 'vertical', length: `${onlyOneSource ? 24 : (sources.length) * 34}px` })),
15768
+ React.createElement(Divider, { orientation: 'vertical', length: `${onlyOneSource ? 24 : sources.length * 34}px` })),
15580
15769
  sources.map((source) => {
15581
15770
  const isSourceSelected = onlySelectedSources.some(({ name }) => name === source.name);
15582
15771
  return React.createElement(SourceRow, { key: `source-${source.name}`, withInstances: withInstances, source: source, namespace: namespace, isSelected: isSourceSelected, onSelect: onSelectSource });
@@ -15604,19 +15793,20 @@ const Container$3 = styled.div `
15604
15793
  height: fit-content;
15605
15794
  overflow-y: scroll;
15606
15795
  `;
15607
- const SetupSummary = ({ onEditStream, onEditSources, onEditDestinations }) => {
15608
- const { selectedStreamName } = useDataStreamStore();
15796
+ const SetupSummary = ({
15797
+ // onEditStream,
15798
+ onEditSources, onEditDestinations, categories, }) => {
15799
+ // const { selectedStreamName } = useDataStreamStore();
15609
15800
  const { configuredSources, configuredDestinations, configuredDestinationsUpdateOnly } = useSetupStore();
15610
15801
  const sourceCount = useMemo(() => Object.values(configuredSources).reduce((total, sourceList) => total + sourceList.filter((s) => s.selected).length, 0), [configuredSources]);
15611
15802
  return (React.createElement(ModalBody, { "$isNotModal": true },
15612
15803
  React.createElement(FlexColumn, { "$gap": 12 },
15613
15804
  React.createElement(SectionTitle, { title: DISPLAY_TITLES.SUMMARY, description: DISPLAY_TITLES.STREAM_CONFIRM }),
15614
15805
  React.createElement(Container$3, null,
15615
- React.createElement(DataCard, { title: DISPLAY_TITLES.STREAM_NAME, action: () => React.createElement(EditButton, { onClick: onEditStream }), data: [{ title: '', value: selectedStreamName }] }),
15616
15806
  React.createElement(DataCard, { title: DISPLAY_TITLES.SELECTED_SOURCES, titleBadge: sourceCount, action: () => React.createElement(EditButton, { onClick: onEditSources }) },
15617
15807
  React.createElement(SourceList, { filteredNamespacesAndSources: configuredSources, withInstances: false })),
15618
15808
  React.createElement(DataCard, { title: DISPLAY_TITLES.SELECTED_DESTINATIONS, titleBadge: configuredDestinations.length + configuredDestinationsUpdateOnly.length, action: () => React.createElement(EditButton, { onClick: onEditDestinations }) },
15619
- React.createElement(DestinationList, null))))));
15809
+ React.createElement(DestinationList, { categories: categories }))))));
15620
15810
  };
15621
15811
 
15622
15812
  var NavIconIds;