@odigos/ui-kit 0.0.98 → 0.0.99
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 +13 -0
- package/bundle-analysis.html +4949 -0
- package/lib/chunks/ui-components-675457f7.js +1604 -0
- package/lib/chunks/vendor-56978108.js +1 -0
- package/lib/components.js +1 -163
- package/lib/constants.js +1 -9
- package/lib/containers.js +163 -5141
- package/lib/functions.js +1 -141
- package/lib/hooks.js +1 -649
- package/lib/icons.js +1 -187
- package/lib/snippets.js +1 -28
- package/lib/store/useDarkMode.d.ts +5 -3
- package/lib/store.js +1 -4
- package/lib/theme.js +1 -4
- package/lib/types.js +1 -369
- package/package.json +19 -13
- package/lib/index-0a77c1be.js +0 -11
- package/lib/index-195415d4.js +0 -676
- package/lib/index-1cb4f9e2.js +0 -20
- package/lib/index-5e5f7bda.js +0 -39
- package/lib/index-6a6bea6e.js +0 -37
- package/lib/index-77cf7846.js +0 -124
- package/lib/index-89edd01d.js +0 -1968
- package/lib/index-9475009f.js +0 -225
- package/lib/index-a3c0cecd.js +0 -36
- package/lib/index-c823fbfb.js +0 -342
- package/lib/index-c8b542d8.js +0 -38528
- package/lib/index-d8fb5fed.js +0 -138
- package/lib/index-f18c8530.js +0 -64
- package/lib/useTransition-159c9af8.js +0 -3598
package/lib/index-9475009f.js
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { StatusType, OtherStatus, SignalType } from './types.js';
|
|
2
|
-
import 'react';
|
|
3
|
-
import './index-89edd01d.js';
|
|
4
|
-
import 'styled-components';
|
|
5
|
-
import { L as LogsIcon, M as MetricsIcon, T as TracesIcon, C as CheckCircledIcon, E as ErrorTriangleIcon, W as WarningTriangleIcon, I as InfoIcon, O as OdigosLogo } from './index-f18c8530.js';
|
|
6
|
-
|
|
7
|
-
const capitalizeFirstLetter = (string) => {
|
|
8
|
-
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Recursively flattens a nested object into a single-level object where each key
|
|
13
|
-
* represents the path to its corresponding value in the original object. Keys for nested
|
|
14
|
-
* properties are concatenated using a dot (`.`) as a separator, while array elements
|
|
15
|
-
* include their index in square brackets (`[]`).
|
|
16
|
-
*
|
|
17
|
-
* @param {Record<string, any>} obj - The input object to be flattened.
|
|
18
|
-
* @param {string} [prefix=''] - The current prefix for the keys, used for recursion.
|
|
19
|
-
* @param {Record<string, any>} [result={}] - The accumulator object that stores the flattened result.
|
|
20
|
-
* @returns {Record<string, any>} A new object where all nested properties are flattened into
|
|
21
|
-
* a single level with their paths as keys.
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* const input = {
|
|
25
|
-
* name: {
|
|
26
|
-
* name: 'Name',
|
|
27
|
-
* value: 'load-generator',
|
|
28
|
-
* status: null,
|
|
29
|
-
* explain: '...',
|
|
30
|
-
* },
|
|
31
|
-
* };
|
|
32
|
-
*
|
|
33
|
-
* const output = flattenObjectKeys(input);
|
|
34
|
-
* Output:
|
|
35
|
-
* {
|
|
36
|
-
* 'name.name': 'Name',
|
|
37
|
-
* 'name.value': 'load-generator',
|
|
38
|
-
* 'name.status': null,
|
|
39
|
-
* 'name.explain': '...',
|
|
40
|
-
* }
|
|
41
|
-
*/
|
|
42
|
-
const flattenObjectKeys = (obj, prefix = '', result = {}) => {
|
|
43
|
-
for (const key in obj) {
|
|
44
|
-
if (obj.hasOwnProperty(key)) {
|
|
45
|
-
const value = obj[key];
|
|
46
|
-
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
47
|
-
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
48
|
-
// Recurse for nested objects
|
|
49
|
-
flattenObjectKeys(value, newKey, result);
|
|
50
|
-
}
|
|
51
|
-
else if (Array.isArray(value)) {
|
|
52
|
-
value.forEach((item, index) => {
|
|
53
|
-
const arrayKey = `${newKey}[${index}]`;
|
|
54
|
-
if (item !== null && typeof item === 'object') {
|
|
55
|
-
// Recurse for objects in arrays
|
|
56
|
-
flattenObjectKeys(item, arrayKey, result);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
// Assign primitive array values
|
|
60
|
-
result[arrayKey] = item;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
// Assign non-object, non-array values
|
|
66
|
-
result[newKey] = value;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return result;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
const getConditionsBooleans = (conditions) => {
|
|
74
|
-
const errors = conditions?.filter(({ status }) => status === StatusType.Error);
|
|
75
|
-
const warnings = conditions?.filter(({ status }) => status === StatusType.Warning);
|
|
76
|
-
const disableds = conditions?.filter(({ status }) => status === OtherStatus.Disabled);
|
|
77
|
-
const loadings = conditions?.filter(({ status }) => status === OtherStatus.Loading);
|
|
78
|
-
const hasErrors = errors.length > 0;
|
|
79
|
-
const hasWarnings = warnings.length > 0;
|
|
80
|
-
const hasDisableds = disableds.length > 0;
|
|
81
|
-
const hasLoadings = loadings.length > 0;
|
|
82
|
-
const priorotizedStatus = hasErrors ? StatusType.Error : hasWarnings ? StatusType.Warning : hasDisableds ? StatusType.Info : undefined;
|
|
83
|
-
return {
|
|
84
|
-
errors,
|
|
85
|
-
hasErrors,
|
|
86
|
-
warnings,
|
|
87
|
-
hasWarnings,
|
|
88
|
-
disableds,
|
|
89
|
-
hasDisableds,
|
|
90
|
-
loadings,
|
|
91
|
-
hasLoadings,
|
|
92
|
-
priorotizedStatus,
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
const getMonitorIcon = (type) => {
|
|
97
|
-
const LOGOS = {
|
|
98
|
-
[SignalType.Logs]: LogsIcon,
|
|
99
|
-
[SignalType.Metrics]: MetricsIcon,
|
|
100
|
-
[SignalType.Traces]: TracesIcon,
|
|
101
|
-
};
|
|
102
|
-
return LOGOS[type];
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const getStatusIcon = (type, theme) => {
|
|
106
|
-
const LOGOS = {
|
|
107
|
-
[StatusType.Success]: (props) => CheckCircledIcon({ fill: theme.text[type], ...props }),
|
|
108
|
-
[StatusType.Error]: (props) => ErrorTriangleIcon({ fill: theme.text[type], ...props }),
|
|
109
|
-
[StatusType.Warning]: (props) => WarningTriangleIcon({ fill: theme.text[type], ...props }),
|
|
110
|
-
[StatusType.Info]: (props) => InfoIcon({ fill: theme.text[type], ...props }),
|
|
111
|
-
[StatusType.Default]: (props) => OdigosLogo({ fill: theme.text[type], ...props }),
|
|
112
|
-
};
|
|
113
|
-
return LOGOS[type];
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const isStringABoolean = (value) => {
|
|
117
|
-
const normalizedValue = String(value).trim().toLowerCase();
|
|
118
|
-
const booleanValues = ['true', 'false', '1', '0'];
|
|
119
|
-
return booleanValues.includes(normalizedValue);
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const SEMVER_REGEX = /^(\d+\.)?(\d+\.)?(\*|\d+)$/;
|
|
123
|
-
const isValidVersion = (version) => SEMVER_REGEX.test(version);
|
|
124
|
-
|
|
125
|
-
// Example: splitCamelString('LoremIpsumDolorSitAmet')
|
|
126
|
-
// > 'Lorem Ipsum Dolor Sit Amet'
|
|
127
|
-
const splitCamelString = (str) => {
|
|
128
|
-
if (!str)
|
|
129
|
-
return '';
|
|
130
|
-
return str.replace(/([a-z0-9])([A-Z])/g, '$1 $2');
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const mapConditions = (conditions) => {
|
|
134
|
-
return (conditions?.map(({ status, type, reason, message, lastTransitionTime }) => ({
|
|
135
|
-
status,
|
|
136
|
-
type: splitCamelString(type),
|
|
137
|
-
reason: !!reason ? splitCamelString(reason) : '',
|
|
138
|
-
message,
|
|
139
|
-
lastTransitionTime,
|
|
140
|
-
})) || []);
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const numbersOnly = (value) => {
|
|
144
|
-
// Use a regular expression to replace all non-digit characters with an empty string
|
|
145
|
-
const cleaned = value.replace(/[^\d]/g, '');
|
|
146
|
-
return cleaned;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const parseBooleanFromString = (value) => {
|
|
150
|
-
const normalizedValue = String(value).trim().toLowerCase();
|
|
151
|
-
if (normalizedValue === 'true' || normalizedValue === '1') {
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
else if (normalizedValue === 'false' || normalizedValue === '0') {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
console.warn(`Cannot parse boolean from string: "${value}"`);
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const parseJsonStringToPrettyString = (value) => {
|
|
164
|
-
let str = '';
|
|
165
|
-
try {
|
|
166
|
-
const parsed = JSON.parse(value);
|
|
167
|
-
// Handle arrays
|
|
168
|
-
if (Array.isArray(parsed)) {
|
|
169
|
-
str = parsed
|
|
170
|
-
.map((item) => {
|
|
171
|
-
if (typeof item === 'object' && item !== null)
|
|
172
|
-
return `${item.key}: ${item.value}`;
|
|
173
|
-
else
|
|
174
|
-
return item;
|
|
175
|
-
})
|
|
176
|
-
.join(', ');
|
|
177
|
-
}
|
|
178
|
-
// Handle objects (non-array JSON objects)
|
|
179
|
-
else if (typeof parsed === 'object' && parsed !== null) {
|
|
180
|
-
str = Object.entries(parsed)
|
|
181
|
-
.map(([key, val]) => `${key}: ${val}`)
|
|
182
|
-
.join(', ');
|
|
183
|
-
}
|
|
184
|
-
// Should never reach this if it's a string (it will throw)
|
|
185
|
-
else {
|
|
186
|
-
str = value;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
catch (_) {
|
|
190
|
-
str = value;
|
|
191
|
-
}
|
|
192
|
-
return str;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const removeEmptyValuesFromObject = (obj) => {
|
|
196
|
-
if (typeof obj !== 'object')
|
|
197
|
-
return obj;
|
|
198
|
-
const result = Array.isArray(obj) ? [] : {};
|
|
199
|
-
Object.keys(obj).forEach((key) => {
|
|
200
|
-
const value = obj[key];
|
|
201
|
-
if (Array.isArray(value)) {
|
|
202
|
-
// Remove empty arrays or recursively clean non-empty ones
|
|
203
|
-
const filteredArray = value.filter((item) => item !== null && item !== undefined && item !== '');
|
|
204
|
-
if (filteredArray.length > 0)
|
|
205
|
-
result[key] = filteredArray.map((item) => removeEmptyValuesFromObject(item));
|
|
206
|
-
}
|
|
207
|
-
else if (typeof value === 'object' && value !== null) {
|
|
208
|
-
// Recursively clean nested objects
|
|
209
|
-
const nestedObject = removeEmptyValuesFromObject(value);
|
|
210
|
-
if (Object.keys(nestedObject).length > 0)
|
|
211
|
-
result[key] = nestedObject;
|
|
212
|
-
}
|
|
213
|
-
else if (![undefined, null, ''].includes(value)) {
|
|
214
|
-
// Keep valid values
|
|
215
|
-
result[key] = value;
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
return result;
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const safeJsonStringify = (obj, indent = 2) => {
|
|
222
|
-
return JSON.stringify(obj || {}, null, indent);
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
export { getMonitorIcon as a, getStatusIcon as b, capitalizeFirstLetter as c, isValidVersion as d, parseJsonStringToPrettyString as e, flattenObjectKeys as f, getConditionsBooleans as g, splitCamelString as h, isStringABoolean as i, mapConditions as m, numbersOnly as n, parseBooleanFromString as p, removeEmptyValuesFromObject as r, safeJsonStringify as s };
|
package/lib/index-a3c0cecd.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { a6 as WarningModal } from './index-c8b542d8.js';
|
|
3
|
-
import { StatusType, EntityTypes } from './types.js';
|
|
4
|
-
import './index-89edd01d.js';
|
|
5
|
-
import 'styled-components';
|
|
6
|
-
|
|
7
|
-
const CancelWarning = ({ isOpen, noOverlay, name, onApprove, onDeny }) => {
|
|
8
|
-
return (React.createElement(WarningModal, { isOpen: isOpen, noOverlay: noOverlay, title: `Cancel${name ? ` ${name}` : ''}`, description: 'Are you sure you want to cancel?', approveButton: {
|
|
9
|
-
text: 'Confirm',
|
|
10
|
-
variant: StatusType.Warning,
|
|
11
|
-
onClick: onApprove,
|
|
12
|
-
}, denyButton: {
|
|
13
|
-
text: 'Go Back',
|
|
14
|
-
onClick: onDeny,
|
|
15
|
-
} }));
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const DeleteWarning = ({ isOpen, noOverlay, name, type, isLastItem, onApprove, onDeny }) => {
|
|
19
|
-
const actionText = type === EntityTypes.Source ? 'uninstrument' : 'delete';
|
|
20
|
-
return (React.createElement(WarningModal, { isOpen: isOpen, noOverlay: noOverlay, title: `${actionText.charAt(0).toUpperCase() + actionText.substring(1)}${name ? ` ${name}` : ''}`, description: `Are you sure you want to ${actionText}?`, note: isLastItem
|
|
21
|
-
? {
|
|
22
|
-
type: StatusType.Warning,
|
|
23
|
-
title: `You're about to ${actionText} the last ${type || name}`,
|
|
24
|
-
message: '',
|
|
25
|
-
}
|
|
26
|
-
: undefined, approveButton: {
|
|
27
|
-
text: 'Confirm',
|
|
28
|
-
variant: 'danger',
|
|
29
|
-
onClick: onApprove,
|
|
30
|
-
}, denyButton: {
|
|
31
|
-
text: 'Go Back',
|
|
32
|
-
onClick: onDeny,
|
|
33
|
-
} }));
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export { CancelWarning as C, DeleteWarning as D };
|
package/lib/index-c823fbfb.js
DELETED
|
@@ -1,342 +0,0 @@
|
|
|
1
|
-
import { StatusType, DestinationTypes, EntityTypes } from './types.js';
|
|
2
|
-
import { a as DEFAULT_DATA_STREAM_NAME, f as getProgrammingLanguageIcon, h as KafkaLogo } from './index-89edd01d.js';
|
|
3
|
-
import 'react';
|
|
4
|
-
import 'styled-components';
|
|
5
|
-
import { O as OdigosLogo } from './index-f18c8530.js';
|
|
6
|
-
import { A as AlaudaLogo, a as AlibabaCloudLogo, b as AppDynamicsLogo, c as AxiomLogo, B as BlobStorageLogo, d as BetterStackLogo, e as BonreeLogo, C as CauselyLogo, f as ChecklyLogo, g as ChronosphereLogo, h as ClickhouseLogo, i as AwsCloudwatchLogo, j as CoralogixLogo, D as Dash0Logo, k as DatadogLogo, O as OpenTelemetryLogo, l as DynatraceLogo, E as ElasticApmLogo, m as ElasticSearchLogo, G as GoogleCloudPlatformLogo, n as GrafanaLogo, o as GreptimeLogo, p as GroundcoverLogo, H as HoneycombLogo, q as HyperDxLogo, I as InstanaLogo, J as JaegerLogo, K as KloudmateLogo, L as Last9Logo, r as LightstepLogo, s as LogzioLogo, t as LokiLogo, u as LumigoLogo, M as MiddlewareLogo, N as NewRelicLogo, v as ObserveLogo, w as OneUptimeLogo, x as OpenObserveLogo, y as OpsVerseLogo, z as OracleLogo, P as PrometheusLogo, Q as QrynLogo, F as GigapipeLogo, R as QuickwitLogo, S as AwsS3Logo, T as SeqLogo, U as SignozLogo, V as SplunkLogo, W as SumoLogicLogo, X as TelemetryHubLogo, Y as TempoLogo, Z as TingyunLogo, _ as TraceloopLogo, $ as UptraceLogo, a0 as VictoriaMetricsLogo, a1 as AwsXrayLogo, a2 as NamespacesIcon, a3 as SourcesIcon, a4 as DestinationsIcon, a5 as ActionsIcon, a6 as RulesIcon } from './index-195415d4.js';
|
|
7
|
-
import { s as safeJsonParse } from './index-5e5f7bda.js';
|
|
8
|
-
|
|
9
|
-
const filterActions = (actions, filters) => {
|
|
10
|
-
let filtered = [...actions];
|
|
11
|
-
if (!!filters.monitors?.length)
|
|
12
|
-
filtered = filtered.filter((action) => !!filters.monitors?.find((metric) => action.spec.signals.find((str) => str.toLowerCase() === metric.id)));
|
|
13
|
-
return filtered;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const filterDestinations = (destinations, filters) => {
|
|
17
|
-
let filtered = [...destinations];
|
|
18
|
-
if (!!filters.monitors?.length)
|
|
19
|
-
filtered = filtered.filter((dest) => !!filters.monitors?.find((metr) => dest.exportedSignals[metr.id]));
|
|
20
|
-
return filtered;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const filterDestinationsByStream = (destinations, streamName) => {
|
|
24
|
-
// if no stream is selected, return nothing (to prevent glitchy rendering)
|
|
25
|
-
if (!streamName)
|
|
26
|
-
return [];
|
|
27
|
-
// note: destinations can also not have any streams assigned, and we want to show them
|
|
28
|
-
return destinations.filter((dest) => dest.dataStreamNames.includes(streamName) || !dest.dataStreamNames.length);
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const filterSources = (sources, filters) => {
|
|
32
|
-
let filtered = [...sources];
|
|
33
|
-
if (!!filters.namespaces?.length)
|
|
34
|
-
filtered = filtered.filter(({ namespace }) => !!filters.namespaces?.find(({ id }) => id === namespace));
|
|
35
|
-
if (!!filters.kinds?.length)
|
|
36
|
-
filtered = filtered.filter(({ kind }) => !!filters.kinds?.find(({ id }) => id === kind));
|
|
37
|
-
if (!!filters.languages?.length)
|
|
38
|
-
filtered = filtered.filter(({ containers }) => !!filters.languages?.find(({ id }) => !!containers?.find(({ language }) => id === language)));
|
|
39
|
-
if (!!filters.conditions?.length)
|
|
40
|
-
filtered = filtered.filter(({ conditions }) => !!filters.conditions?.find(({ id }) => !!conditions?.find(({ type, reason }) => id === `${type}#${reason}`)));
|
|
41
|
-
if (!!filters.onlyErrors)
|
|
42
|
-
filtered = filtered.filter((source) => !!source.conditions?.find((cond) => cond.status === StatusType.Error));
|
|
43
|
-
if (!!filters.errors?.length)
|
|
44
|
-
filtered = filtered.filter((source) => !!filters.errors?.find((error) => !!source.conditions?.find((cond) => cond.message === error.id)));
|
|
45
|
-
return filtered;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const filterSourcesByStream = (sources, streamName) => {
|
|
49
|
-
// if no stream is selected, return nothing (to prevent glitchy rendering)
|
|
50
|
-
if (!streamName)
|
|
51
|
-
return [];
|
|
52
|
-
return sources.filter((source) => source.dataStreamNames.includes(streamName) || (streamName === DEFAULT_DATA_STREAM_NAME && !source.dataStreamNames.length));
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const formatBytes = (bytes) => {
|
|
56
|
-
if (!bytes)
|
|
57
|
-
return '0 KB/s';
|
|
58
|
-
const sizes = ['Bytes/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s'];
|
|
59
|
-
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
60
|
-
const value = bytes / Math.pow(1024, i);
|
|
61
|
-
return `${value.toFixed(i === 0 ? 0 : 1)} ${sizes[i]}`;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
// 1000000000000000000 ns = 1 s
|
|
65
|
-
// 1000000000000000 ns = 1 ms
|
|
66
|
-
// 1000000000 ns = 1 μs
|
|
67
|
-
// 1000000 ns = 1 ns
|
|
68
|
-
// 1000 ns = 1 ns
|
|
69
|
-
// 100 ns = 1 ns
|
|
70
|
-
// 10 ns = 1 ns
|
|
71
|
-
// 1 ns = 1 ns
|
|
72
|
-
const formatDuration = (durationNanoseconds) => {
|
|
73
|
-
if (!durationNanoseconds)
|
|
74
|
-
return '0 ns';
|
|
75
|
-
// Define time unit thresholds and conversion factors
|
|
76
|
-
if (durationNanoseconds < 1000) {
|
|
77
|
-
// Less than 1 microsecond - show in nanoseconds
|
|
78
|
-
return `${durationNanoseconds.toFixed(0)} ns`;
|
|
79
|
-
}
|
|
80
|
-
else if (durationNanoseconds < 1000000) {
|
|
81
|
-
// Less than 1 millisecond - show in microseconds
|
|
82
|
-
const microseconds = durationNanoseconds / 1000;
|
|
83
|
-
return `${microseconds.toFixed(microseconds < 10 ? 2 : 0)} μs`;
|
|
84
|
-
}
|
|
85
|
-
else if (durationNanoseconds < 1000000000) {
|
|
86
|
-
// Less than 1 second - show in milliseconds
|
|
87
|
-
const milliseconds = durationNanoseconds / 1000000;
|
|
88
|
-
return `${milliseconds.toFixed(milliseconds < 10 ? 2 : 0)} ms`;
|
|
89
|
-
}
|
|
90
|
-
else if (durationNanoseconds < 60000000000) {
|
|
91
|
-
// Less than 1 minute - show in seconds
|
|
92
|
-
const seconds = durationNanoseconds / 1000000000;
|
|
93
|
-
return `${seconds.toFixed(seconds < 10 ? 2 : 0)} s`;
|
|
94
|
-
}
|
|
95
|
-
else if (durationNanoseconds < 3600000000000) {
|
|
96
|
-
// Less than 1 hour - show in minutes
|
|
97
|
-
const minutes = durationNanoseconds / 60000000000;
|
|
98
|
-
return `${minutes.toFixed(minutes < 10 ? 2 : 0)} m`;
|
|
99
|
-
}
|
|
100
|
-
else if (durationNanoseconds < 86400000000000) {
|
|
101
|
-
// Less than 1 day - show in hours
|
|
102
|
-
const hours = durationNanoseconds / 3600000000000;
|
|
103
|
-
return `${hours.toFixed(hours < 10 ? 2 : 0)} h`;
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
// 1 day or more - show in days
|
|
107
|
-
const days = durationNanoseconds / 86400000000000;
|
|
108
|
-
return `${days.toFixed(days < 10 ? 2 : 0)} d`;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const getContainersInstrumentedCount = (containers) => {
|
|
113
|
-
const instrumentedCount = containers?.reduce((prev, curr) => (curr.instrumented ? prev + 1 : prev), 0);
|
|
114
|
-
const totalCount = containers?.length || 0;
|
|
115
|
-
return `${instrumentedCount}/${totalCount} instrumented`;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const getContainersIcons = (containers) => {
|
|
119
|
-
const icons = containers?.map(({ language }) => getProgrammingLanguageIcon(language)) || [];
|
|
120
|
-
return icons;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const getDestinationIcon = (type, forceFromUrl) => {
|
|
124
|
-
const LOGOS = {
|
|
125
|
-
[DestinationTypes.Alauda]: AlaudaLogo,
|
|
126
|
-
[DestinationTypes.AlibabaCloud]: AlibabaCloudLogo,
|
|
127
|
-
[DestinationTypes.AppDynamics]: AppDynamicsLogo,
|
|
128
|
-
[DestinationTypes.Axiom]: AxiomLogo,
|
|
129
|
-
[DestinationTypes.AzureBlob]: BlobStorageLogo,
|
|
130
|
-
[DestinationTypes.BetterStack]: BetterStackLogo,
|
|
131
|
-
[DestinationTypes.Bonree]: BonreeLogo,
|
|
132
|
-
[DestinationTypes.Causely]: CauselyLogo,
|
|
133
|
-
[DestinationTypes.Checkly]: ChecklyLogo,
|
|
134
|
-
[DestinationTypes.Chronosphere]: ChronosphereLogo,
|
|
135
|
-
[DestinationTypes.ClickHouse]: ClickhouseLogo,
|
|
136
|
-
[DestinationTypes.CloudWatch]: AwsCloudwatchLogo,
|
|
137
|
-
[DestinationTypes.Coralogix]: CoralogixLogo,
|
|
138
|
-
[DestinationTypes.Dash0]: Dash0Logo,
|
|
139
|
-
[DestinationTypes.Datadog]: DatadogLogo,
|
|
140
|
-
[DestinationTypes.Dynamic]: OpenTelemetryLogo,
|
|
141
|
-
[DestinationTypes.Dynatrace]: DynatraceLogo,
|
|
142
|
-
[DestinationTypes.ElasticApm]: ElasticApmLogo,
|
|
143
|
-
[DestinationTypes.ElasticSearch]: ElasticSearchLogo,
|
|
144
|
-
[DestinationTypes.GoogleCloud]: GoogleCloudPlatformLogo,
|
|
145
|
-
[DestinationTypes.GrafanaCloudLoki]: GrafanaLogo,
|
|
146
|
-
[DestinationTypes.GrafanaCloudPrometheus]: GrafanaLogo,
|
|
147
|
-
[DestinationTypes.GrafanaCloudTempo]: GrafanaLogo,
|
|
148
|
-
[DestinationTypes.Greptime]: GreptimeLogo,
|
|
149
|
-
[DestinationTypes.Groundcover]: GroundcoverLogo,
|
|
150
|
-
[DestinationTypes.Honeycomb]: HoneycombLogo,
|
|
151
|
-
[DestinationTypes.HyperDX]: HyperDxLogo,
|
|
152
|
-
[DestinationTypes.Instana]: InstanaLogo,
|
|
153
|
-
[DestinationTypes.Jaeger]: JaegerLogo,
|
|
154
|
-
[DestinationTypes.Kafka]: KafkaLogo,
|
|
155
|
-
[DestinationTypes.Kloudmate]: KloudmateLogo,
|
|
156
|
-
[DestinationTypes.Last9]: Last9Logo,
|
|
157
|
-
[DestinationTypes.Lightstep]: LightstepLogo,
|
|
158
|
-
[DestinationTypes.LogzIo]: LogzioLogo,
|
|
159
|
-
[DestinationTypes.Loki]: LokiLogo,
|
|
160
|
-
[DestinationTypes.Lumigo]: LumigoLogo,
|
|
161
|
-
[DestinationTypes.Middleware]: MiddlewareLogo,
|
|
162
|
-
[DestinationTypes.NewRelic]: NewRelicLogo,
|
|
163
|
-
[DestinationTypes.Observe]: ObserveLogo,
|
|
164
|
-
[DestinationTypes.Odigos]: OdigosLogo,
|
|
165
|
-
[DestinationTypes.OneUptime]: OneUptimeLogo,
|
|
166
|
-
[DestinationTypes.OpenObserve]: OpenObserveLogo,
|
|
167
|
-
[DestinationTypes.Opsverse]: OpsVerseLogo,
|
|
168
|
-
[DestinationTypes.Oracle]: OracleLogo,
|
|
169
|
-
[DestinationTypes.OTLP]: OpenTelemetryLogo,
|
|
170
|
-
[DestinationTypes.OTLPHttp]: OpenTelemetryLogo,
|
|
171
|
-
[DestinationTypes.Prometheus]: PrometheusLogo,
|
|
172
|
-
[DestinationTypes.Qryn]: QrynLogo,
|
|
173
|
-
[DestinationTypes.QrynOss]: GigapipeLogo,
|
|
174
|
-
[DestinationTypes.Quickwit]: QuickwitLogo,
|
|
175
|
-
[DestinationTypes.S3]: AwsS3Logo,
|
|
176
|
-
[DestinationTypes.Seq]: SeqLogo,
|
|
177
|
-
[DestinationTypes.Signoz]: SignozLogo,
|
|
178
|
-
[DestinationTypes.Splunk]: SplunkLogo,
|
|
179
|
-
[DestinationTypes.SplunkSapm]: SplunkLogo,
|
|
180
|
-
[DestinationTypes.SplunkOtlp]: SplunkLogo,
|
|
181
|
-
[DestinationTypes.SumoLogic]: SumoLogicLogo,
|
|
182
|
-
[DestinationTypes.TelemetryHub]: TelemetryHubLogo,
|
|
183
|
-
[DestinationTypes.Tempo]: TempoLogo,
|
|
184
|
-
[DestinationTypes.Tingyun]: TingyunLogo,
|
|
185
|
-
[DestinationTypes.Traceloop]: TraceloopLogo,
|
|
186
|
-
[DestinationTypes.Uptrace]: UptraceLogo,
|
|
187
|
-
[DestinationTypes.VictoriaMetrics]: VictoriaMetricsLogo,
|
|
188
|
-
[DestinationTypes.VictoriaMetricsCloud]: VictoriaMetricsLogo,
|
|
189
|
-
[DestinationTypes.XRay]: AwsXrayLogo,
|
|
190
|
-
};
|
|
191
|
-
const logo = LOGOS[type];
|
|
192
|
-
if (logo && !forceFromUrl)
|
|
193
|
-
return { icon: logo };
|
|
194
|
-
// Fallback to fetched-icon (in-case new destinations were added, and we haven't added the icon to the kit yet)
|
|
195
|
-
return { iconSrc: `https://d15jtxgb40qetw.cloudfront.net/${type}.svg` };
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
const getEntityIcon = (type) => {
|
|
199
|
-
const LOGOS = {
|
|
200
|
-
[EntityTypes.Namespace]: NamespacesIcon,
|
|
201
|
-
[EntityTypes.Source]: SourcesIcon,
|
|
202
|
-
[EntityTypes.Destination]: DestinationsIcon,
|
|
203
|
-
[EntityTypes.Action]: ActionsIcon,
|
|
204
|
-
[EntityTypes.InstrumentationRule]: RulesIcon,
|
|
205
|
-
};
|
|
206
|
-
return LOGOS[type];
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const getEntityLabel = (entity, entityType, options) => {
|
|
210
|
-
const { extended, prioritizeDisplayName } = options || {};
|
|
211
|
-
let type = '';
|
|
212
|
-
let name = '';
|
|
213
|
-
switch (entityType) {
|
|
214
|
-
case EntityTypes.InstrumentationRule:
|
|
215
|
-
const rule = entity;
|
|
216
|
-
type = rule.type;
|
|
217
|
-
name = rule.ruleName;
|
|
218
|
-
break;
|
|
219
|
-
case EntityTypes.Source:
|
|
220
|
-
const source = entity;
|
|
221
|
-
type = source.name;
|
|
222
|
-
name = source.otelServiceName;
|
|
223
|
-
break;
|
|
224
|
-
case EntityTypes.Action:
|
|
225
|
-
const action = entity;
|
|
226
|
-
type = action.type;
|
|
227
|
-
name = action.spec.actionName;
|
|
228
|
-
break;
|
|
229
|
-
case EntityTypes.Destination:
|
|
230
|
-
const destination = entity;
|
|
231
|
-
type = destination.destinationType.displayName;
|
|
232
|
-
name = destination.name;
|
|
233
|
-
break;
|
|
234
|
-
case EntityTypes.Namespace:
|
|
235
|
-
const namespace = entity;
|
|
236
|
-
type = namespace.name;
|
|
237
|
-
name = namespace.name;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
if (extended)
|
|
241
|
-
return type + (name && name !== type ? ` (${name})` : '');
|
|
242
|
-
else if (prioritizeDisplayName)
|
|
243
|
-
return name || type;
|
|
244
|
-
else
|
|
245
|
-
return type;
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
const getMetricForEntity = (metrics, entityType, entityId) => {
|
|
249
|
-
const metric = entityType === EntityTypes.Source
|
|
250
|
-
? metrics?.sources.find((m) => m.kind === entityId.kind && m.name === entityId.name && m.namespace === entityId.namespace)
|
|
251
|
-
: metrics?.destinations.find((m) => m.id === entityId);
|
|
252
|
-
return metric || { throughput: 0 };
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
const getRecursiveValues = (obj, childrenKey, returnKey) => {
|
|
256
|
-
const children = obj[childrenKey];
|
|
257
|
-
if (!children)
|
|
258
|
-
return [];
|
|
259
|
-
return children.flatMap((item) => {
|
|
260
|
-
const values = item[returnKey];
|
|
261
|
-
const result = [];
|
|
262
|
-
if (values !== undefined) {
|
|
263
|
-
if (Array.isArray(values)) {
|
|
264
|
-
result.push(...values);
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
result.push(values);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
result.push(...getRecursiveValues(item, childrenKey, returnKey));
|
|
271
|
-
return result;
|
|
272
|
-
});
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
276
|
-
const getValueForRange = (current, matrix) => {
|
|
277
|
-
// CURRENT: represents the current value (such as window width)
|
|
278
|
-
// MATRIX: represents the ranges (index[0] == min, index[1] == max, index[2] == value to get)
|
|
279
|
-
// EXAMPLE:
|
|
280
|
-
// getValueForRange(width, [
|
|
281
|
-
// [0, 1000, 'small'], // ---> from 0 to 1000, return "small"
|
|
282
|
-
// [1000, null, 'big'], // ---> from 1000 to infinite, return "big"
|
|
283
|
-
// ])
|
|
284
|
-
const found = matrix.find(([min, max]) => current >= min && (max === null || current <= max));
|
|
285
|
-
return found?.[2] || null;
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const getWorkloadId = ({ namespace, name, kind }) => {
|
|
289
|
-
return { namespace, name, kind };
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const getYamlFieldsForDestination = (categories, destination) => {
|
|
293
|
-
const fields = [];
|
|
294
|
-
const parsedCategories = JSON.parse(JSON.stringify(categories));
|
|
295
|
-
for (const category of parsedCategories) {
|
|
296
|
-
const autoFilledFields = safeJsonParse(destination.fields, {});
|
|
297
|
-
const idx = category.items.findIndex((item) => item.type === destination.destinationType.type);
|
|
298
|
-
if (idx !== -1) {
|
|
299
|
-
fields.push(...category.items[idx].fields.map((field) => ({
|
|
300
|
-
...field,
|
|
301
|
-
initialValue: autoFilledFields[field.name],
|
|
302
|
-
})));
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return fields;
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const hasUnhealthyInstances = (containers, instances) => {
|
|
309
|
-
const hasUnhealthy = (list) => list?.some(({ healthy }) => healthy.status !== StatusType.Success);
|
|
310
|
-
if (containers?.length) {
|
|
311
|
-
return containers.some(({ instrumentationInstances }) => hasUnhealthy(instrumentationInstances));
|
|
312
|
-
}
|
|
313
|
-
return hasUnhealthy(instances) ?? false;
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
const isOverTime = (originDate, difference = 0) => {
|
|
317
|
-
const now = new Date().getTime();
|
|
318
|
-
const compareWith = new Date(originDate).getTime();
|
|
319
|
-
return compareWith - now <= difference;
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const mapDestinationFieldsForDisplay = (destination, yamlFields) => {
|
|
323
|
-
const parsedFields = safeJsonParse(destination.fields, {});
|
|
324
|
-
if (!yamlFields.length) {
|
|
325
|
-
return Object.entries(parsedFields).map(([key, value]) => ({
|
|
326
|
-
key,
|
|
327
|
-
name: key,
|
|
328
|
-
value,
|
|
329
|
-
}));
|
|
330
|
-
}
|
|
331
|
-
return yamlFields
|
|
332
|
-
.map((field) => ({
|
|
333
|
-
key: field.name,
|
|
334
|
-
name: field.displayName || field.name,
|
|
335
|
-
value: parsedFields[field.name] ?? null,
|
|
336
|
-
}))
|
|
337
|
-
.filter((item) => item.value !== null);
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
const sleep = async (ms = 1000) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
341
|
-
|
|
342
|
-
export { filterDestinations as a, filterDestinationsByStream as b, filterSources as c, filterSourcesByStream as d, formatBytes as e, filterActions as f, formatDuration as g, getContainersInstrumentedCount as h, getContainersIcons as i, getDestinationIcon as j, getEntityIcon as k, getEntityLabel as l, getMetricForEntity as m, getRecursiveValues as n, getValueForRange as o, getWorkloadId as p, getYamlFieldsForDestination as q, hasUnhealthyInstances as r, isOverTime as s, mapDestinationFieldsForDisplay as t, sleep as u };
|