@odigos/ui-kit 0.0.27 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.29](https://github.com/odigos-io/ui-kit/compare/ui-kit-v0.0.28...ui-kit-v0.0.29) (2025-05-20)
4
+
5
+
6
+ ### Features
7
+
8
+ * add icon for dynamic destination ([#125](https://github.com/odigos-io/ui-kit/issues/125)) ([19015f0](https://github.com/odigos-io/ui-kit/commit/19015f02948dbfb4397cc9ef0348211ed85761af))
9
+ * add namespace icon ([#127](https://github.com/odigos-io/ui-kit/issues/127)) ([c530096](https://github.com/odigos-io/ui-kit/commit/c5300961fe8b89938dfa1ad179bd8a70690f76ea))
10
+ * add notes "is for all streams" to actions and rules ([#122](https://github.com/odigos-io/ui-kit/issues/122)) ([d399704](https://github.com/odigos-io/ui-kit/commit/d39970425686817299af6dbe4300f7e37720ae21))
11
+ * allow custom subtitle texts in stepper ([#129](https://github.com/odigos-io/ui-kit/issues/129)) ([9ac62c8](https://github.com/odigos-io/ui-kit/commit/9ac62c8e5c42461777bbcc0fd06b95898d7c3dd3))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * add already-configured destination from overview page ([#126](https://github.com/odigos-io/ui-kit/issues/126)) ([40d9a71](https://github.com/odigos-io/ui-kit/commit/40d9a71d6714e1f88667f1cd4152cd431a20bc16))
17
+
18
+ ## [0.0.28](https://github.com/odigos-io/ui-kit/compare/ui-kit-v0.0.27...ui-kit-v0.0.28) (2025-05-19)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * state of source selection ([#118](https://github.com/odigos-io/ui-kit/issues/118)) ([7b73ae3](https://github.com/odigos-io/ui-kit/commit/7b73ae34778d6576a9a3c6645a434ae2ec4a2674))
24
+ * stream name input to include initial value, and validated as required ([#119](https://github.com/odigos-io/ui-kit/issues/119)) ([31a7f97](https://github.com/odigos-io/ui-kit/commit/31a7f9791def013cf1b99dcb36e043d6fa77021a))
25
+
3
26
  ## [0.0.27](https://github.com/odigos-io/ui-kit/compare/ui-kit-v0.0.26...ui-kit-v0.0.27) (2025-05-19)
4
27
 
5
28
 
@@ -16,6 +16,7 @@ interface AutocompleteInputProps extends InputHTMLAttributes<HTMLInputElement> {
16
16
  onTextChange?: (text: string) => void;
17
17
  style?: CSSProperties;
18
18
  disabled?: boolean;
19
+ errorMessage?: string;
19
20
  }
20
21
  declare const AutocompleteInput: FC<AutocompleteInputProps>;
21
22
  export { AutocompleteInput, type AutocompleteInputProps };
@@ -4,6 +4,7 @@ interface StepperProps {
4
4
  data: {
5
5
  stepNumber: number;
6
6
  title: string;
7
+ subtitle?: string;
7
8
  }[];
8
9
  }
9
10
  declare const Stepper: FC<StepperProps>;
package/lib/components.js CHANGED
@@ -1,19 +1,19 @@
1
- import { B as Button } from './index-QaNawEGJ.js';
2
- export { a as AutocompleteInput, b as Badge, a1 as CenterThis, C as Checkbox, c as Code, d as ConditionDetails, D as DataCard, f as DataCardFieldTypes, e as DataCardFields, g as DataTab, h as Divider, i as DocsButton, j as Drawer, l as DrawerFooter, k as DrawerHeader, m as Dropdown, E as ExtendArrow, F as FadeLoader, n as FieldError, o as FieldLabel, a0 as FlexColumn, $ as FlexRow, H as Header, I as IconButton, p as IconGroup, q as IconTitleBadge, r as IconWrapped, s as IconsNav, t as ImageControlled, u as Input, v as InputList, w as InputTable, x as InteractiveTable, K as KeyValueInputsList, M as Modal, a4 as ModalBody, y as MonitorsCheckboxes, z as MonitorsIcons, N as NavigationButtons, G as NoDataFound, J as NotificationNote, a3 as Overlay, S as ScrollX, L as SectionTitle, O as Segment, P as SelectionButton, Q as SkeletonLoader, R as Status, U as Stepper, a5 as TableContainer, a6 as TableTitleWrap, a7 as TableWrap, V as Text, W as TextArea, X as Toggle, T as ToggleCodeComponent, Y as Tooltip, Z as TraceLoader, a2 as VerticalScroll, _ as WarningModal } from './index-QaNawEGJ.js';
3
- export { C as CancelWarning, D as DeleteWarning } from './index-DlCB8lqz.js';
1
+ import { B as Button } from './index-qzll74wE.js';
2
+ export { a as AutocompleteInput, b as Badge, a1 as CenterThis, C as Checkbox, c as Code, d as ConditionDetails, D as DataCard, f as DataCardFieldTypes, e as DataCardFields, g as DataTab, h as Divider, i as DocsButton, j as Drawer, l as DrawerFooter, k as DrawerHeader, m as Dropdown, E as ExtendArrow, F as FadeLoader, n as FieldError, o as FieldLabel, a0 as FlexColumn, $ as FlexRow, H as Header, I as IconButton, p as IconGroup, q as IconTitleBadge, r as IconWrapped, s as IconsNav, t as ImageControlled, u as Input, v as InputList, w as InputTable, x as InteractiveTable, K as KeyValueInputsList, M as Modal, a4 as ModalBody, y as MonitorsCheckboxes, z as MonitorsIcons, N as NavigationButtons, G as NoDataFound, J as NotificationNote, a3 as Overlay, S as ScrollX, L as SectionTitle, O as Segment, P as SelectionButton, Q as SkeletonLoader, R as Status, U as Stepper, a5 as TableContainer, a6 as TableTitleWrap, a7 as TableWrap, V as Text, W as TextArea, X as Toggle, T as ToggleCodeComponent, Y as Tooltip, Z as TraceLoader, a2 as VerticalScroll, _ as WarningModal } from './index-qzll74wE.js';
3
+ export { C as CancelWarning, D as DeleteWarning } from './index-CPGUhlkI.js';
4
4
  import React, { Component, createElement, createContext } from 'react';
5
5
  import Theme from './theme.js';
6
6
  import 'styled-components';
7
7
  import './index-BJxaoI0G.js';
8
8
  import './types.js';
9
9
  import './index-BZS1ijMm.js';
10
- import './index-CTgLYGo-.js';
10
+ import './index-B7MM_DAw.js';
11
11
  import './index-CFnxjzaW.js';
12
12
  import './index-DGel4E-Z.js';
13
13
  import './index-DMXaEyAB.js';
14
14
  import './index-CJs4RDHU.js';
15
15
  import './index-IKusBlIE.js';
16
- import './useTransition-BSKilkmZ.js';
16
+ import './useTransition-n4huKtX2.js';
17
17
  import 'react-dom';
18
18
 
19
19
  const ErrorBoundaryContext = createContext(null);
@@ -3,6 +3,7 @@ export declare const FORM_ALERTS: {
3
3
  FIELD_IS_REQUIRED: string;
4
4
  FORBIDDEN: string;
5
5
  ENTERPRISE_ONLY: (str?: string) => string;
6
+ DEFINED_FOR_ALL_STREAMS: (str: string) => string;
6
7
  CANNOT_EDIT_RULE: string;
7
8
  CANNOT_DELETE_RULE: string;
8
9
  LATENCY_HTTP_ROUTE: string;
package/lib/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ACTION_OPTIONS, B as BUTTON_TEXTS, D as DISPLAY_TITLES, F as FORM_ALERTS, I as INSTRUMENTATION_RULE_OPTIONS, M as MONITORS_OPTIONS } from './index-CTgLYGo-.js';
1
+ export { A as ACTION_OPTIONS, B as BUTTON_TEXTS, D as DISPLAY_TITLES, F as FORM_ALERTS, I as INSTRUMENTATION_RULE_OPTIONS, M as MONITORS_OPTIONS } from './index-B7MM_DAw.js';
2
2
  export { D as DESTINATION_CATEGORIES } from './index-Dqief9td.js';
3
3
  import './types.js';
4
4
  import './index-CFnxjzaW.js';
@@ -4,6 +4,7 @@ interface DataStreamSelectionFormProps {
4
4
  onClickSummary?: () => void;
5
5
  }
6
6
  interface DataStreamSelectionFormRef {
7
+ validateForm: () => boolean;
7
8
  getFormValues: () => {
8
9
  name: string;
9
10
  };
@@ -5,6 +5,7 @@ interface DestinationModalProps {
5
5
  categories: DestinationCategories;
6
6
  potentialDestinations: DestinationOption[];
7
7
  createDestination: (destination: DestinationFormData) => void;
8
+ updateDestination: (id: string, destination: DestinationFormData) => void;
8
9
  testConnection: TestConnectionFunc;
9
10
  }
10
11
  declare const DestinationModal: FC<DestinationModalProps>;
package/lib/containers.js CHANGED
@@ -1,25 +1,25 @@
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 { D as DISPLAY_TITLES, A as ACTION_OPTIONS, M as MONITORS_OPTIONS, B as BUTTON_TEXTS, I as INSTRUMENTATION_RULE_OPTIONS, F as FORM_ALERTS } from './index-CTgLYGo-.js';
3
+ import { D as DISPLAY_TITLES, A as ACTION_OPTIONS, F as FORM_ALERTS, M as MONITORS_OPTIONS, B as BUTTON_TEXTS, I as INSTRUMENTATION_RULE_OPTIONS } from './index-B7MM_DAw.js';
4
4
  import { ActionType, EntityTypes, StatusType, Crud, OtherStatus, NodeTypes, AddNodeTypes, EdgeTypes, FieldTypes, SignalType, 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, M as Modal, N as NavigationButtons, a4 as ModalBody, 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, a0 as FlexColumn, 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, J as NotificationNote, U as Stepper, I as IconButton, e as DataCardFields, s as IconsNav, p as IconGroup } from './index-QaNawEGJ.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-qzll74wE.js';
6
6
  import { h as usePendingStore, g as useNotificationStore, b as useDrawerStore, c as useEntityStore, f as useModalStore, d as useFilterStore, s as styleInject, i as useSelectedStore, e as useInstrumentStore, a as useDataStreamStore, k as getEntityId, j as useSetupStore, u as useDarkMode } from './index-DMXaEyAB.js';
7
7
  import Theme from './theme.js';
8
8
  import { i as isEmpty, s as safeJsonParse } from './index-BZS1ijMm.js';
9
9
  import { i as CheckCircledIcon, O as OdigosLogo } from './index-IKusBlIE.js';
10
10
  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-CamnKrev.js';
11
11
  import { g as getActionIcon, a as getInstrumentationRuleIcon } from './index-CFnxjzaW.js';
12
- import { u as useActionFormData, a as useClickNode, c as useDestinationFormData, b as useClickNotification, d as useSourceFormData, e as useSourceSelectionFormData } from './useSourceSelectionFormData-DAxuVELF.js';
13
- import { d as useKeyDown, e as useOnClickOutside, u as useContainerSize, c as useInstrumentationRuleFormData, g as useTransition, f as useTimeAgo, a as useCopy } from './useTransition-BSKilkmZ.js';
12
+ import { u as useActionFormData, a as useClickNode, c as useDestinationFormData, b as useClickNotification, d as useSourceFormData, e as useSourceSelectionFormData } from './useSourceSelectionFormData-Bw2p1Fr4.js';
13
+ import { d as useKeyDown, e as useOnClickOutside, u as useContainerSize, b as useGenericForm, c as useInstrumentationRuleFormData, g as useTransition, f as useTimeAgo, a as useCopy } from './useTransition-n4huKtX2.js';
14
14
  import { E as EditIcon } from './index-CWbxXTof.js';
15
15
  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-BJxaoI0G.js';
16
- import { D as DeleteWarning, C as CancelWarning } from './index-DlCB8lqz.js';
16
+ import { D as DeleteWarning, C as CancelWarning } from './index-CPGUhlkI.js';
17
17
  import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-CJs4RDHU.js';
18
- 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-BfatCMWq.js';
18
+ 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-DYNMhZMX.js';
19
19
  import { createPortal } from 'react-dom';
20
- import { N as NoteBackToSummary, E as EditButton } from './index-KyiD2AtF.js';
20
+ import { N as NoteBackToSummary, E as EditButton } from './index-CnBjimup.js';
21
21
  import { D as DESTINATION_CATEGORIES } from './index-Dqief9td.js';
22
- import { a6 as RulesIcon, a7 as SourcesIcon, a3 as ActionsIcon, a4 as DestinationsIcon } from './index-BRW_Nl-n.js';
22
+ import { a6 as RulesIcon, a7 as SourcesIcon, a3 as ActionsIcon, a4 as DestinationsIcon } from './index-BbbCCewR.js';
23
23
  import './index-DGel4E-Z.js';
24
24
  import './index-7-KCQK-x.js';
25
25
 
@@ -535,6 +535,10 @@ const ActionDrawer = ({ updateAction, deleteAction }) => {
535
535
  React.createElement(DataCard, { title: DISPLAY_TITLES.ACTION_DETAILS, data: !!thisItem ? buildCard$3(thisItem) : [] })))));
536
536
  };
537
537
 
538
+ const GapAndMargin$1 = styled(FlexColumn) `
539
+ margin-top: 24px;
540
+ gap: 12px;
541
+ `;
538
542
  const ActionModal = ({ createAction }) => {
539
543
  const { currentModal, setCurrentModal } = useModalStore();
540
544
  const isOpen = currentModal === EntityTypes.Action;
@@ -568,7 +572,9 @@ const ActionModal = ({ createAction }) => {
568
572
  ] }) },
569
573
  React.createElement(ModalBody, null,
570
574
  React.createElement(SectionTitle, { title: 'Select Action', description: 'Select an action to modify telemetry data before it`s sent to destinations. Choose an action type and configure its details.' }),
571
- React.createElement(AutocompleteInput, { options: ACTION_OPTIONS, selectedOption: selectedItem, onOptionSelect: (opt) => handleSelect(opt), style: { marginTop: '24px' }, autoFocus: !selectedItem?.type }),
575
+ React.createElement(GapAndMargin$1, null,
576
+ React.createElement(NotificationNote, { type: StatusType.Warning, message: FORM_ALERTS.DEFINED_FOR_ALL_STREAMS(DISPLAY_TITLES.ACTIONS) }),
577
+ React.createElement(AutocompleteInput, { options: ACTION_OPTIONS, selectedOption: selectedItem, onOptionSelect: (opt) => handleSelect(opt), autoFocus: !selectedItem?.type })),
572
578
  !!selectedItem?.type ? (React.createElement("div", null,
573
579
  React.createElement(Divider, { margin: '16px 0' }),
574
580
  React.createElement(ActionForm, { action: selectedItem, formData: formData, formErrors: formErrors, handleFormChange: handleFormChange }))) : null)));
@@ -13999,19 +14005,30 @@ const DataFlowActionsMenu = ({ addEntity, onClickNewDataStream }) => {
13999
14005
  };
14000
14006
 
14001
14007
  const DataStreamSelectionForm = forwardRef(({ isModal, onClickSummary }, ref) => {
14002
- const { dataStreams } = useDataStreamStore();
14003
- const [nameInput, setNameInput] = useState('');
14008
+ const { selectedStreamName, dataStreams } = useDataStreamStore();
14009
+ const { formData, handleFormChange, formErrors, handleErrorChange } = useGenericForm({
14010
+ name: selectedStreamName,
14011
+ });
14004
14012
  useImperativeHandle(ref, () => ({
14005
- getFormValues: () => ({
14006
- name: nameInput,
14007
- }),
14013
+ validateForm: () => {
14014
+ let isValid = true;
14015
+ if (!formData['name']) {
14016
+ isValid = false;
14017
+ handleErrorChange('name', FORM_ALERTS.FIELD_IS_REQUIRED);
14018
+ }
14019
+ else {
14020
+ handleErrorChange('name', undefined);
14021
+ }
14022
+ return isValid;
14023
+ },
14024
+ getFormValues: () => formData,
14008
14025
  }));
14009
14026
  const dataStreamOptions = useMemo(() => dataStreams.map(({ name }) => ({ label: name })), [dataStreams]);
14010
14027
  return (React.createElement(ModalBody, { "$isNotModal": !isModal, "$minHeight": '70vh' },
14011
14028
  React.createElement(FlexColumn, { "$gap": 24 },
14012
14029
  onClickSummary && React.createElement(NoteBackToSummary, { onClick: onClickSummary }),
14013
14030
  React.createElement(SectionTitle, { title: DISPLAY_TITLES.NAME_YOUR_STREAM, description: DISPLAY_TITLES.STREAM_DESCRIPTION }),
14014
- React.createElement(AutocompleteInput, { placeholder: DISPLAY_TITLES.NAME_YOUR_STREAM_PLACEHOLDER, autoFocus: true, options: dataStreamOptions, defaultText: nameInput, onTextChange: setNameInput }))));
14031
+ 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'] }))));
14015
14032
  });
14016
14033
 
14017
14034
  const buildMonitorsList = (exportedSignals) => Object.keys(exportedSignals)
@@ -14464,19 +14481,19 @@ const SideMenuWrapper = styled.div `
14464
14481
  display: none;
14465
14482
  }
14466
14483
  `;
14467
- const DestinationModal = ({ isOnboarding, categories, potentialDestinations, createDestination, testConnection }) => {
14484
+ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, createDestination, updateDestination, testConnection }) => {
14468
14485
  const { destinations } = useEntityStore();
14469
14486
  const { selectedStreamName } = useDataStreamStore();
14470
14487
  const { currentModal, setCurrentModal } = useModalStore();
14471
14488
  const { addConfiguredDestination, addConfiguredDestinationUpdateOnly } = useSetupStore();
14472
14489
  const isOpen = currentModal === EntityTypes.Destination;
14473
14490
  const [selectedItem, setSelectedItem] = useState(undefined);
14474
- const { formData, formErrors, handleFormChange, resetFormData, validateForm, setYamlFields, dynamicFields, setDynamicFields } = useDestinationFormData({
14491
+ const { formData, formErrors, handleFormChange, resetFormData, validateForm, setYamlFields, dynamicFields, setDynamicFields, loadFormWithDrawerItem } = useDestinationFormData({
14475
14492
  supportedSignals: selectedItem?.supportedSignals,
14476
14493
  preLoadedFields: selectedItem?.fields,
14477
14494
  });
14478
14495
  const getDestPayload = (alreadyConfigDest) => {
14479
- const fields = alreadyConfigDest ? safeJsonParse(alreadyConfigDest.fields, {}) : {};
14496
+ const fields = {};
14480
14497
  if (!alreadyConfigDest) {
14481
14498
  dynamicFields.forEach((f) => {
14482
14499
  fields[f.name] = (f.componentType === FieldTypes.Dropdown ? f.value?.value || '' : f.value);
@@ -14488,7 +14505,7 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
14488
14505
  dataStreamNames: alreadyConfigDest?.dataStreamNames || [],
14489
14506
  conditions: alreadyConfigDest?.conditions || [],
14490
14507
  exportedSignals: alreadyConfigDest?.exportedSignals || formData.exportedSignals,
14491
- fields: JSON.stringify(fields),
14508
+ fields: alreadyConfigDest?.fields || JSON.stringify(fields),
14492
14509
  destinationType: alreadyConfigDest?.destinationType || {
14493
14510
  type: selectedItem.type,
14494
14511
  displayName: selectedItem.displayName,
@@ -14501,15 +14518,29 @@ const DestinationModal = ({ isOnboarding, categories, potentialDestinations, cre
14501
14518
  };
14502
14519
  };
14503
14520
  const handleAdd = (alreadyConfigDest) => {
14504
- // Handle case from already configured
14505
- if (alreadyConfigDest)
14506
- return addConfiguredDestinationUpdateOnly(getDestPayload(alreadyConfigDest));
14507
14521
  // Handle new cases from onboarding
14508
- if (isOnboarding)
14509
- return addConfiguredDestination(getDestPayload());
14522
+ if (isOnboarding && !alreadyConfigDest) {
14523
+ const payload = getDestPayload();
14524
+ addConfiguredDestination(payload);
14525
+ }
14526
+ // Handle already configured cases from onboarding
14527
+ else if (isOnboarding && alreadyConfigDest) {
14528
+ const payload = getDestPayload(alreadyConfigDest);
14529
+ addConfiguredDestinationUpdateOnly(payload);
14530
+ }
14510
14531
  // Handle new cases from overview
14511
- else
14512
- return createDestination(formData);
14532
+ else if (!isOnboarding && !alreadyConfigDest) {
14533
+ createDestination(formData);
14534
+ }
14535
+ // Handle already configured cases from overview
14536
+ else if (!isOnboarding && alreadyConfigDest) {
14537
+ const payload = getDestPayload(alreadyConfigDest);
14538
+ const payloadForm = loadFormWithDrawerItem(payload);
14539
+ updateDestination(alreadyConfigDest.id, payloadForm);
14540
+ }
14541
+ else {
14542
+ console.warn('DestinationModal: handleAdd: No action taken, no destination or already configured destination found');
14543
+ }
14513
14544
  };
14514
14545
  const handleClose = () => {
14515
14546
  resetFormData();
@@ -14646,7 +14677,7 @@ const DestinationSelectionForm = ({ isSourcesListEmpty, goToSources, categories,
14646
14677
  React.createElement(PlusIcon$1, null),
14647
14678
  React.createElement(Text, { color: theme.colors.secondary, size: 14, decoration: 'underline', family: 'secondary' }, DISPLAY_TITLES.ADD_DESTINATION))),
14648
14679
  React.createElement(DestinationList, { withDelete: true }))),
14649
- React.createElement(DestinationModal, { isOnboarding: true, categories: categories, potentialDestinations: potentialDestinations, createDestination: () => { }, testConnection: testConnection })));
14680
+ React.createElement(DestinationModal, { isOnboarding: true, categories: categories, potentialDestinations: potentialDestinations, updateDestination: () => { }, createDestination: () => { }, testConnection: testConnection })));
14650
14681
  };
14651
14682
 
14652
14683
  const columns$2 = [
@@ -15030,6 +15061,10 @@ const InstrumentationRuleDrawer = ({ updateInstrumentationRule, deleteInstrument
15030
15061
  } }))) : (React.createElement(DataCard, { title: 'Instrumentation Rule Details', data: !!thisItem ? buildCard$1(thisItem) : [] }))));
15031
15062
  };
