@oneuptime/common 10.0.81 → 10.0.84
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/Models/AnalyticsModels/Metric.ts +296 -2
- package/Server/Services/MetricService.ts +228 -3
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +43 -3
- package/Types/AnalyticsDatabase/TableColumnType.ts +1 -0
- package/Types/BaseDatabase/AggregationType.ts +35 -0
- package/UI/Components/Banner/Banner.tsx +7 -2
- package/UI/Components/Breadcrumbs/Breadcrumbs.tsx +6 -2
- package/UI/Components/EventItem/EventItem.tsx +9 -5
- package/UI/Components/Label/Labels.tsx +10 -2
- package/UI/Components/Modal/ConfirmModal.tsx +5 -1
- package/UI/Components/Modal/Modal.tsx +21 -5
- package/UI/Components/ModelTable/BaseModelTable.tsx +7 -1
- package/UI/Components/Page/Page.tsx +6 -2
- package/UI/esbuild-config.js +8 -0
- package/build/dist/Models/AnalyticsModels/Metric.js +250 -2
- package/build/dist/Models/AnalyticsModels/Metric.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +183 -2
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +36 -2
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js +1 -0
- package/build/dist/Types/AnalyticsDatabase/TableColumnType.js.map +1 -1
- package/build/dist/Types/BaseDatabase/AggregationType.js +30 -0
- package/build/dist/Types/BaseDatabase/AggregationType.js.map +1 -1
- package/build/dist/UI/Components/Banner/Banner.js +6 -2
- package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
- package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js +5 -2
- package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js.map +1 -1
- package/build/dist/UI/Components/EventItem/EventItem.js +9 -7
- package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
- package/build/dist/UI/Components/Label/Labels.js +8 -2
- package/build/dist/UI/Components/Label/Labels.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +4 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +13 -3
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +7 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Page/Page.js +5 -2
- package/build/dist/UI/Components/Page/Page.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,41 @@ enum AggregationType {
|
|
|
4
4
|
Sum = "Sum",
|
|
5
5
|
Avg = "Avg",
|
|
6
6
|
Count = "Count",
|
|
7
|
+
/*
|
|
8
|
+
* Percentile aggregations. For Metric (the only model that carries
|
|
9
|
+
* histogram bucket data), MetricService overrides the aggregate path to
|
|
10
|
+
* fan out histogram buckets into weighted samples and use
|
|
11
|
+
* quantileExactWeighted, so a P95 of an `http.server.request.duration`
|
|
12
|
+
* histogram returns the bucket-derived 95th percentile rather than the
|
|
13
|
+
* 95th percentile of the per-row `sum`. For other models (Span, Log,
|
|
14
|
+
* etc.) the StatementGenerator falls back to ClickHouse's `quantile(p)`
|
|
15
|
+
* over the raw column, which is the right thing for scalar columns.
|
|
16
|
+
*/
|
|
17
|
+
P50 = "P50",
|
|
18
|
+
P90 = "P90",
|
|
19
|
+
P95 = "P95",
|
|
20
|
+
P99 = "P99",
|
|
7
21
|
}
|
|
8
22
|
|
|
9
23
|
export default AggregationType;
|
|
24
|
+
|
|
25
|
+
export const PercentileAggregationLevels: Record<string, number> = {
|
|
26
|
+
[AggregationType.P50]: 0.5,
|
|
27
|
+
[AggregationType.P90]: 0.9,
|
|
28
|
+
[AggregationType.P95]: 0.95,
|
|
29
|
+
[AggregationType.P99]: 0.99,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export function isPercentileAggregation(type: AggregationType): boolean {
|
|
33
|
+
return Object.prototype.hasOwnProperty.call(
|
|
34
|
+
PercentileAggregationLevels,
|
|
35
|
+
type,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getPercentileLevel(type: AggregationType): number | null {
|
|
40
|
+
if (!isPercentileAggregation(type)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return PercentileAggregationLevels[type] ?? null;
|
|
44
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Link from "../Link/Link";
|
|
2
2
|
import Route from "../../../Types/API/Route";
|
|
3
3
|
import URL from "../../../Types/API/URL";
|
|
4
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
4
5
|
import React, { FunctionComponent, ReactElement } from "react";
|
|
5
6
|
import { GetReactElementFunction } from "../../Types/FunctionTypes";
|
|
6
7
|
|
|
@@ -15,10 +16,14 @@ export interface ComponentProps {
|
|
|
15
16
|
const Banner: FunctionComponent<ComponentProps> = (
|
|
16
17
|
props: ComponentProps,
|
|
17
18
|
): ReactElement => {
|
|
19
|
+
const { translateString } = useTranslateValue();
|
|
20
|
+
const translatedTitle: string = translateString(props.title) || props.title;
|
|
21
|
+
const translatedDescription: string =
|
|
22
|
+
translateString(props.description) || props.description;
|
|
18
23
|
const getContent: GetReactElementFunction = (): ReactElement => {
|
|
19
24
|
return (
|
|
20
25
|
<>
|
|
21
|
-
<strong className="font-semibold">{
|
|
26
|
+
<strong className="font-semibold">{translatedTitle}</strong>
|
|
22
27
|
<svg
|
|
23
28
|
viewBox="0 0 2 2"
|
|
24
29
|
className="mx-2 inline h-0.5 w-0.5 fill-current"
|
|
@@ -26,7 +31,7 @@ const Banner: FunctionComponent<ComponentProps> = (
|
|
|
26
31
|
>
|
|
27
32
|
<circle cx="1" cy="1" r="1" />
|
|
28
33
|
</svg>
|
|
29
|
-
{
|
|
34
|
+
{translatedDescription}
|
|
30
35
|
<span aria-hidden="true">→</span>
|
|
31
36
|
</>
|
|
32
37
|
);
|
|
@@ -4,6 +4,7 @@ import Route from "../../../Types/API/Route";
|
|
|
4
4
|
import URL from "../../../Types/API/URL";
|
|
5
5
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
6
6
|
import Link from "../../../Types/Link";
|
|
7
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
7
8
|
import React, { FunctionComponent, ReactElement } from "react";
|
|
8
9
|
|
|
9
10
|
interface ComponentProps {
|
|
@@ -13,12 +14,15 @@ interface ComponentProps {
|
|
|
13
14
|
const Breadcrumbs: FunctionComponent<ComponentProps> = ({
|
|
14
15
|
links,
|
|
15
16
|
}: ComponentProps): ReactElement => {
|
|
17
|
+
const { translateString } = useTranslateValue();
|
|
16
18
|
return (
|
|
17
19
|
<nav className="flex hidden md:block" aria-label="Breadcrumb">
|
|
18
20
|
<ol role="list" className="flex items-center space-x-1">
|
|
19
21
|
{links &&
|
|
20
22
|
links.length > 0 &&
|
|
21
23
|
links.map((link: Link, i: number) => {
|
|
24
|
+
const translatedTitle: string =
|
|
25
|
+
translateString(link.title) || link.title;
|
|
22
26
|
return (
|
|
23
27
|
<li className="breadcrumb-item" key={i}>
|
|
24
28
|
{i === 0 && (
|
|
@@ -28,7 +32,7 @@ const Breadcrumbs: FunctionComponent<ComponentProps> = ({
|
|
|
28
32
|
className="text-gray-400 hover:text-gray-500 -mt-1"
|
|
29
33
|
>
|
|
30
34
|
<span className="text-sm font-medium text-gray-500 hover:text-gray-700 -mt-1">
|
|
31
|
-
{
|
|
35
|
+
{translatedTitle}
|
|
32
36
|
</span>
|
|
33
37
|
</UILink>
|
|
34
38
|
</div>
|
|
@@ -48,7 +52,7 @@ const Breadcrumbs: FunctionComponent<ComponentProps> = ({
|
|
|
48
52
|
}
|
|
49
53
|
className="ml-1 text-sm font-medium text-gray-500 hover:text-gray-700 -mt-1"
|
|
50
54
|
>
|
|
51
|
-
{
|
|
55
|
+
{translatedTitle}
|
|
52
56
|
</UILink>
|
|
53
57
|
</div>
|
|
54
58
|
)}
|
|
@@ -11,6 +11,7 @@ import Color from "../../../Types/Color";
|
|
|
11
11
|
import OneUptimeDate from "../../../Types/Date";
|
|
12
12
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
13
13
|
import React, { FunctionComponent, ReactElement } from "react";
|
|
14
|
+
import { useTranslation } from "react-i18next";
|
|
14
15
|
|
|
15
16
|
export enum TimelineItemType {
|
|
16
17
|
StateChange = "StateChange",
|
|
@@ -61,6 +62,7 @@ export interface ComponentProps {
|
|
|
61
62
|
const EventItem: FunctionComponent<ComponentProps> = (
|
|
62
63
|
props: ComponentProps,
|
|
63
64
|
): ReactElement => {
|
|
65
|
+
const { t } = useTranslation();
|
|
64
66
|
return (
|
|
65
67
|
<div className="mt-5 mb-5 bg-white shadow rounded-xl border-gray-100 p-5">
|
|
66
68
|
<div>
|
|
@@ -156,7 +158,7 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
|
|
156
158
|
<div key={0}>
|
|
157
159
|
<div className="flex flex-wrap gap-y-4 space-x-1 active-event-box-body-reesources">
|
|
158
160
|
<div className="text-sm text-gray-400 mr-3 mt-1">
|
|
159
|
-
|
|
161
|
+
{t("eventItem.affectedResources")}
|
|
160
162
|
</div>
|
|
161
163
|
{props.eventResourcesAffected?.map((item: string, i: number) => {
|
|
162
164
|
return (
|
|
@@ -222,7 +224,7 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
|
|
222
224
|
<span className="font-medium text-gray-900 mr-1">
|
|
223
225
|
{props.eventType}
|
|
224
226
|
</span>
|
|
225
|
-
|
|
227
|
+
{t("eventItem.stateChangedTo")}
|
|
226
228
|
</span>
|
|
227
229
|
<span className="mr-1">
|
|
228
230
|
<Pill
|
|
@@ -294,11 +296,13 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
|
|
294
296
|
>
|
|
295
297
|
{item.title
|
|
296
298
|
? item.title
|
|
297
|
-
:
|
|
299
|
+
: t("eventItem.updateTo", {
|
|
300
|
+
eventType: props.eventType,
|
|
301
|
+
})}
|
|
298
302
|
</span>
|
|
299
303
|
</div>
|
|
300
304
|
<p className="mt-0.5 text-sm text-gray-500">
|
|
301
|
-
|
|
305
|
+
{t("eventItem.postedOn")}{" "}
|
|
302
306
|
{OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(
|
|
303
307
|
item.date,
|
|
304
308
|
)}
|
|
@@ -345,7 +349,7 @@ const EventItem: FunctionComponent<ComponentProps> = (
|
|
|
345
349
|
className="cursor-pointer text-gray-400 hover:text-gray-500 text-sm"
|
|
346
350
|
to={props.eventViewRoute}
|
|
347
351
|
>
|
|
348
|
-
<>
|
|
352
|
+
<>{t("eventItem.view", { eventType: props.eventType })}</>
|
|
349
353
|
</Link>
|
|
350
354
|
</span>
|
|
351
355
|
) : (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import LabelElement from "./Label";
|
|
2
2
|
import TableColumnListComponent from "../TableColumnList/TableColumnListComponent";
|
|
3
3
|
import LabelModel from "../../../Models/DatabaseModels/Label";
|
|
4
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
4
5
|
import React, { FunctionComponent, ReactElement } from "react";
|
|
5
6
|
|
|
6
7
|
export interface ComponentProps {
|
|
@@ -10,10 +11,17 @@ export interface ComponentProps {
|
|
|
10
11
|
const LabelsElement: FunctionComponent<ComponentProps> = (
|
|
11
12
|
props: ComponentProps,
|
|
12
13
|
): ReactElement => {
|
|
14
|
+
const { translateString } = useTranslateValue();
|
|
15
|
+
const moreText: string =
|
|
16
|
+
props.labels.length > 4
|
|
17
|
+
? translateString("more labels") || "more labels"
|
|
18
|
+
: translateString("more label") || "more label";
|
|
19
|
+
const noItemsMessage: string =
|
|
20
|
+
translateString("No labels attached.") || "No labels attached.";
|
|
13
21
|
return (
|
|
14
22
|
<TableColumnListComponent
|
|
15
23
|
items={props.labels}
|
|
16
|
-
moreText={
|
|
24
|
+
moreText={moreText}
|
|
17
25
|
className={props.labels.length > 0 ? "-mb-1 -mt-1" : ""}
|
|
18
26
|
getEachElement={(label: LabelModel) => {
|
|
19
27
|
return (
|
|
@@ -27,7 +35,7 @@ const LabelsElement: FunctionComponent<ComponentProps> = (
|
|
|
27
35
|
</div>
|
|
28
36
|
);
|
|
29
37
|
}}
|
|
30
|
-
noItemsMessage=
|
|
38
|
+
noItemsMessage={noItemsMessage}
|
|
31
39
|
/>
|
|
32
40
|
);
|
|
33
41
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ButtonStyleType } from "../Button/Button";
|
|
2
2
|
import Modal from "./Modal";
|
|
3
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
3
4
|
import React, { FunctionComponent, ReactElement } from "react";
|
|
4
5
|
|
|
5
6
|
export interface ComponentProps {
|
|
@@ -19,6 +20,9 @@ export interface ComponentProps {
|
|
|
19
20
|
const ConfirmModal: FunctionComponent<ComponentProps> = (
|
|
20
21
|
props: ComponentProps,
|
|
21
22
|
): ReactElement => {
|
|
23
|
+
const { translateValue } = useTranslateValue();
|
|
24
|
+
const translatedDescription: string | ReactElement | undefined =
|
|
25
|
+
translateValue(props.description);
|
|
22
26
|
return (
|
|
23
27
|
<Modal
|
|
24
28
|
title={props.title}
|
|
@@ -46,7 +50,7 @@ const ConfirmModal: FunctionComponent<ComponentProps> = (
|
|
|
46
50
|
data-testid="confirm-modal-description"
|
|
47
51
|
className="text-gray-500 mt-5 text-sm whitespace-pre-wrap break-words max-h-96 overflow-y-auto pr-1"
|
|
48
52
|
>
|
|
49
|
-
{
|
|
53
|
+
{translatedDescription}
|
|
50
54
|
</div>
|
|
51
55
|
</Modal>
|
|
52
56
|
);
|
|
@@ -6,6 +6,7 @@ import ModalBody from "./ModalBody";
|
|
|
6
6
|
import ModalFooter from "./ModalFooter";
|
|
7
7
|
import { VeryLightGray } from "../../../Types/BrandColors";
|
|
8
8
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
9
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
9
10
|
import React, {
|
|
10
11
|
FunctionComponent,
|
|
11
12
|
ReactElement,
|
|
@@ -43,6 +44,17 @@ export interface ComponentProps {
|
|
|
43
44
|
const Modal: FunctionComponent<ComponentProps> = (
|
|
44
45
|
props: ComponentProps,
|
|
45
46
|
): ReactElement => {
|
|
47
|
+
const { translateString } = useTranslateValue();
|
|
48
|
+
const translatedTitle: string = translateString(props.title) || props.title;
|
|
49
|
+
const translatedDescription: string | undefined = translateString(
|
|
50
|
+
props.description,
|
|
51
|
+
);
|
|
52
|
+
const translatedSubmitButtonText: string | undefined = translateString(
|
|
53
|
+
props.submitButtonText,
|
|
54
|
+
);
|
|
55
|
+
const translatedCloseButtonText: string | undefined = translateString(
|
|
56
|
+
props.closeButtonText,
|
|
57
|
+
);
|
|
46
58
|
const modalRef: React.RefObject<HTMLDivElement> =
|
|
47
59
|
useRef<HTMLDivElement>(null);
|
|
48
60
|
|
|
@@ -162,15 +174,15 @@ const Modal: FunctionComponent<ComponentProps> = (
|
|
|
162
174
|
}`}
|
|
163
175
|
id="modal-title"
|
|
164
176
|
>
|
|
165
|
-
{
|
|
177
|
+
{translatedTitle}
|
|
166
178
|
</h3>
|
|
167
|
-
{
|
|
179
|
+
{translatedDescription && (
|
|
168
180
|
<p
|
|
169
181
|
id="modal-description"
|
|
170
182
|
data-testid="modal-description"
|
|
171
183
|
className="text-sm leading-6 text-gray-500 mt-2"
|
|
172
184
|
>
|
|
173
|
-
{
|
|
185
|
+
{translatedDescription}
|
|
174
186
|
</p>
|
|
175
187
|
)}
|
|
176
188
|
</div>
|
|
@@ -214,10 +226,14 @@ const Modal: FunctionComponent<ComponentProps> = (
|
|
|
214
226
|
: ButtonStyleType.NORMAL
|
|
215
227
|
}
|
|
216
228
|
submitButtonText={
|
|
217
|
-
|
|
229
|
+
translatedSubmitButtonText
|
|
230
|
+
? translatedSubmitButtonText
|
|
231
|
+
: translateString("Save") || "Save"
|
|
218
232
|
}
|
|
219
233
|
closeButtonText={
|
|
220
|
-
|
|
234
|
+
translatedCloseButtonText
|
|
235
|
+
? translatedCloseButtonText
|
|
236
|
+
: translateString("Cancel") || "Cancel"
|
|
221
237
|
}
|
|
222
238
|
onSubmit={props.onSubmit}
|
|
223
239
|
onClose={props.onClose ? props.onClose : undefined}
|
|
@@ -4,6 +4,7 @@ import { API_DOCS_URL, BILLING_ENABLED, getAllEnvVars } from "../../Config";
|
|
|
4
4
|
import { GetReactElementFunction } from "../../Types/FunctionTypes";
|
|
5
5
|
import SelectEntityField from "../../Types/SelectEntityField";
|
|
6
6
|
import API from "../../Utils/API/API";
|
|
7
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
7
8
|
|
|
8
9
|
import Query from "../../../Types/BaseDatabase/Query";
|
|
9
10
|
import GroupBy from "../../../Types/BaseDatabase/GroupBy";
|
|
@@ -266,6 +267,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
266
267
|
) => ReactElement = <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
267
268
|
props: ComponentProps<TBaseModel>,
|
|
268
269
|
): ReactElement => {
|
|
270
|
+
const { translateValue } = useTranslateValue();
|
|
269
271
|
const [tableView, setTableView] = useState<TableView | null>(null);
|
|
270
272
|
|
|
271
273
|
const matchBulkSelectedItemByField: keyof TBaseModel =
|
|
@@ -1917,6 +1919,10 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1917
1919
|
const getCardTitle: GetCardTitleFunction = (
|
|
1918
1920
|
title: ReactElement | string,
|
|
1919
1921
|
): ReactElement => {
|
|
1922
|
+
const renderedTitle: ReactElement | string =
|
|
1923
|
+
typeof title === "string"
|
|
1924
|
+
? (translateValue(title) as ReactElement | string | undefined) ?? title
|
|
1925
|
+
: title;
|
|
1920
1926
|
const plan: PlanType | null = ProjectUtil.getCurrentPlan();
|
|
1921
1927
|
|
|
1922
1928
|
let showPlan: boolean = Boolean(
|
|
@@ -1950,7 +1956,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1950
1956
|
|
|
1951
1957
|
return (
|
|
1952
1958
|
<span>
|
|
1953
|
-
{
|
|
1959
|
+
{renderedTitle}
|
|
1954
1960
|
{showPlan && (
|
|
1955
1961
|
<span
|
|
1956
1962
|
style={{
|
|
@@ -5,6 +5,7 @@ import PageLoader from "../Loader/PageLoader";
|
|
|
5
5
|
import LabelElement from "../Label/Label";
|
|
6
6
|
import Link from "../../../Types/Link";
|
|
7
7
|
import LabelModel from "../../../Models/DatabaseModels/Label";
|
|
8
|
+
import useTranslateValue from "../../Utils/Translation";
|
|
8
9
|
import React, { FunctionComponent, ReactElement, useEffect } from "react";
|
|
9
10
|
|
|
10
11
|
export interface ComponentProps {
|
|
@@ -22,6 +23,9 @@ export interface ComponentProps {
|
|
|
22
23
|
const Page: FunctionComponent<ComponentProps> = (
|
|
23
24
|
props: ComponentProps,
|
|
24
25
|
): ReactElement => {
|
|
26
|
+
const { translateString } = useTranslateValue();
|
|
27
|
+
const translatedTitle: string | undefined = translateString(props.title);
|
|
28
|
+
|
|
25
29
|
useEffect(() => {
|
|
26
30
|
if (props.breadcrumbLinks && props.breadcrumbLinks.length > 0) {
|
|
27
31
|
Analytics.capture(
|
|
@@ -60,7 +64,7 @@ const Page: FunctionComponent<ComponentProps> = (
|
|
|
60
64
|
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between sm:flex-wrap sm:gap-4">
|
|
61
65
|
<div className="flex flex-col gap-1 min-w-0">
|
|
62
66
|
<h1 className="text-xl font-semibold leading-7 text-gray-900 sm:text-xl sm:tracking-tight sm:truncate">
|
|
63
|
-
{
|
|
67
|
+
{translatedTitle}
|
|
64
68
|
</h1>
|
|
65
69
|
</div>
|
|
66
70
|
{props.headerRight && (
|
|
@@ -71,7 +75,7 @@ const Page: FunctionComponent<ComponentProps> = (
|
|
|
71
75
|
{props.labels && props.labels.length > 0 && (
|
|
72
76
|
<div className="hidden sm:flex sm:flex-wrap sm:items-center sm:justify-end sm:gap-3">
|
|
73
77
|
<span className="text-xs font-semibold uppercase tracking-wide text-gray-500 whitespace-nowrap">
|
|
74
|
-
Labels
|
|
78
|
+
{translateString("Labels") || "Labels"}
|
|
75
79
|
</span>
|
|
76
80
|
<div className="flex flex-wrap items-center gap-2 justify-end">
|
|
77
81
|
{props.labels
|
package/UI/esbuild-config.js
CHANGED
|
@@ -230,6 +230,8 @@ function createConfig(options) {
|
|
|
230
230
|
const isDev = process.env.NODE_ENV !== 'production';
|
|
231
231
|
const isAnalyze = process.env.analyze === 'true';
|
|
232
232
|
const reactRoot = resolvePackageRoot('react');
|
|
233
|
+
const reactI18nextRoot = resolvePackageRoot('react-i18next');
|
|
234
|
+
const i18nextRoot = resolvePackageRoot('i18next');
|
|
233
235
|
|
|
234
236
|
return {
|
|
235
237
|
entryPoints: [entryPoint],
|
|
@@ -252,6 +254,12 @@ function createConfig(options) {
|
|
|
252
254
|
'react': reactRoot,
|
|
253
255
|
'react/jsx-runtime': path.join(reactRoot, 'jsx-runtime.js'),
|
|
254
256
|
'react/jsx-dev-runtime': path.join(reactRoot, 'jsx-dev-runtime.js'),
|
|
257
|
+
// Force a single instance of i18next/react-i18next so that translations
|
|
258
|
+
// initialized in the service entry are visible to Common UI components.
|
|
259
|
+
// Without this, Common's own node_modules copy gets a separate, never-
|
|
260
|
+
// initialized i18n singleton and useTranslation() returns the raw key.
|
|
261
|
+
'react-i18next': reactI18nextRoot,
|
|
262
|
+
'i18next': i18nextRoot,
|
|
255
263
|
...additionalAlias,
|
|
256
264
|
},
|
|
257
265
|
plugins: [createMermaidPlugin(), createRefractorCompatibilityPlugin(), createCSSPlugin(), createFileLoaderPlugin()],
|
|
@@ -16,6 +16,7 @@ export var MetricPointType;
|
|
|
16
16
|
MetricPointType["Gauge"] = "Gauge";
|
|
17
17
|
MetricPointType["Histogram"] = "Histogram";
|
|
18
18
|
MetricPointType["ExponentialHistogram"] = "ExponentialHistogram";
|
|
19
|
+
MetricPointType["Summary"] = "Summary";
|
|
19
20
|
})(MetricPointType || (MetricPointType = {}));
|
|
20
21
|
export var ServiceType;
|
|
21
22
|
(function (ServiceType) {
|
|
@@ -473,8 +474,147 @@ export default class Metric extends AnalyticsBaseModel {
|
|
|
473
474
|
});
|
|
474
475
|
const explicitBoundsColumn = new AnalyticsTableColumn({
|
|
475
476
|
key: "explicitBounds",
|
|
476
|
-
title: "Explicit
|
|
477
|
-
description: "
|
|
477
|
+
title: "Explicit Bounds",
|
|
478
|
+
description: "Upper bounds (exclusive of the +inf overflow bucket) for each explicit-bucket histogram bucket. Stored as Float64 so sub-integer boundaries (e.g. 0.005, 0.01) survive ingest — the previous Array(Int64) representation silently truncated those to 0.",
|
|
479
|
+
required: true,
|
|
480
|
+
defaultValue: [],
|
|
481
|
+
type: TableColumnType.ArrayDecimal,
|
|
482
|
+
accessControl: {
|
|
483
|
+
read: [
|
|
484
|
+
Permission.ProjectOwner,
|
|
485
|
+
Permission.ProjectAdmin,
|
|
486
|
+
Permission.ProjectMember,
|
|
487
|
+
Permission.ReadTelemetryServiceLog,
|
|
488
|
+
],
|
|
489
|
+
create: [
|
|
490
|
+
Permission.ProjectOwner,
|
|
491
|
+
Permission.ProjectAdmin,
|
|
492
|
+
Permission.ProjectMember,
|
|
493
|
+
Permission.CreateTelemetryServiceLog,
|
|
494
|
+
],
|
|
495
|
+
update: [],
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
/*
|
|
499
|
+
* --- ExponentialHistogram-only columns ----------------------------------
|
|
500
|
+
* These are populated only when metricPointType = ExponentialHistogram.
|
|
501
|
+
* For other metric types they are left at their defaults (0 / []).
|
|
502
|
+
*/
|
|
503
|
+
const scaleColumn = new AnalyticsTableColumn({
|
|
504
|
+
key: "scale",
|
|
505
|
+
title: "Scale",
|
|
506
|
+
description: "ExponentialHistogram resolution. base = 2^(2^-scale); bucket index `i` covers (base^i, base^(i+1)].",
|
|
507
|
+
required: false,
|
|
508
|
+
type: TableColumnType.Number,
|
|
509
|
+
accessControl: {
|
|
510
|
+
read: [
|
|
511
|
+
Permission.ProjectOwner,
|
|
512
|
+
Permission.ProjectAdmin,
|
|
513
|
+
Permission.ProjectMember,
|
|
514
|
+
Permission.ReadTelemetryServiceLog,
|
|
515
|
+
],
|
|
516
|
+
create: [
|
|
517
|
+
Permission.ProjectOwner,
|
|
518
|
+
Permission.ProjectAdmin,
|
|
519
|
+
Permission.ProjectMember,
|
|
520
|
+
Permission.CreateTelemetryServiceLog,
|
|
521
|
+
],
|
|
522
|
+
update: [],
|
|
523
|
+
},
|
|
524
|
+
});
|
|
525
|
+
const zeroCountColumn = new AnalyticsTableColumn({
|
|
526
|
+
key: "zeroCount",
|
|
527
|
+
title: "Zero Count",
|
|
528
|
+
description: "ExponentialHistogram count of values within the zero region (|v| <= zeroThreshold).",
|
|
529
|
+
required: false,
|
|
530
|
+
type: TableColumnType.BigNumber,
|
|
531
|
+
accessControl: {
|
|
532
|
+
read: [
|
|
533
|
+
Permission.ProjectOwner,
|
|
534
|
+
Permission.ProjectAdmin,
|
|
535
|
+
Permission.ProjectMember,
|
|
536
|
+
Permission.ReadTelemetryServiceLog,
|
|
537
|
+
],
|
|
538
|
+
create: [
|
|
539
|
+
Permission.ProjectOwner,
|
|
540
|
+
Permission.ProjectAdmin,
|
|
541
|
+
Permission.ProjectMember,
|
|
542
|
+
Permission.CreateTelemetryServiceLog,
|
|
543
|
+
],
|
|
544
|
+
update: [],
|
|
545
|
+
},
|
|
546
|
+
});
|
|
547
|
+
const positiveOffsetColumn = new AnalyticsTableColumn({
|
|
548
|
+
key: "positiveOffset",
|
|
549
|
+
title: "Positive Bucket Offset",
|
|
550
|
+
description: "Bucket index of the first entry in positiveBucketCounts (ExponentialHistogram).",
|
|
551
|
+
required: false,
|
|
552
|
+
type: TableColumnType.Number,
|
|
553
|
+
accessControl: {
|
|
554
|
+
read: [
|
|
555
|
+
Permission.ProjectOwner,
|
|
556
|
+
Permission.ProjectAdmin,
|
|
557
|
+
Permission.ProjectMember,
|
|
558
|
+
Permission.ReadTelemetryServiceLog,
|
|
559
|
+
],
|
|
560
|
+
create: [
|
|
561
|
+
Permission.ProjectOwner,
|
|
562
|
+
Permission.ProjectAdmin,
|
|
563
|
+
Permission.ProjectMember,
|
|
564
|
+
Permission.CreateTelemetryServiceLog,
|
|
565
|
+
],
|
|
566
|
+
update: [],
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
const positiveBucketCountsColumn = new AnalyticsTableColumn({
|
|
570
|
+
key: "positiveBucketCounts",
|
|
571
|
+
title: "Positive Bucket Counts",
|
|
572
|
+
description: "Counts for the positive range of an ExponentialHistogram, indexed from positiveOffset.",
|
|
573
|
+
required: true,
|
|
574
|
+
defaultValue: [],
|
|
575
|
+
type: TableColumnType.ArrayBigNumber,
|
|
576
|
+
accessControl: {
|
|
577
|
+
read: [
|
|
578
|
+
Permission.ProjectOwner,
|
|
579
|
+
Permission.ProjectAdmin,
|
|
580
|
+
Permission.ProjectMember,
|
|
581
|
+
Permission.ReadTelemetryServiceLog,
|
|
582
|
+
],
|
|
583
|
+
create: [
|
|
584
|
+
Permission.ProjectOwner,
|
|
585
|
+
Permission.ProjectAdmin,
|
|
586
|
+
Permission.ProjectMember,
|
|
587
|
+
Permission.CreateTelemetryServiceLog,
|
|
588
|
+
],
|
|
589
|
+
update: [],
|
|
590
|
+
},
|
|
591
|
+
});
|
|
592
|
+
const negativeOffsetColumn = new AnalyticsTableColumn({
|
|
593
|
+
key: "negativeOffset",
|
|
594
|
+
title: "Negative Bucket Offset",
|
|
595
|
+
description: "Bucket index of the first entry in negativeBucketCounts (ExponentialHistogram).",
|
|
596
|
+
required: false,
|
|
597
|
+
type: TableColumnType.Number,
|
|
598
|
+
accessControl: {
|
|
599
|
+
read: [
|
|
600
|
+
Permission.ProjectOwner,
|
|
601
|
+
Permission.ProjectAdmin,
|
|
602
|
+
Permission.ProjectMember,
|
|
603
|
+
Permission.ReadTelemetryServiceLog,
|
|
604
|
+
],
|
|
605
|
+
create: [
|
|
606
|
+
Permission.ProjectOwner,
|
|
607
|
+
Permission.ProjectAdmin,
|
|
608
|
+
Permission.ProjectMember,
|
|
609
|
+
Permission.CreateTelemetryServiceLog,
|
|
610
|
+
],
|
|
611
|
+
update: [],
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
const negativeBucketCountsColumn = new AnalyticsTableColumn({
|
|
615
|
+
key: "negativeBucketCounts",
|
|
616
|
+
title: "Negative Bucket Counts",
|
|
617
|
+
description: "Counts for the negative range of an ExponentialHistogram, indexed from negativeOffset.",
|
|
478
618
|
required: true,
|
|
479
619
|
defaultValue: [],
|
|
480
620
|
type: TableColumnType.ArrayBigNumber,
|
|
@@ -494,6 +634,58 @@ export default class Metric extends AnalyticsBaseModel {
|
|
|
494
634
|
update: [],
|
|
495
635
|
},
|
|
496
636
|
});
|
|
637
|
+
/*
|
|
638
|
+
* --- Summary-only columns -----------------------------------------------
|
|
639
|
+
* Populated only when metricPointType = Summary. Two parallel arrays
|
|
640
|
+
* keyed by index (mirrors the bucketCounts/explicitBounds convention):
|
|
641
|
+
* summaryQuantiles[i] in [0,1], summaryValues[i] is value at that quantile.
|
|
642
|
+
*/
|
|
643
|
+
const summaryQuantilesColumn = new AnalyticsTableColumn({
|
|
644
|
+
key: "summaryQuantiles",
|
|
645
|
+
title: "Summary Quantiles",
|
|
646
|
+
description: "Quantile percentages in [0,1] for a Summary metric (parallel to summaryValues).",
|
|
647
|
+
required: true,
|
|
648
|
+
defaultValue: [],
|
|
649
|
+
type: TableColumnType.ArrayDecimal,
|
|
650
|
+
accessControl: {
|
|
651
|
+
read: [
|
|
652
|
+
Permission.ProjectOwner,
|
|
653
|
+
Permission.ProjectAdmin,
|
|
654
|
+
Permission.ProjectMember,
|
|
655
|
+
Permission.ReadTelemetryServiceLog,
|
|
656
|
+
],
|
|
657
|
+
create: [
|
|
658
|
+
Permission.ProjectOwner,
|
|
659
|
+
Permission.ProjectAdmin,
|
|
660
|
+
Permission.ProjectMember,
|
|
661
|
+
Permission.CreateTelemetryServiceLog,
|
|
662
|
+
],
|
|
663
|
+
update: [],
|
|
664
|
+
},
|
|
665
|
+
});
|
|
666
|
+
const summaryValuesColumn = new AnalyticsTableColumn({
|
|
667
|
+
key: "summaryValues",
|
|
668
|
+
title: "Summary Values",
|
|
669
|
+
description: "Values corresponding to each quantile in summaryQuantiles for a Summary metric.",
|
|
670
|
+
required: true,
|
|
671
|
+
defaultValue: [],
|
|
672
|
+
type: TableColumnType.ArrayDecimal,
|
|
673
|
+
accessControl: {
|
|
674
|
+
read: [
|
|
675
|
+
Permission.ProjectOwner,
|
|
676
|
+
Permission.ProjectAdmin,
|
|
677
|
+
Permission.ProjectMember,
|
|
678
|
+
Permission.ReadTelemetryServiceLog,
|
|
679
|
+
],
|
|
680
|
+
create: [
|
|
681
|
+
Permission.ProjectOwner,
|
|
682
|
+
Permission.ProjectAdmin,
|
|
683
|
+
Permission.ProjectMember,
|
|
684
|
+
Permission.CreateTelemetryServiceLog,
|
|
685
|
+
],
|
|
686
|
+
update: [],
|
|
687
|
+
},
|
|
688
|
+
});
|
|
497
689
|
const traceIdColumn = new AnalyticsTableColumn({
|
|
498
690
|
key: "traceId",
|
|
499
691
|
title: "Trace ID",
|
|
@@ -611,6 +803,14 @@ export default class Metric extends AnalyticsBaseModel {
|
|
|
611
803
|
maxColumn,
|
|
612
804
|
bucketCountsColumn,
|
|
613
805
|
explicitBoundsColumn,
|
|
806
|
+
scaleColumn,
|
|
807
|
+
zeroCountColumn,
|
|
808
|
+
positiveOffsetColumn,
|
|
809
|
+
positiveBucketCountsColumn,
|
|
810
|
+
negativeOffsetColumn,
|
|
811
|
+
negativeBucketCountsColumn,
|
|
812
|
+
summaryQuantilesColumn,
|
|
813
|
+
summaryValuesColumn,
|
|
614
814
|
traceIdColumn,
|
|
615
815
|
spanIdColumn,
|
|
616
816
|
retentionDateColumn,
|
|
@@ -760,5 +960,53 @@ export default class Metric extends AnalyticsBaseModel {
|
|
|
760
960
|
set retentionDate(v) {
|
|
761
961
|
this.setColumnValue("retentionDate", v);
|
|
762
962
|
}
|
|
963
|
+
get scale() {
|
|
964
|
+
return this.getColumnValue("scale");
|
|
965
|
+
}
|
|
966
|
+
set scale(v) {
|
|
967
|
+
this.setColumnValue("scale", v);
|
|
968
|
+
}
|
|
969
|
+
get zeroCount() {
|
|
970
|
+
return this.getColumnValue("zeroCount");
|
|
971
|
+
}
|
|
972
|
+
set zeroCount(v) {
|
|
973
|
+
this.setColumnValue("zeroCount", v);
|
|
974
|
+
}
|
|
975
|
+
get positiveOffset() {
|
|
976
|
+
return this.getColumnValue("positiveOffset");
|
|
977
|
+
}
|
|
978
|
+
set positiveOffset(v) {
|
|
979
|
+
this.setColumnValue("positiveOffset", v);
|
|
980
|
+
}
|
|
981
|
+
get positiveBucketCounts() {
|
|
982
|
+
return this.getColumnValue("positiveBucketCounts");
|
|
983
|
+
}
|
|
984
|
+
set positiveBucketCounts(v) {
|
|
985
|
+
this.setColumnValue("positiveBucketCounts", v);
|
|
986
|
+
}
|
|
987
|
+
get negativeOffset() {
|
|
988
|
+
return this.getColumnValue("negativeOffset");
|
|
989
|
+
}
|
|
990
|
+
set negativeOffset(v) {
|
|
991
|
+
this.setColumnValue("negativeOffset", v);
|
|
992
|
+
}
|
|
993
|
+
get negativeBucketCounts() {
|
|
994
|
+
return this.getColumnValue("negativeBucketCounts");
|
|
995
|
+
}
|
|
996
|
+
set negativeBucketCounts(v) {
|
|
997
|
+
this.setColumnValue("negativeBucketCounts", v);
|
|
998
|
+
}
|
|
999
|
+
get summaryQuantiles() {
|
|
1000
|
+
return this.getColumnValue("summaryQuantiles");
|
|
1001
|
+
}
|
|
1002
|
+
set summaryQuantiles(v) {
|
|
1003
|
+
this.setColumnValue("summaryQuantiles", v);
|
|
1004
|
+
}
|
|
1005
|
+
get summaryValues() {
|
|
1006
|
+
return this.getColumnValue("summaryValues");
|
|
1007
|
+
}
|
|
1008
|
+
set summaryValues(v) {
|
|
1009
|
+
this.setColumnValue("summaryValues", v);
|
|
1010
|
+
}
|
|
763
1011
|
}
|
|
764
1012
|
//# sourceMappingURL=Metric.js.map
|