@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.
- package/CHANGELOG.md +14 -0
- package/lib/components/dropdown/index.d.ts +1 -0
- package/lib/components/input/index.d.ts +1 -1
- package/lib/components/input-table/index.d.ts +3 -11
- package/lib/components/input-table/map-columns-to-fields/index.d.ts +15 -0
- package/lib/components/input-table/types.d.ts +15 -0
- package/lib/components.js +11 -11
- package/lib/constants/strings/index.d.ts +1 -0
- package/lib/constants.js +2 -2
- package/lib/containers/action-form/custom-fields/add-cluster-info.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/delete-attributes.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/error-sampler.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/k8s-attributes.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/latency-sampler.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/pii-masking.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/probabilistic-sampler.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/rename-attributes.d.ts +1 -1
- package/lib/containers/action-form/custom-fields/service-name-sampler.d.ts +5 -0
- package/lib/containers/action-form/custom-fields/span-attribute-sampler.d.ts +5 -0
- package/lib/containers/data-stream-drawer/index.d.ts +1 -1
- package/lib/containers/data-stream-form/index.d.ts +1 -0
- package/lib/containers/destination-selection-form/destination-list/index.d.ts +2 -0
- package/lib/containers/instrumentation-rule-drawer/build-card.d.ts +1 -1
- package/lib/containers/setup-summary/index.d.ts +2 -0
- package/lib/containers.js +379 -189
- package/lib/functions/get-action-icon/index.d.ts +2 -2
- package/lib/functions/get-yaml-fields-for-destination/index.d.ts +2 -0
- package/lib/functions/index.d.ts +4 -0
- package/lib/functions/is-legal-k8s-label/index.d.ts +1 -0
- package/lib/functions/map-destination-fields-for-display/index.d.ts +6 -0
- package/lib/functions/numbers-only/index.d.ts +1 -0
- package/lib/functions.js +8 -8
- package/lib/hooks.js +6 -6
- package/lib/icons.js +7 -7
- package/lib/{index-DR5ryS5d.js → index--RecCPGA.js} +1 -1
- package/lib/{index-cG2lNgzz.js → index-BBjwRlta.js} +41 -6
- package/lib/{index-B3j_QWzh.js → index-BWZT-ipR.js} +1 -1
- package/lib/{index-BxckQJom.js → index-BZq0yNL-.js} +90 -45
- package/lib/{index-DuSmjoDs.js → index-Bd8ZAEvq.js} +1 -1
- package/lib/{index-DAbcw-wM.js → index-CIKkezVt.js} +1 -1
- package/lib/{index-C7YDojNh.js → index-ChYtqgBW.js} +9 -3
- package/lib/{index-7-KCQK-x.js → index-CnZlllYu.js} +10 -1
- package/lib/{index-PfG5pvFK.js → index-Cq8NT9Hr.js} +1 -1
- package/lib/{index-ivnS3eWW.js → index-DJGe2YeC.js} +128 -111
- package/lib/{index-rbphz5kH.js → index-a_WA-82O.js} +2 -2
- package/lib/{index-B9cvsYnj.js → index-mOgS3e5E.js} +1 -0
- package/lib/{index-DeD-SIlN.js → index-ovjVbVQq.js} +5 -5
- package/lib/snippets.js +10 -10
- package/lib/store.js +1 -1
- package/lib/theme.js +1 -1
- package/lib/types/actions/index.d.ts +137 -41
- package/lib/types/common/index.d.ts +4 -16
- package/lib/types.js +78 -20
- package/lib/{useSourceSelectionFormData-A5_zhn1C.js → useSourceSelectionFormData-DBNf1uEe.js} +48 -26
- package/lib/{useTransition-9tDdAS9s.js → useTransition-dZ92VxT2.js} +1 -1
- package/package.json +12 -12
- 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-
|
|
4
|
-
import { a as DISPLAY_TITLES, B as BUTTON_TEXTS, F as FORM_ALERTS
|
|
5
|
-
import { ActionType, EntityTypes, StatusType, Crud, OtherStatus, NodeTypes, AddNodeTypes, EdgeTypes,
|
|
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,
|
|
7
|
-
import { i as isEmpty, s as safeJsonParse } from './index-
|
|
8
|
-
import { i as CheckCircledIcon, O as OdigosLogo } from './index-
|
|
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
|
|
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-
|
|
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-
|
|
12
|
-
import { E as EditIcon } from './index-
|
|
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-
|
|
14
|
-
import { D as DeleteWarning, C as CancelWarning } from './index-
|
|
15
|
-
import { m as mapConditions, b as getStatusIcon, c as capitalizeFirstLetter } from './index-
|
|
16
|
-
import { f as filterActions, i as getConditionsBooleans, n as getEntityLabel, m as getEntityIcon,
|
|
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-
|
|
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-
|
|
21
|
-
import './index-
|
|
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$
|
|
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$
|
|
131
|
-
const mappedValue = value[KEY$
|
|
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$
|
|
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$
|
|
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$
|
|
177
|
+
const KEY$7 = ActionKeyTypes.FallbackSamplingRatio, MIN$1 = 0, MAX$1 = 100;
|
|
153
178
|
const ErrorSampler = ({ value, setValue, formErrors }) => {
|
|
154
|
-
const errorMessage = formErrors[KEY$
|
|
155
|
-
const mappedValue = value[KEY$
|
|
156
|
-
const handleChange = (val) => setValue(KEY$
|
|
157
|
-
return (React.createElement(Input, { title: 'Fallback sampling ratio', required: true, type:
|
|
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.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
setValue(
|
|
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[
|
|
174
|
-
React.createElement(Checkbox, { title: 'Collect ReplicaSet Attributes', value: value[
|
|
175
|
-
React.createElement(Checkbox, { title: 'Collect Workload ID', value: value[
|
|
176
|
-
React.createElement(Checkbox, { title: 'Collect Cluster ID', value: value[
|
|
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$
|
|
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$
|
|
210
|
-
const mappedValue = value[KEY$
|
|
211
|
-
const handleChange = (arr) =>
|
|
212
|
-
|
|
213
|
-
{
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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$
|
|
290
|
+
const KEY$5 = ActionKeyTypes.ClusterAttributes;
|
|
247
291
|
const AddClusterInfo = ({ value, setValue, formErrors }) => {
|
|
248
|
-
const errorMessage = formErrors[KEY$
|
|
249
|
-
const mappedValue = value[KEY$
|
|
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$
|
|
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$
|
|
304
|
+
const KEY$4 = ActionKeyTypes.AttributeNamesToDelete;
|
|
261
305
|
const DeleteAttributes = ({ value, setValue, formErrors }) => {
|
|
262
|
-
const errorMessage = formErrors[KEY$
|
|
263
|
-
const mappedValue = value[KEY$
|
|
264
|
-
const handleChange = (arr) => setValue(KEY$
|
|
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$
|
|
312
|
+
const KEY$3 = ActionKeyTypes.Renames;
|
|
269
313
|
const RenameAttributes = ({ value, setValue, formErrors }) => {
|
|
270
|
-
const errorMessage = formErrors[KEY$
|
|
271
|
-
const mappedValue = Object.entries(value[KEY$
|
|
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$
|
|
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 =
|
|
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
|
-
|
|
285
|
-
|
|
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:
|
|
7119
|
-
? rendererPointToPoint({ x:
|
|
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,
|
|
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
|
|
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 && !
|
|
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,
|
|
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
|
-
|
|
13981
|
-
|
|
13982
|
-
|
|
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 = ({
|
|
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 {
|
|
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(
|
|
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
|
|
14120
|
-
const
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
const
|
|
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
|
|
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:
|
|
14144
|
-
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
|
-
|
|
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(() =>
|
|
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.
|
|
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 (
|
|
15029
|
+
if (payloadCollection) {
|
|
14846
15030
|
const str = Object.entries(payloadCollection)
|
|
14847
|
-
.filter(([key, val]) =>
|
|
15031
|
+
.filter(([key, val]) => val)
|
|
14848
15032
|
.map(([key, val]) => key)
|
|
14849
15033
|
.join(', ');
|
|
14850
|
-
if (
|
|
15034
|
+
if (str)
|
|
14851
15035
|
arr.push({ title: 'Collect', value: str });
|
|
14852
15036
|
}
|
|
14853
|
-
if (
|
|
15037
|
+
if (codeAttributes) {
|
|
14854
15038
|
const str = Object.entries(codeAttributes)
|
|
14855
|
-
.filter(([key, val]) =>
|
|
15039
|
+
.filter(([key, val]) => val)
|
|
14856
15040
|
.map(([key, val]) => key)
|
|
14857
15041
|
.join(', ');
|
|
14858
|
-
if (
|
|
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 :
|
|
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 = ({
|
|
15608
|
-
|
|
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,
|
|
15809
|
+
React.createElement(DestinationList, { categories: categories }))))));
|
|
15620
15810
|
};
|
|
15621
15811
|
|
|
15622
15812
|
var NavIconIds;
|