15032
15063
 
15064
+ const GapAndMargin = styled(FlexColumn) `
15065
+ margin-top: 24px;
15066
+ gap: 12px;
15067
+ `;
15033
15068
  const InstrumentationRuleModal = ({ isEnterprise, createInstrumentationRule }) => {
15034
15069
  const { currentModal, setCurrentModal } = useModalStore();
15035
15070
  const isOpen = currentModal === EntityTypes.InstrumentationRule;
@@ -15063,8 +15098,9 @@ const InstrumentationRuleModal = ({ isEnterprise, createInstrumentationRule }) =
15063
15098
  ] }) },
15064
15099
  React.createElement(ModalBody, null,
15065
15100
  React.createElement(SectionTitle, { title: 'Select Instrumentation Rule', description: 'Define how telemetry is recorded from your application. Choose a rule type and configure the details.' }),
15066
- !isEnterprise && React.createElement(NotificationNote, { type: StatusType.Default, message: FORM_ALERTS.ENTERPRISE_ONLY('Instrumentation Rules'), style: { marginTop: '24px' } }),
15067
- React.createElement(AutocompleteInput, { options: INSTRUMENTATION_RULE_OPTIONS, selectedOption: selectedItem, onOptionSelect: (opt) => handleSelect(opt), style: { marginTop: isEnterprise ? '24px' : '12px' }, autoFocus: !selectedItem?.type }),
15101
+ React.createElement(GapAndMargin, null,
15102
+ !isEnterprise ? (React.createElement(NotificationNote, { type: StatusType.Default, message: FORM_ALERTS.ENTERPRISE_ONLY(DISPLAY_TITLES.INSTRUMENTATION_RULES) })) : (React.createElement(NotificationNote, { type: StatusType.Warning, message: FORM_ALERTS.DEFINED_FOR_ALL_STREAMS(DISPLAY_TITLES.INSTRUMENTATION_RULES) })),
15103
+ React.createElement(AutocompleteInput, { options: INSTRUMENTATION_RULE_OPTIONS, selectedOption: selectedItem, onOptionSelect: (opt) => handleSelect(opt), autoFocus: !selectedItem?.type })),
15068
15104
  !!selectedItem?.type ? (React.createElement("div", null,
15069
15105
  React.createElement(Divider, { margin: '16px 0' }),
15070
15106
  React.createElement(InstrumentationRuleForm, { rule: selectedItem, formData: formData, formErrors: formErrors, handleFormChange: handleFormChange }))) : null)));
@@ -15397,8 +15433,8 @@ const NamespaceItem = styled.div `
15397
15433
  }
15398
15434
  `;
15399
15435
  const SourceItem = styled(NamespaceItem) `
15400
- width: calc(100% - 50px);
15401
- margin-left: auto;
15436
+ width: calc(100% - 100px);
15437
+ margin: 0 auto;
15402
15438
  padding: 8px;
15403
15439
  `;
15404
15440
  const RelativeWrapper = styled.div `
@@ -15423,6 +15459,7 @@ const SourceList = ({ isModal = false, withInstances = true, filteredNamespacesA
15423
15459
  if (!matrix?.length) {
15424
15460
  return (React.createElement(CenterThis, null, namespacesLoading ? (React.createElement(FadeLoader, null)) : (React.createElement(NoDataFound, { title: DISPLAY_TITLES.NO_SOURCES, subTitle: onSelectNamespace ? DISPLAY_TITLES.PLEASE_MAKE_SURE_UNIGNORED_NAMESPACES : DISPLAY_TITLES.PLEASE_ADD_SOURCE }))));
15425
15461
  }
15462
+ const NamespaceIcon = getEntityIcon(EntityTypes.Namespace);
15426
15463
  return (React.createElement(Container$4, { "$isModal": isModal }, matrix.map(([namespace, sources]) => {
15427
15464
  const sourcesForNamespace = selectedSources?.[namespace] || [];
15428
15465
  const onlySelectedSources = sourcesForNamespace.filter(({ selected }) => selected);
@@ -15431,12 +15468,14 @@ const SourceList = ({ isModal = false, withInstances = true, filteredNamespacesA
15431
15468
  const isNamespaceAllSourcesSelected = onlySelectedSources.length > 0 && onlySelectedSources.length === sources.length;
15432
15469
  const isNamespacePartiallySourcesSelected = onlySelectedSources.length > 0 && onlySelectedSources.length !== sources.length;
15433
15470
  const hasSources = sources.length > 0;
15471
+ const onlyOneSource = sources.length === 1;
15434
15472
  if (!onSelectNamespace && !hasSources)
15435
15473
  return null;
15436
15474
  return (React.createElement(Group, { key: `namespace-${namespace}`, "data-id": `namespace-${namespace}`, "$selected": isNamespaceAllSourcesSelected, "$isOpen": isNamespaceSelected },
15437
15475
  React.createElement(NamespaceItem, { "$selected": isNamespaceAllSourcesSelected, "$withClick": !!onSelectNamespace, onClick: () => onSelectNamespace?.(namespace) },
15438
15476
  React.createElement(FlexRow, { "$gap": 12 },
15439
15477
  onSelectNamespace && React.createElement(Checkbox, { partiallyChecked: isNamespacePartiallySourcesSelected, value: isNamespaceAllSourcesSelected, onChange: (bool) => onSelectNamespace(namespace, bool) }),
15478
+ React.createElement(NamespaceIcon, null),
15440
15479
  React.createElement(Text, null, namespace)),
15441
15480
  React.createElement(FlexRow, { "$gap": 12 },
15442
15481
  React.createElement(SelectionCount, { size: 10, color: theme.text.grey }, isNamespaceLoaded ? `${onlySelectedSources.length}/${sources.length}` : null),
@@ -15444,7 +15483,7 @@ const SourceList = ({ isModal = false, withInstances = true, filteredNamespacesA
15444
15483
  (isNamespaceSelected || !onSelectNamespace) &&
15445
15484
  (hasSources ? (React.createElement(RelativeWrapper, { "$addPadding": !onSelectSource },
15446
15485
  React.createElement(AbsoluteWrapper, null,
15447
- React.createElement(Divider, { orientation: 'vertical', length: `${(sources.length || 0) * 36}px` })),
15486
+ React.createElement(Divider, { orientation: 'vertical', length: `${onlyOneSource ? 24 : (sources.length) * 34}px` })),
15448
15487
  sources.map((source) => {
15449
15488
  const isSourceSelected = onlySelectedSources.some(({ name }) => name === source.name);
15450
15489
  return React.createElement(SourceRow, { key: `source-${source.name}`, withInstances: withInstances, source: source, namespace: namespace, isSelected: isSourceSelected, onSelect: onSelectSource });
@@ -15455,10 +15494,11 @@ const SourceRow = ({ withInstances, source, namespace, isSelected, onSelect, })
15455
15494
  return (React.createElement(SourceItem, { "data-id": `source-${source.name}`, "$selected": isSelected, "$withClick": !!onSelect, onClick: () => onSelect?.(source) },
15456
15495
  React.createElement(FlexRow, { "$gap": 12 },
15457
15496
  onSelect && React.createElement(Checkbox, { value: isSelected, onChange: () => onSelect(source, namespace) }),
15458
- React.createElement(Text, null, source.name),
15459
- React.createElement(Text, { opacity: 0.8, size: 10 },
15460
- withInstances ? `${source.numberOfInstances || 0} running instance${source.numberOfInstances !== 1 ? 's' : ''} • ` : '',
15461
- source.kind))));
15497
+ React.createElement(FlexRow, { "$gap": 4 },
15498
+ React.createElement(Text, null, source.name),
15499
+ React.createElement(Text, { opacity: 0.8, size: 10 },
15500
+ withInstances ? ` • ${source.numberOfInstances || 0} running instance${source.numberOfInstances !== 1 ? 's' : ''}` : '',
15501
+ ` • ${source.kind}`)))));
15462
15502
  };
15463
15503
 
15464
15504
  const Container$3 = styled.div `
@@ -15763,10 +15803,10 @@ const SearchWrapper = styled.div `
15763
15803
  `;
15764
15804
  const SourceSelectionForm = forwardRef(({ isModal, fetchSingleNamespace, onClickSummary }, ref) => {
15765
15805
  const formState = useSourceSelectionFormData({ fetchSingleNamespace });
15766
- const { recordedInitialSources, selectedSources, getApiSourcesPayload, getApiFutureAppsPayload, searchText, setSearchText, showSelectedOnly, setShowSelectedOnly } = formState;
15806
+ const { availableSources, selectedSources, getApiSourcesPayload, getApiFutureAppsPayload, searchText, setSearchText, showSelectedOnly, setShowSelectedOnly } = formState;
15767
15807
  useImperativeHandle(ref, () => ({
15768
15808
  getFormValues: () => ({
15769
- initial: recordedInitialSources,
15809
+ initial: availableSources,
15770
15810
  apps: getApiSourcesPayload(),
15771
15811
  futureApps: getApiFutureAppsPayload(),
15772
15812
  }),
package/lib/functions.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export { c as capitalizeFirstLetter, f as flattenObjectKeys, g as getMonitorIcon, a as getProgrammingLanguageIcon, b as getStatusIcon, m as mapConditions, p as parseJsonStringToPrettyString, r as removeEmptyValuesFromObject, s as safeJsonStringify, d as splitCamelString } from './index-CJs4RDHU.js';
2
- export { c as compareCondition, d as deepClone, f as filterActions, a as filterDestinations, b as filterDestinationsByStream, e as filterSources, g as filterSourcesByStream, h as formatBytes, i as getConditionsBooleans, k as getContainersIcons, j as getContainersInstrumentedCount, l as getDestinationIcon, m as getEntityIcon, n as getEntityLabel, o as getMetricForEntity, p as getPlatformIcon, q as getPlatformLabel, r as getValueForRange, s as getWorkloadId, t as isOverTime, u as mapExportedSignals, v as sleep } from './index-BfatCMWq.js';
2
+ export { c as compareCondition, d as deepClone, f as filterActions, a as filterDestinations, b as filterDestinationsByStream, e as filterSources, g as filterSourcesByStream, h as formatBytes, i as getConditionsBooleans, k as getContainersIcons, j as getContainersInstrumentedCount, l as getDestinationIcon, m as getEntityIcon, n as getEntityLabel, o as getMetricForEntity, p as getPlatformIcon, q as getPlatformLabel, r as getValueForRange, s as getWorkloadId, t as isOverTime, u as mapExportedSignals, v as sleep } from './index-DYNMhZMX.js';
3
3
  export { g as getActionIcon, a as getInstrumentationRuleIcon } from './index-CFnxjzaW.js';
4
4
  export { k as getEntityId } from './index-DMXaEyAB.js';
5
5
  export { g as getIdFromSseTarget } from './index-7-KCQK-x.js';
@@ -10,7 +10,7 @@ import 'styled-components';
10
10
  import './index-DGel4E-Z.js';
11
11
  import './theme.js';
12
12
  import './index-IKusBlIE.js';
13
- import './index-BRW_Nl-n.js';
13
+ import './index-BbbCCewR.js';
14
14
 
15
15
  const cleanObjectEmptyStringsValues = (obj) => {
16
16
  const cleanArray = (arr) => arr.filter((item) => {
@@ -12,7 +12,7 @@ export declare const useDestinationFormData: (params?: Params) => {
12
12
  withAlert?: boolean;
13
13
  alertTitle?: string;
14
14
  }) => boolean;
15
- loadFormWithDrawerItem: ({ destinationType: { type }, name, exportedSignals, fields }: Destination) => void;
15
+ loadFormWithDrawerItem: ({ destinationType: { type }, name, exportedSignals, fields }: Destination) => DestinationFormData;
16
16
  yamlFields: DestinationYamlProperties[];
17
17
  setYamlFields: import("react").Dispatch<import("react").SetStateAction<DestinationYamlProperties[]>>;
18
18
  dynamicFields: DestinationDynamicField[];
@@ -6,7 +6,7 @@ interface UseSourceFormDataParams {
6
6
  fetchSingleNamespace: FetchSingleNamespace;
7
7
  }
8
8
  export interface UseSourceSelectionFormData {
9
- recordedInitialSources: AvailableSourcesByNamespace;
9
+ availableSources: AvailableSourcesByNamespace;
10
10
  filteredNamespacesAndSources: AvailableSourcesByNamespace;
11
11
  getApiSourcesPayload: () => SourceSelectionFormData;
12
12
  getApiFutureAppsPayload: () => NamespaceSelectionFormData;
package/lib/hooks.js CHANGED
@@ -1,11 +1,11 @@
1
- export { u as useActionFormData, a as useClickNode, b as useClickNotification, c as useDestinationFormData, d as useSourceFormData, e as useSourceSelectionFormData } from './useSourceSelectionFormData-DAxuVELF.js';
2
- export { u as useContainerSize, a as useCopy, b as useGenericForm, c as useInstrumentationRuleFormData, d as useKeyDown, e as useOnClickOutside, f as useTimeAgo, g as useTransition } from './useTransition-BSKilkmZ.js';
1
+ export { u as useActionFormData, a as useClickNode, b as useClickNotification, c as useDestinationFormData, d as useSourceFormData, e as useSourceSelectionFormData } from './useSourceSelectionFormData-Bw2p1Fr4.js';
2
+ export { u as useContainerSize, a as useCopy, b as useGenericForm, c as useInstrumentationRuleFormData, d as useKeyDown, e as useOnClickOutside, f as useTimeAgo, g as useTransition } from './useTransition-n4huKtX2.js';
3
3
  import './types.js';
4
4
  import 'react';
5
5
  import './index-DMXaEyAB.js';
6
6
  import 'styled-components';
7
7
  import './index-BZS1ijMm.js';
8
- import './index-CTgLYGo-.js';
8
+ import './index-B7MM_DAw.js';
9
9
  import './index-CFnxjzaW.js';
10
10
  import './index-DGel4E-Z.js';
11
11
  import './theme.js';
package/lib/icons.js CHANGED
@@ -5,7 +5,7 @@ export { A as ArrowIcon, f as CheckIcon, C as CodeIcon, a as CopyIcon, g as Cros
5
5
  import React from 'react';
6
6
  import Theme from './theme.js';
7
7
  export { E as EditIcon } from './index-CWbxXTof.js';
8
- export { a3 as ActionsIcon, A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, c as AwsCloudwatchLogo, d as AwsS3Logo, e as AwsXrayLogo, f as AxiomLogo, B as BetterStackLogo, g as BlobStorageLogo, h as BonreeLogo, C as CauselyLogo, i as ChecklyLogo, j as ChronosphereLogo, k as ClickhouseLogo, l as CoralogixLogo, D as Dash0Logo, m as DatadogLogo, a4 as DestinationsIcon, n as DynatraceLogo, E as ElasticApmLogo, o as ElasticSearchLogo, G as GigapipeLogo, p as GoogleCloudPlatformLogo, q as GrafanaLogo, r as GreptimeLogo, s as GroundcoverLogo, H as HoneycombLogo, t as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, u as LightstepLogo, v as LogzioLogo, w as LokiLogo, x as LumigoLogo, M as MiddlewareLogo, a5 as NamespacesIcon, N as NewRelicLogo, O as ObserveLogo, y as OneUptimeLogo, z as OpenObserveLogo, F as OpenTelemetryLogo, P as OpsVerseLogo, Q as OracleLogo, R as PrometheusLogo, S as QrynLogo, T as QuickwitLogo, a6 as RulesIcon, U as SeqLogo, W as SignozLogo, a7 as SourcesIcon, X as SplunkLogo, Y as SumoLogicLogo, Z as TelemetryHubLogo, _ as TempoLogo, $ as TingyunLogo, a0 as TraceloopLogo, a1 as UptraceLogo, a2 as VictoriaMetricsLogo, V as VmLogo } from './index-BRW_Nl-n.js';
8
+ export { a3 as ActionsIcon, A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, c as AwsCloudwatchLogo, d as AwsS3Logo, e as AwsXrayLogo, f as AxiomLogo, B as BetterStackLogo, g as BlobStorageLogo, h as BonreeLogo, C as CauselyLogo, i as ChecklyLogo, j as ChronosphereLogo, k as ClickhouseLogo, l as CoralogixLogo, D as Dash0Logo, m as DatadogLogo, a4 as DestinationsIcon, n as DynatraceLogo, E as ElasticApmLogo, o as ElasticSearchLogo, G as GigapipeLogo, p as GoogleCloudPlatformLogo, q as GrafanaLogo, r as GreptimeLogo, s as GroundcoverLogo, H as HoneycombLogo, t as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, u as LightstepLogo, v as LogzioLogo, w as LokiLogo, x as LumigoLogo, M as MiddlewareLogo, a5 as NamespacesIcon, N as NewRelicLogo, O as ObserveLogo, y as OneUptimeLogo, z as OpenObserveLogo, F as OpenTelemetryLogo, P as OpsVerseLogo, Q as OracleLogo, R as PrometheusLogo, S as QrynLogo, T as QuickwitLogo, a6 as RulesIcon, U as SeqLogo, W as SignozLogo, a7 as SourcesIcon, X as SplunkLogo, Y as SumoLogicLogo, Z as TelemetryHubLogo, _ as TempoLogo, $ as TingyunLogo, a0 as TraceloopLogo, a1 as UptraceLogo, a2 as VictoriaMetricsLogo, V as VmLogo } from './index-BbbCCewR.js';
9
9
  import './index-DMXaEyAB.js';
10
10
  import './types.js';
11
11
  import 'styled-components';
@@ -130,6 +130,7 @@ const FORM_ALERTS = {
130
130
  FIELD_IS_REQUIRED: 'This field is required',
131
131
  FORBIDDEN: 'Forbidden',
132
132
  ENTERPRISE_ONLY: (str = 'This') => `${str} is an Enterprise feature. Please upgrade your plan.`,
133
+ DEFINED_FOR_ALL_STREAMS: (str) => `${str} are defined for all Data Streams.`,
133
134
  CANNOT_EDIT_RULE: 'Cannot edit a system-managed instrumentation rule',
134
135
  CANNOT_DELETE_RULE: 'Cannot delete a system-managed instrumentation rule',
135
136
  LATENCY_HTTP_ROUTE: 'HTTP route must start with a forward slash "/"',
@@ -632,7 +632,7 @@ const NamespacesIcon = ({ size = 16, fill: f, rotate = 0, onClick }) => {
632
632
  const theme = Theme.useTheme();
633
633
  const fill = f || theme.text.secondary;
634
634
  return (React.createElement("svg", { width: size, height: size, viewBox: '0 0 24 24', xmlns: 'http://www.w3.org/2000/svg', fill: 'none', style: { transform: `rotate(${rotate}deg)` }, onClick: onClick },
635
- React.createElement("path", { stroke: fill, strokeLinecap: 'round', strokeLinejoin: 'round', d: 'M7 12H17M7 12C6.536 12 6.303 12 6.108 12.022C5.32013 12.1108 4.58575 12.4645 4.02511 13.0251C3.46447 13.5857 3.1108 14.3201 3.022 15.108C3 15.303 3 15.536 3 16C3 16.464 3 16.697 3.022 16.892C3.1108 17.6799 3.46447 18.4143 4.02511 18.9749C4.58575 19.5355 5.32013 19.8892 6.108 19.978C6.303 20 6.536 20 7 20H17C17.464 20 17.697 20 17.892 19.978C18.6799 19.8892 19.4143 19.5355 19.9749 18.9749C20.5355 18.4143 20.8892 17.6799 20.978 16.892C21 16.697 21 16.464 21 16C21 15.536 21 15.303 20.978 15.108C20.8892 14.3201 20.5355 13.5857 19.9749 13.0251C19.4143 12.4645 18.6799 12.1108 17.892 12.022C17.697 12 17.464 12 17 12M7 12C6.536 12 6.303 12 6.108 11.978C5.32013 11.8892 4.58575 11.5355 4.02511 10.9749C3.46447 10.4143 3.1108 9.67987 3.022 8.892C3 8.697 3 8.464 3 8C3 7.536 3 7.303 3.022 7.108C3.1108 6.32013 3.46447 5.58575 4.02511 5.02511C4.58575 4.46447 5.32013 4.1108 6.108 4.022C6.303 4 6.536 4 7 4H17C17.464 4 17.697 4 17.892 4.022C18.6799 4.1108 19.4143 4.46447 19.9749 5.02511C20.5355 5.58575 20.8892 6.32013 20.978 7.108C21 7.303 21 7.536 21 8C21 8.464 21 8.697 20.978 8.892C20.8892 9.67987 20.5355 10.4143 19.9749 10.9749C19.4143 11.5355 18.6799 11.8892 17.892 11.978C17.697 12 17.464 12 17 12M13 8H13.01M17 8H17.01M13 16H13.01M17 16H17.01' })));
635
+ React.createElement("path", { stroke: fill, strokeLinecap: 'round', strokeLinejoin: 'round', d: 'M12 12V21.5M12 12L3.33967 7.38776M12 12L16.3302 9.69388M12 21.5C12.2173 21.5 12.4345 21.4782 12.6482 21.4347C13.1312 21.3363 13.5855 21.0848 14.4942 20.5819L18.5058 18.3616C19.4145 17.8587 19.8688 17.6073 20.1992 17.2555C20.4916 16.9442 20.7124 16.5775 20.8474 16.1792C21 15.729 21 15.2261 21 14.2203V9.77967C21 8.77388 21 8.27099 20.8474 7.82079C20.7968 7.67159 20.7342 7.52683 20.6603 7.38776M12 21.5C11.7827 21.5 11.5655 21.4782 11.3518 21.4347C10.8688 21.3363 10.4145 21.0848 9.50585 20.5819L5.49415 18.3616C4.58552 17.8587 4.13121 17.6073 3.8008 17.2555C3.50845 16.9442 3.2876 16.5775 3.15259 16.1792C3 15.729 3 15.2261 3 14.2203V9.77967C3 8.77388 3 8.27099 3.15259 7.82079C3.20316 7.67159 3.26577 7.52683 3.33967 7.38776M20.6603 7.38776C20.5369 7.15554 20.3821 6.93919 20.1992 6.74452C19.8688 6.39274 19.4145 6.14129 18.5058 5.6384L14.4942 3.41807C13.5855 2.91518 13.1312 2.66373 12.6482 2.56531C12.2208 2.47823 11.7792 2.47823 11.3518 2.56531C10.8688 2.66373 10.4145 2.91518 9.50585 3.41807L7.5 4.52823M20.6603 7.38776L16.3302 9.69388M3.33967 7.38776C3.46307 7.15554 3.61795 6.93919 3.8008 6.74452C4.13121 6.39274 4.58552 6.14129 5.49415 5.6384L7.5 4.52823M7.5 4.52823L16.3302 9.69388' })));
636
636
  };
637
637
 
638
638
  const RulesIcon = ({ size = 16, fill: f, rotate = 0, onClick }) => {
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { _ as WarningModal } from './index-QaNawEGJ.js';
2
+ import { _ as WarningModal } from './index-qzll74wE.js';
3
3
  import { StatusType, EntityTypes } from './types.js';
4
4
  import './index-DMXaEyAB.js';
5
5
  import 'styled-components';
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
2
  import Theme from './theme.js';
3
3
  import { E as EditIcon } from './index-CWbxXTof.js';
4
- import { B as BUTTON_TEXTS, D as DISPLAY_TITLES } from './index-CTgLYGo-.js';
5
- import { B as Button, V as Text, J as NotificationNote } from './index-QaNawEGJ.js';
4
+ import { B as BUTTON_TEXTS, D as DISPLAY_TITLES } from './index-B7MM_DAw.js';
5
+ import { B as Button, V as Text, J as NotificationNote } from './index-qzll74wE.js';
6
6
  import { StatusType } from './types.js';
7
7
  import './index-DMXaEyAB.js';
8
8
  import 'styled-components';
@@ -3,7 +3,7 @@ import { a as getProgrammingLanguageIcon } from './index-CJs4RDHU.js';
3
3
  import 'react';
4
4
  import './index-DMXaEyAB.js';
5
5
  import 'styled-components';
6
- import { e as AwsXrayLogo, a2 as VictoriaMetricsLogo, a1 as UptraceLogo, a0 as TraceloopLogo, $ as TingyunLogo, _ as TempoLogo, Z as TelemetryHubLogo, Y as SumoLogicLogo, X as SplunkLogo, W as SignozLogo, U as SeqLogo, d as AwsS3Logo, T as QuickwitLogo, G as GigapipeLogo, S as QrynLogo, R as PrometheusLogo, F as OpenTelemetryLogo, Q as OracleLogo, P as OpsVerseLogo, z as OpenObserveLogo, y as OneUptimeLogo, O as ObserveLogo, N as NewRelicLogo, M as MiddlewareLogo, x as LumigoLogo, w as LokiLogo, v as LogzioLogo, u as LightstepLogo, L as Last9Logo, K as KloudmateLogo, J as JaegerLogo, I as InstanaLogo, t as HyperDxLogo, H as HoneycombLogo, s as GroundcoverLogo, r as GreptimeLogo, q as GrafanaLogo, p as GoogleCloudPlatformLogo, o as ElasticSearchLogo, E as ElasticApmLogo, n as DynatraceLogo, m as DatadogLogo, D as Dash0Logo, l as CoralogixLogo, c as AwsCloudwatchLogo, k as ClickhouseLogo, j as ChronosphereLogo, i as ChecklyLogo, C as CauselyLogo, h as BonreeLogo, B as BetterStackLogo, g as BlobStorageLogo, f as AxiomLogo, b as AppDynamicsLogo, a as AlibabaCloudLogo, A as AlaudaLogo, a6 as RulesIcon, a3 as ActionsIcon, a4 as DestinationsIcon, a7 as SourcesIcon, a5 as NamespacesIcon, V as VmLogo } from './index-BRW_Nl-n.js';
6
+ import { e as AwsXrayLogo, a2 as VictoriaMetricsLogo, a1 as UptraceLogo, a0 as TraceloopLogo, $ as TingyunLogo, _ as TempoLogo, Z as TelemetryHubLogo, Y as SumoLogicLogo, X as SplunkLogo, W as SignozLogo, U as SeqLogo, d as AwsS3Logo, T as QuickwitLogo, G as GigapipeLogo, S as QrynLogo, R as PrometheusLogo, F as OpenTelemetryLogo, Q as OracleLogo, P as OpsVerseLogo, z as OpenObserveLogo, y as OneUptimeLogo, O as ObserveLogo, N as NewRelicLogo, M as MiddlewareLogo, x as LumigoLogo, w as LokiLogo, v as LogzioLogo, u as LightstepLogo, L as Last9Logo, K as KloudmateLogo, J as JaegerLogo, I as InstanaLogo, t as HyperDxLogo, H as HoneycombLogo, s as GroundcoverLogo, r as GreptimeLogo, q as GrafanaLogo, p as GoogleCloudPlatformLogo, o as ElasticSearchLogo, E as ElasticApmLogo, n as DynatraceLogo, m as DatadogLogo, D as Dash0Logo, l as CoralogixLogo, c as AwsCloudwatchLogo, k as ClickhouseLogo, j as ChronosphereLogo, i as ChecklyLogo, C as CauselyLogo, h as BonreeLogo, B as BetterStackLogo, g as BlobStorageLogo, f as AxiomLogo, b as AppDynamicsLogo, a as AlibabaCloudLogo, A as AlaudaLogo, a6 as RulesIcon, a3 as ActionsIcon, a4 as DestinationsIcon, a7 as SourcesIcon, a5 as NamespacesIcon, V as VmLogo } from './index-BbbCCewR.js';
7
7
  import { K as KafkaLogo, O as OdigosLogo } from './index-IKusBlIE.js';
8
8
  import { K as K8sLogo } from './index-DGel4E-Z.js';
9
9
 
@@ -139,6 +139,7 @@ const getDestinationIcon = (type, forceFromUrl) => {
139
139
  [DestinationTypes.Coralogix]: CoralogixLogo,
140
140
  [DestinationTypes.Dash0]: Dash0Logo,
141
141
  [DestinationTypes.Datadog]: DatadogLogo,
142
+ [DestinationTypes.Dynamic]: OpenTelemetryLogo,
142
143
  [DestinationTypes.Dynatrace]: DynatraceLogo,
143
144
  [DestinationTypes.ElasticApm]: ElasticApmLogo,
144
145
  [DestinationTypes.ElasticSearch]: ElasticSearchLogo,
@@ -4,10 +4,10 @@ import styled, { css } from 'styled-components';
4
4
  import { M as MinusIcon, f as CheckIcon, L as ListIcon, C as CodeIcon, E as ExtendArrowIcon, c as SortArrowsIcon, a as CopyIcon, b as NotebookIcon, X as XIcon, d as EyeClosedIcon, e as EyeOpenIcon, N as NoDataIcon, g as CrossIcon, S as SearchIcon, P as PlusIcon, T as TrashIcon, A as ArrowIcon } from './index-BJxaoI0G.js';
5
5
  import { StatusType, OtherStatus, SortDirection, ProgrammingLanguages } from './types.js';
6
6
  import { s as safeJsonParse, i as isEmpty } from './index-BZS1ijMm.js';
7
- import { M as MONITORS_OPTIONS, B as BUTTON_TEXTS } from './index-CTgLYGo-.js';
7
+ import { M as MONITORS_OPTIONS, B as BUTTON_TEXTS } from './index-B7MM_DAw.js';
8
8
  import { b as getStatusIcon, r as removeEmptyValuesFromObject, s as safeJsonStringify, f as flattenObjectKeys, m as mapConditions, c as capitalizeFirstLetter, g as getMonitorIcon, p as parseJsonStringToPrettyString, a as getProgrammingLanguageIcon, d as splitCamelString } from './index-CJs4RDHU.js';
9
9
  import './index-DMXaEyAB.js';
10
- import { u as useContainerSize, a as useCopy, g as useTransition, d as useKeyDown, e as useOnClickOutside } from './useTransition-BSKilkmZ.js';
10
+ import { u as useContainerSize, a as useCopy, g as useTransition, d as useKeyDown, e as useOnClickOutside } from './useTransition-n4huKtX2.js';
11
11
  import { I as ImageErrorIcon } from './index-DGel4E-Z.js';
12
12
  import ReactDOM from 'react-dom';
13
13
  import { I as InfoIcon } from './index-IKusBlIE.js';
@@ -26,6 +26,18 @@ const Text = ({ children, color, size, weight, align, family, opacity, decoratio
26
26
  return (React.createElement(TextWrapper$2, { "$color": color, "$size": size, "$weight": weight, "$align": align, "$family": family, "$opacity": opacity, "$decoration": decoration, ...props }, children));
27
27
  };
28
28
 
29
+ const ErrorWrapper = styled.div `
30
+ padding: 4px 0 0 0;
31
+ `;
32
+ const ErrorMessage = styled(Text) `
33
+ font-size: 12px;
34
+ color: ${({ theme }) => theme.text.error};
35
+ `;
36
+ const FieldError = ({ children }) => {
37
+ return (React.createElement(ErrorWrapper, null,
38
+ React.createElement(ErrorMessage, null, children)));
39
+ };
40
+
29
41
  const AutocompleteContainer = styled.div `
30
42
  position: relative;
31
43
  width: 100%;
@@ -39,13 +51,13 @@ const InputWrapper$2 = styled.div `
39
51
  padding-left: 12px;
40
52
  transition: border-color 0.3s;
41
53
  border-radius: 32px;
42
- border: 1px solid ${({ theme }) => theme.colors.border};
54
+ border: 1px solid ${({ theme, $hasError }) => ($hasError ? theme.text.error : theme.colors.border)};
43
55
 
44
56
  &:hover {
45
- border-color: ${({ theme }) => theme.colors.secondary};
57
+ border-color: ${({ theme, $hasError }) => ($hasError ? theme.text.error_secondary : theme.colors.secondary)};
46
58
  }
47
59
  &:focus-within {
48
- border-color: ${({ theme }) => theme.colors.secondary};
60
+ border-color: ${({ theme, $hasError }) => ($hasError ? theme.text.error_secondary : theme.colors.secondary)};
49
61
  }
50
62
  `;
51
63
  const StyledInput$1 = styled.input `
@@ -146,7 +158,7 @@ const filterOptions = (optionsList, input) => {
146
158
  return acc;
147
159
  }, []);
148
160
  };
149
- const AutocompleteInput = ({ placeholder = 'Type to search...', options, selectedOption, onOptionSelect, defaultText, onTextChange, style, disabled, ...props }) => {
161
+ const AutocompleteInput = ({ placeholder = 'Type to search...', options, selectedOption, onOptionSelect, defaultText, onTextChange, style, disabled, errorMessage, ...props }) => {
150
162
  const [query, setQuery] = useState(selectedOption?.label || defaultText || '');
151
163
  const [filteredOptions, setFilteredOptions] = useState(filterOptions(options, query));
152
164
  const [showOptions, setShowOptions] = useState(false);
@@ -178,10 +190,11 @@ const AutocompleteInput = ({ placeholder = 'Type to search...', options, selecte
178
190
  return;
179
191
  };
180
192
  return (React.createElement(AutocompleteContainer, { style: style },
181
- React.createElement(InputWrapper$2, null,
193
+ React.createElement(InputWrapper$2, { "$hasError": !!errorMessage },
182
194
  Icon && React.createElement(Icon, null),
183
195
  React.createElement(StyledInput$1, { type: 'text', value: query, placeholder: placeholder, onChange: handleChange, onKeyDown: handleKeyDown, disabled: disabled, onBlur: () => !disabled && setShowOptions(false), onFocus: () => !disabled && setShowOptions(true), ...props })),
184
- showOptions && filteredOptions.length ? (React.createElement(OptionsList, null, filteredOptions.map((option) => (React.createElement(OptionItem, { key: option.type || option.label, option: option, onClick: handleOptionClick }))))) : null));
196
+ showOptions && filteredOptions.length ? (React.createElement(OptionsList, null, filteredOptions.map((option) => (React.createElement(OptionItem, { key: option.type || option.label, option: option, onClick: handleOptionClick }))))) : null,
197
+ errorMessage && React.createElement(FieldError, null, errorMessage)));
185
198
  };
186
199
  const OptionItem = ({ option, renderIcon = true, onClick }) => {
187
200
  const hasSubItems = !!option.items && option.items.length > 0;
@@ -455,18 +468,6 @@ const Popup = forwardRef(({ top, left, children }, ref) => {
455
468
  return ReactDOM.createPortal(React.createElement(PopupContainer, { ref: ref, "$top": top, "$left": left }, children), document.body);
456
469
  });
457
470
 
458
- const ErrorWrapper = styled.div `
459
- padding: 4px 0 0 0;
460
- `;
461
- const ErrorMessage = styled(Text) `
462
- font-size: 12px;
463
- color: ${({ theme }) => theme.text.error};
464
- `;
465
- const FieldError = ({ children }) => {
466
- return (React.createElement(ErrorWrapper, null,
467
- React.createElement(ErrorMessage, null, children)));
468
- };
469
-
470
471
  const Container$t = styled.div `
471
472
  display: flex;
472
473
  align-items: center;
@@ -6046,13 +6047,16 @@ const Stepper = ({ data, currentStep = 0 }) => {
6046
6047
  useEffect(() => {
6047
6048
  setStepsList(data.map((step, i) => {
6048
6049
  if (i < currentStep - 1) {
6049
- return { ...step, state: StepState.Finished, subtitle: 'Success' };
6050
+ // Finished
6051
+ return { ...step, state: StepState.Finished, subtitle: step.subtitle || StatusType.Success };
6050
6052
  }
6051
6053
  else if (i === currentStep - 1) {
6052
- return { ...step, state: StepState.Active };
6054
+ // Current
6055
+ return { ...step, state: StepState.Active, subtitle: '' };
6053
6056
  }
6054
6057
  else {
6055
- return { ...step, state: StepState.Disabled };
6058
+ // Future
6059
+ return { ...step, state: StepState.Disabled, subtitle: '' };
6056
6060
  }
6057
6061
  }));
6058
6062
  }, [currentStep, data]);
@@ -4,7 +4,7 @@ export declare const MOCK_SOURCE_JAEGER: {
4
4
  namespace: string;
5
5
  name: string;
6
6
  kind: K8sResourceKind;
7
- dataStreamNames: never[];
7
+ dataStreamNames: string[];
8
8
  selected: boolean;
9
9
  otelServiceName: string;
10
10
  numberOfInstances: number;
package/lib/snippets.js CHANGED
@@ -1,5 +1,5 @@
1
- export { A as AddButton } from './index-QaNawEGJ.js';
2
- export { E as EditButton, N as NoteBackToSummary } from './index-KyiD2AtF.js';
1
+ export { A as AddButton } from './index-qzll74wE.js';
2
+ export { E as EditButton, N as NoteBackToSummary } from './index-CnBjimup.js';
3
3
  import 'react';
4
4
  import './theme.js';
5
5
  import './index-DMXaEyAB.js';
@@ -7,11 +7,11 @@ import './types.js';
7
7
  import 'styled-components';
8
8
  import './index-BJxaoI0G.js';
9
9
  import './index-BZS1ijMm.js';
10
- import './index-CTgLYGo-.js';
10
+ import './index-B7MM_DAw.js';
11
11
  import './index-CFnxjzaW.js';
12
12
  import './index-DGel4E-Z.js';
13
13
  import './index-CJs4RDHU.js';
14
14
  import './index-IKusBlIE.js';
15
- import './useTransition-BSKilkmZ.js';
15
+ import './useTransition-n4huKtX2.js';
16
16
  import 'react-dom';
17
17
  import './index-CWbxXTof.js';
@@ -17,6 +17,7 @@ export declare enum DestinationTypes {
17
17
  Coralogix = "coralogix",
18
18
  Dash0 = "dash0",
19
19
  Datadog = "datadog",
20
+ Dynamic = "dynamic",
20
21
  Dynatrace = "dynatrace",
21
22
  ElasticApm = "elasticapm",
22
23
  ElasticSearch = "elasticsearch",
package/lib/types.js CHANGED
@@ -148,6 +148,7 @@ var DestinationTypes;
148
148
  DestinationTypes["Coralogix"] = "coralogix";
149
149
  DestinationTypes["Dash0"] = "dash0";
150
150
  DestinationTypes["Datadog"] = "datadog";
151
+ DestinationTypes["Dynamic"] = "dynamic";
151
152
  DestinationTypes["Dynatrace"] = "dynatrace";
152
153
  DestinationTypes["ElasticApm"] = "elasticapm";
153
154
  DestinationTypes["ElasticSearch"] = "elasticsearch";
@@ -3,8 +3,8 @@ import { useState, useEffect, useMemo } from 'react';
3
3
  import { g as useNotificationStore, f as useModalStore, b as useDrawerStore, c as useEntityStore, a as useDataStreamStore, j as useSetupStore } from './index-DMXaEyAB.js';
4
4
  import 'styled-components';
5
5
  import { i as isEmpty, s as safeJsonParse } from './index-BZS1ijMm.js';
6
- import { F as FORM_ALERTS } from './index-CTgLYGo-.js';
7
- import { b as useGenericForm } from './useTransition-BSKilkmZ.js';
6
+ import { F as FORM_ALERTS } from './index-B7MM_DAw.js';
7
+ import { b as useGenericForm } from './useTransition-n4huKtX2.js';
8
8
  import { g as getIdFromSseTarget } from './index-7-KCQK-x.js';
9
9
 
10
10
  const INITIAL$2 = {
@@ -327,6 +327,7 @@ const useDestinationFormData = (params) => {
327
327
  fields: Object.entries(safeJsonParse(fields, {})).map(([key, value]) => ({ key, value })),
328
328
  };
329
329
  handleFormChange(undefined, undefined, updatedData);
330
+ return updatedData;
330
331
  };
331
332
  return {
332
333
  formData,
@@ -373,10 +374,12 @@ const useSourceFormData = () => {
373
374
  };
374
375
 
375
376
  const mapSourceToAvailableSource = (source, selectedStreamName, selectAll) => {
377
+ const sourceIsInCurrentStream = source.dataStreamNames?.includes(selectedStreamName) || source.currentStreamName === selectedStreamName;
378
+ const selected = typeof selectAll === 'boolean' ? selectAll : sourceIsInCurrentStream ? source.selected : false;
376
379
  return {
377
380
  name: source.name,
378
381
  kind: source.kind,
379
- selected: typeof selectAll === 'boolean' ? selectAll : source.selected && source.dataStreamNames?.includes(selectedStreamName) ? source.selected : false,
382
+ selected,
380
383
  numberOfInstances: source.numberOfInstances,
381
384
  };
382
385
  };
@@ -386,18 +389,37 @@ const mapSourceToSelectedSource = (source, selectedStreamName, selectAll) => {
386
389
  currentStreamName: selectedStreamName,
387
390
  };
388
391
  };
392
+ const mergeAvailableAndSelectedSources = (available, selected, currentStreamName) => {
393
+ const payload = {};
394
+ Object.entries(available).forEach(([namespace, sources]) => {
395
+ payload[namespace] = sources.map((s) => mapSourceToSelectedSource(s, currentStreamName));
396
+ });
397
+ Object.entries(selected).forEach(([namespace, sources]) => {
398
+ sources.forEach((s) => {
399
+ const foundIdx = payload[namespace].findIndex((src) => src.name === s.name && src.kind === s.kind);
400
+ const mapped = mapSourceToSelectedSource(s, currentStreamName);
401
+ if (foundIdx !== -1) {
402
+ payload[namespace][foundIdx] = mapped;
403
+ }
404
+ else {
405
+ payload[namespace].push(mapped);
406
+ }
407
+ });
408
+ });
409
+ return payload;
410
+ };
389
411
  const useSourceSelectionFormData = (params) => {
390
412
  const { fetchSingleNamespace } = params || {};
391
413
  const { namespaces } = useEntityStore();
392
414
  const { selectedStreamName } = useDataStreamStore();
393
415
  // only for "onboarding" - get unsaved values and set to state
394
416
  // (this is to persist the values when user navigates back to this page)
395
- const { configuredSources, configuredFutureApps, availableSources } = useSetupStore();
417
+ const { configuredSources, configuredFutureApps, availableSources: availableSourcesFromStore } = useSetupStore();
396
418
  // Keeps intial values fetched from API, so we can later filter the user-specific-selections, therebey minimizing the amount of data sent to the API on "persist sources".
397
- const [recordedInitialSources, setRecordedInitialSources] = useState(availableSources);
419
+ const [availableSources, setRecordedInitialSources] = useState(availableSourcesFromStore);
398
420
  const [selectedNamespace, setSelectedNamespace] = useState('');
399
- const [selectedSources, setSelectedSources] = useState(configuredSources);
400
421
  const [selectedFutureApps, setSelectedFutureApps] = useState(configuredFutureApps);
422
+ const [selectedSources, setSelectedSources] = useState(mergeAvailableAndSelectedSources(availableSourcesFromStore, configuredSources, selectedStreamName));
401
423
  const fetchAndSetThisNamespace = (ns, selectAll) => {
402
424
  fetchSingleNamespace?.({ variables: { namespaceName: ns } }).then(({ data }) => {
403
425
  const { name, sources = [] } = data?.computePlatform?.k8sActualNamespace || {};
@@ -480,7 +502,7 @@ const useSourceSelectionFormData = (params) => {
480
502
  const payload = {};
481
503
  Object.entries(selectedSources).forEach(([namespace, sources]) => {
482
504
  sources.forEach((source) => {
483
- const foundInitial = recordedInitialSources[namespace]?.find((initialSource) => initialSource.name === source.name && initialSource.kind === source.kind);
505
+ const foundInitial = availableSources[namespace]?.find((initialSource) => initialSource.name === source.name && initialSource.kind === source.kind);
484
506
  if (foundInitial?.selected !== source.selected) {
485
507
  if (!payload[namespace])
486
508
  payload[namespace] = [];
@@ -502,7 +524,7 @@ const useSourceSelectionFormData = (params) => {
502
524
  return payload;
503
525
  };
504
526
  return {
505
- recordedInitialSources,
527
+ availableSources,
506
528
  filteredNamespacesAndSources,
507
529
  getApiSourcesPayload,
508
530
  getApiFutureAppsPayload,
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useRef, useEffect, useCallback } from 'react';
2
- import './index-CTgLYGo-.js';
2
+ import './index-B7MM_DAw.js';
3
3
  import { g as useNotificationStore } from './index-DMXaEyAB.js';
4
4
  import { CodeAttributesKeyTypes, PayloadCollectionKeyTypes } from './types.js';
5
5
  import styled from 'styled-components';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odigos/ui-kit",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "author": "Odigos",
5
5
  "repository": {
6
6
  "type": "git",