mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-31 10:22:00 +08:00
Use fetch fix (#995)
* feat: useFetch in tag value is removed and moved to use query * feat: useFetch in all channels is removed and moved to use query * feat: useFetch in edit rule is removed and moved to use query * feat: useFetch in general settings is removed and moved to use query * feat: useFetch in all alerts is changed into use query
This commit is contained in:
parent
844ca57686
commit
93638d5615
323
frontend/src/container/GeneralSettings/GeneralSettings.tsx
Normal file
323
frontend/src/container/GeneralSettings/GeneralSettings.tsx
Normal file
@ -0,0 +1,323 @@
|
||||
import { Button, Col, Modal, notification, Row, Typography } from 'antd';
|
||||
import setRetentionApi from 'api/settings/setRetention';
|
||||
import TextToolTip from 'components/TextToolTip';
|
||||
import find from 'lodash-es/find';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
IDiskType,
|
||||
PayloadProps as GetDisksPayload,
|
||||
} from 'types/api/disks/getDisks';
|
||||
import { PayloadProps as GetRetentionPayload } from 'types/api/settings/getRetention';
|
||||
|
||||
import Retention from './Retention';
|
||||
import { ButtonContainer, ErrorText, ErrorTextContainer } from './styles';
|
||||
|
||||
type NumberOrNull = number | null;
|
||||
|
||||
function GeneralSettings({
|
||||
ttlValuesPayload,
|
||||
getAvailableDiskPayload,
|
||||
}: GeneralSettingsProps): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const [modal, setModal] = useState<boolean>(false);
|
||||
const [postApiLoading, setPostApiLoading] = useState<boolean>(false);
|
||||
|
||||
const [availableDisks] = useState<IDiskType[]>(getAvailableDiskPayload);
|
||||
|
||||
const [currentTTLValues, setCurrentTTLValues] = useState(ttlValuesPayload);
|
||||
|
||||
const [
|
||||
metricsTotalRetentionPeriod,
|
||||
setMetricsTotalRetentionPeriod,
|
||||
] = useState<NumberOrNull>(null);
|
||||
const [
|
||||
metricsS3RetentionPeriod,
|
||||
setMetricsS3RetentionPeriod,
|
||||
] = useState<NumberOrNull>(null);
|
||||
const [
|
||||
tracesTotalRetentionPeriod,
|
||||
setTracesTotalRetentionPeriod,
|
||||
] = useState<NumberOrNull>(null);
|
||||
const [
|
||||
tracesS3RetentionPeriod,
|
||||
setTracesS3RetentionPeriod,
|
||||
] = useState<NumberOrNull>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentTTLValues) {
|
||||
setMetricsTotalRetentionPeriod(currentTTLValues.metrics_ttl_duration_hrs);
|
||||
setMetricsS3RetentionPeriod(
|
||||
currentTTLValues.metrics_move_ttl_duration_hrs
|
||||
? currentTTLValues.metrics_move_ttl_duration_hrs
|
||||
: null,
|
||||
);
|
||||
setTracesTotalRetentionPeriod(currentTTLValues.traces_ttl_duration_hrs);
|
||||
setTracesS3RetentionPeriod(
|
||||
currentTTLValues.traces_move_ttl_duration_hrs
|
||||
? currentTTLValues.traces_move_ttl_duration_hrs
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}, [currentTTLValues]);
|
||||
|
||||
const onModalToggleHandler = (): void => {
|
||||
setModal((modal) => !modal);
|
||||
};
|
||||
|
||||
const onClickSaveHandler = useCallback(() => {
|
||||
onModalToggleHandler();
|
||||
}, []);
|
||||
|
||||
const s3Enabled = useMemo(
|
||||
() => !!find(availableDisks, (disks: IDiskType) => disks?.type === 's3'),
|
||||
[availableDisks],
|
||||
);
|
||||
|
||||
const renderConfig = [
|
||||
{
|
||||
name: 'Metrics',
|
||||
retentionFields: [
|
||||
{
|
||||
name: t('settings.total_retention_period'),
|
||||
value: metricsTotalRetentionPeriod,
|
||||
setValue: setMetricsTotalRetentionPeriod,
|
||||
},
|
||||
{
|
||||
name: t('settings.move_to_s3'),
|
||||
value: metricsS3RetentionPeriod,
|
||||
setValue: setMetricsS3RetentionPeriod,
|
||||
hide: !s3Enabled,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Traces',
|
||||
retentionFields: [
|
||||
{
|
||||
name: t('settings.total_retention_period'),
|
||||
value: tracesTotalRetentionPeriod,
|
||||
setValue: setTracesTotalRetentionPeriod,
|
||||
},
|
||||
{
|
||||
name: t('settings.move_to_s3'),
|
||||
value: tracesS3RetentionPeriod,
|
||||
setValue: setTracesS3RetentionPeriod,
|
||||
hide: !s3Enabled,
|
||||
},
|
||||
],
|
||||
},
|
||||
].map((category): JSX.Element | null => {
|
||||
if (
|
||||
Array.isArray(category.retentionFields) &&
|
||||
category.retentionFields.length > 0
|
||||
) {
|
||||
return (
|
||||
<Col flex="40%" style={{ minWidth: 475 }} key={category.name}>
|
||||
<Typography.Title level={3}>{category.name}</Typography.Title>
|
||||
|
||||
{category.retentionFields.map((retentionField) => (
|
||||
<Retention
|
||||
key={retentionField.name}
|
||||
text={retentionField.name}
|
||||
retentionValue={retentionField.value}
|
||||
setRetentionValue={retentionField.setValue}
|
||||
hide={!!retentionField.hide}
|
||||
/>
|
||||
))}
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
const onOkHandler = async (): Promise<void> => {
|
||||
try {
|
||||
setPostApiLoading(true);
|
||||
const apiCalls = [];
|
||||
|
||||
if (
|
||||
!(
|
||||
currentTTLValues?.metrics_move_ttl_duration_hrs ===
|
||||
metricsS3RetentionPeriod &&
|
||||
currentTTLValues.metrics_ttl_duration_hrs === metricsTotalRetentionPeriod
|
||||
)
|
||||
) {
|
||||
apiCalls.push(() =>
|
||||
setRetentionApi({
|
||||
type: 'metrics',
|
||||
totalDuration: `${metricsTotalRetentionPeriod || -1}h`,
|
||||
coldStorage: s3Enabled ? 's3' : null,
|
||||
toColdDuration: `${metricsS3RetentionPeriod || -1}h`,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
apiCalls.push(() => Promise.resolve(null));
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
currentTTLValues?.traces_move_ttl_duration_hrs ===
|
||||
tracesS3RetentionPeriod &&
|
||||
currentTTLValues.traces_ttl_duration_hrs === tracesTotalRetentionPeriod
|
||||
)
|
||||
) {
|
||||
apiCalls.push(() =>
|
||||
setRetentionApi({
|
||||
type: 'traces',
|
||||
totalDuration: `${tracesTotalRetentionPeriod || -1}h`,
|
||||
coldStorage: s3Enabled ? 's3' : null,
|
||||
toColdDuration: `${tracesS3RetentionPeriod || -1}h`,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
apiCalls.push(() => Promise.resolve(null));
|
||||
}
|
||||
const apiCallSequence = ['metrics', 'traces'];
|
||||
const apiResponses = await Promise.all(apiCalls.map((api) => api()));
|
||||
|
||||
apiResponses.forEach((apiResponse, idx) => {
|
||||
const name = apiCallSequence[idx];
|
||||
if (apiResponse) {
|
||||
if (apiResponse.statusCode === 200) {
|
||||
notification.success({
|
||||
message: 'Success!',
|
||||
placement: 'topRight',
|
||||
|
||||
description: t('settings.retention_success_message', { name }),
|
||||
});
|
||||
} else {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: t('settings.retention_error_message', { name }),
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
onModalToggleHandler();
|
||||
setPostApiLoading(false);
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: t('settings.retention_failed_message'),
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
// Updates the currentTTL Values in order to avoid pushing the same values.
|
||||
setCurrentTTLValues({
|
||||
metrics_ttl_duration_hrs: metricsTotalRetentionPeriod || -1,
|
||||
metrics_move_ttl_duration_hrs: metricsS3RetentionPeriod || -1,
|
||||
traces_ttl_duration_hrs: tracesTotalRetentionPeriod || -1,
|
||||
traces_move_ttl_duration_hrs: tracesS3RetentionPeriod || -1,
|
||||
});
|
||||
|
||||
setModal(false);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
const [isDisabled, errorText] = useMemo((): [boolean, string] => {
|
||||
// Various methods to return dynamic error message text.
|
||||
const messages = {
|
||||
compareError: (name: string | number): string =>
|
||||
t('settings.retention_comparison_error', { name }),
|
||||
nullValueError: (name: string | number): string =>
|
||||
t('settings.retention_null_value_error', { name }),
|
||||
};
|
||||
|
||||
// Defaults to button not disabled and empty error message text.
|
||||
let isDisabled = false;
|
||||
let errorText = '';
|
||||
|
||||
if (s3Enabled) {
|
||||
if (
|
||||
(metricsTotalRetentionPeriod || metricsS3RetentionPeriod) &&
|
||||
Number(metricsTotalRetentionPeriod) <= Number(metricsS3RetentionPeriod)
|
||||
) {
|
||||
isDisabled = true;
|
||||
errorText = messages.compareError('metrics');
|
||||
} else if (
|
||||
(tracesTotalRetentionPeriod || tracesS3RetentionPeriod) &&
|
||||
Number(tracesTotalRetentionPeriod) <= Number(tracesS3RetentionPeriod)
|
||||
) {
|
||||
isDisabled = true;
|
||||
errorText = messages.compareError('traces');
|
||||
}
|
||||
}
|
||||
|
||||
if (!metricsTotalRetentionPeriod || !tracesTotalRetentionPeriod) {
|
||||
isDisabled = true;
|
||||
if (!metricsTotalRetentionPeriod && !tracesTotalRetentionPeriod) {
|
||||
errorText = messages.nullValueError('metrics and traces');
|
||||
} else if (!metricsTotalRetentionPeriod) {
|
||||
errorText = messages.nullValueError('metrics');
|
||||
} else if (!tracesTotalRetentionPeriod) {
|
||||
errorText = messages.nullValueError('traces');
|
||||
}
|
||||
}
|
||||
if (
|
||||
currentTTLValues?.metrics_ttl_duration_hrs === metricsTotalRetentionPeriod &&
|
||||
currentTTLValues.metrics_move_ttl_duration_hrs ===
|
||||
metricsS3RetentionPeriod &&
|
||||
currentTTLValues.traces_ttl_duration_hrs === tracesTotalRetentionPeriod &&
|
||||
currentTTLValues.traces_move_ttl_duration_hrs === tracesS3RetentionPeriod
|
||||
) {
|
||||
isDisabled = true;
|
||||
}
|
||||
return [isDisabled, errorText];
|
||||
}, [
|
||||
currentTTLValues,
|
||||
metricsS3RetentionPeriod,
|
||||
metricsTotalRetentionPeriod,
|
||||
s3Enabled,
|
||||
t,
|
||||
tracesS3RetentionPeriod,
|
||||
tracesTotalRetentionPeriod,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}>
|
||||
{Element}
|
||||
<ErrorTextContainer>
|
||||
<TextToolTip
|
||||
{...{
|
||||
text: `More details on how to set retention period`,
|
||||
url: 'https://signoz.io/docs/userguide/retention-period/',
|
||||
}}
|
||||
/>
|
||||
{errorText && <ErrorText>{errorText}</ErrorText>}
|
||||
</ErrorTextContainer>
|
||||
|
||||
<Row justify="space-around">{renderConfig}</Row>
|
||||
|
||||
<Modal
|
||||
title={t('settings.retention_confirmation')}
|
||||
focusTriggerAfterClose
|
||||
forceRender
|
||||
destroyOnClose
|
||||
closable
|
||||
onCancel={onModalToggleHandler}
|
||||
onOk={onOkHandler}
|
||||
centered
|
||||
visible={modal}
|
||||
confirmLoading={postApiLoading}
|
||||
>
|
||||
<Typography>{t('settings.retention_confirmation_description')}</Typography>
|
||||
</Modal>
|
||||
|
||||
<ButtonContainer>
|
||||
<Button onClick={onClickSaveHandler} disabled={isDisabled} type="primary">
|
||||
Save
|
||||
</Button>
|
||||
</ButtonContainer>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
|
||||
interface GeneralSettingsProps {
|
||||
ttlValuesPayload: GetRetentionPayload;
|
||||
getAvailableDiskPayload: GetDisksPayload;
|
||||
}
|
||||
|
||||
export default GeneralSettings;
|
@ -1,331 +1,52 @@
|
||||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
import { Button, Col, Modal, notification, Row, Typography } from 'antd';
|
||||
import { Typography } from 'antd';
|
||||
import getDisks from 'api/disks/getDisks';
|
||||
import getRetentionPeriodApi from 'api/settings/getRetention';
|
||||
import setRetentionApi from 'api/settings/setRetention';
|
||||
import Spinner from 'components/Spinner';
|
||||
import TextToolTip from 'components/TextToolTip';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import { find } from 'lodash-es';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IDiskType } from 'types/api/disks/getDisks';
|
||||
import { PayloadProps } from 'types/api/settings/getRetention';
|
||||
import { useQueries } from 'react-query';
|
||||
|
||||
import Retention from './Retention';
|
||||
import { ButtonContainer, ErrorText, ErrorTextContainer } from './styles';
|
||||
import GeneralSettingsContainer from './GeneralSettings';
|
||||
|
||||
function GeneralSettings(): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const [notifications, Element] = notification.useNotification();
|
||||
const [modal, setModal] = useState<boolean>(false);
|
||||
const [postApiLoading, setPostApiLoading] = useState<boolean>(false);
|
||||
|
||||
const [availableDisks, setAvailableDisks] = useState<IDiskType[] | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
getDisks().then((response) => setAvailableDisks(response.payload));
|
||||
}, []);
|
||||
|
||||
const { payload, loading, error, errorMessage } = useFetch<
|
||||
PayloadProps,
|
||||
undefined
|
||||
>(getRetentionPeriodApi, undefined);
|
||||
|
||||
const [currentTTLValues, setCurrentTTLValues] = useState(payload);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentTTLValues(payload);
|
||||
}, [payload]);
|
||||
|
||||
const [metricsTotalRetentionPeriod, setMetricsTotalRetentionPeriod] = useState<
|
||||
number | null
|
||||
>(null);
|
||||
const [metricsS3RetentionPeriod, setMetricsS3RetentionPeriod] = useState<
|
||||
number | null
|
||||
>(null);
|
||||
const [tracesTotalRetentionPeriod, setTracesTotalRetentionPeriod] = useState<
|
||||
number | null
|
||||
>(null);
|
||||
const [tracesS3RetentionPeriod, setTracesS3RetentionPeriod] = useState<
|
||||
number | null
|
||||
>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentTTLValues) {
|
||||
setMetricsTotalRetentionPeriod(currentTTLValues.metrics_ttl_duration_hrs);
|
||||
setMetricsS3RetentionPeriod(
|
||||
currentTTLValues.metrics_move_ttl_duration_hrs
|
||||
? currentTTLValues.metrics_move_ttl_duration_hrs
|
||||
: null,
|
||||
);
|
||||
setTracesTotalRetentionPeriod(currentTTLValues.traces_ttl_duration_hrs);
|
||||
setTracesS3RetentionPeriod(
|
||||
currentTTLValues.traces_move_ttl_duration_hrs
|
||||
? currentTTLValues.traces_move_ttl_duration_hrs
|
||||
: null,
|
||||
);
|
||||
}
|
||||
console.log({ changed: currentTTLValues });
|
||||
}, [currentTTLValues]);
|
||||
|
||||
const onModalToggleHandler = (): void => {
|
||||
setModal((modal) => !modal);
|
||||
};
|
||||
|
||||
const onClickSaveHandler = useCallback(() => {
|
||||
onModalToggleHandler();
|
||||
}, []);
|
||||
|
||||
const s3Enabled = useMemo(
|
||||
() => !!find(availableDisks, (disks: IDiskType) => disks?.type === 's3'),
|
||||
[availableDisks],
|
||||
);
|
||||
|
||||
const renderConfig = [
|
||||
const { t } = useTranslation('common');
|
||||
const [getRetentionPeriodApiResponse, getDisksResponse] = useQueries([
|
||||
{
|
||||
name: 'Metrics',
|
||||
retentionFields: [
|
||||
{
|
||||
name: t('settings.total_retention_period'),
|
||||
value: metricsTotalRetentionPeriod,
|
||||
setValue: setMetricsTotalRetentionPeriod,
|
||||
},
|
||||
{
|
||||
name: t('settings.move_to_s3'),
|
||||
value: metricsS3RetentionPeriod,
|
||||
setValue: setMetricsS3RetentionPeriod,
|
||||
hide: !s3Enabled,
|
||||
},
|
||||
],
|
||||
queryFn: getRetentionPeriodApi,
|
||||
queryKey: 'getRetentionPeriodApi',
|
||||
},
|
||||
{
|
||||
name: 'Traces',
|
||||
retentionFields: [
|
||||
{
|
||||
name: t('settings.total_retention_period'),
|
||||
value: tracesTotalRetentionPeriod,
|
||||
setValue: setTracesTotalRetentionPeriod,
|
||||
},
|
||||
{
|
||||
name: t('settings.move_to_s3'),
|
||||
value: tracesS3RetentionPeriod,
|
||||
setValue: setTracesS3RetentionPeriod,
|
||||
hide: !s3Enabled,
|
||||
},
|
||||
],
|
||||
queryFn: getDisks,
|
||||
queryKey: 'getDisks',
|
||||
},
|
||||
].map((category): JSX.Element | null => {
|
||||
if (
|
||||
Array.isArray(category.retentionFields) &&
|
||||
category.retentionFields.length > 0
|
||||
) {
|
||||
return (
|
||||
<Col flex="40%" style={{ minWidth: 475 }} key={category.name}>
|
||||
<Typography.Title level={3}>{category.name}</Typography.Title>
|
||||
|
||||
{category.retentionFields.map((retentionField) => (
|
||||
<Retention
|
||||
key={retentionField.name}
|
||||
text={retentionField.name}
|
||||
retentionValue={retentionField.value}
|
||||
setRetentionValue={retentionField.setValue}
|
||||
hide={!!retentionField.hide}
|
||||
/>
|
||||
))}
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
const onOkHandler = async (): Promise<void> => {
|
||||
try {
|
||||
setPostApiLoading(true);
|
||||
const apiCalls = [];
|
||||
|
||||
if (
|
||||
!(
|
||||
currentTTLValues?.metrics_move_ttl_duration_hrs ===
|
||||
metricsS3RetentionPeriod &&
|
||||
currentTTLValues.metrics_ttl_duration_hrs === metricsTotalRetentionPeriod
|
||||
)
|
||||
) {
|
||||
apiCalls.push(() =>
|
||||
setRetentionApi({
|
||||
type: 'metrics',
|
||||
totalDuration: `${metricsTotalRetentionPeriod || -1}h`,
|
||||
coldStorage: s3Enabled ? 's3' : null,
|
||||
toColdDuration: `${metricsS3RetentionPeriod || -1}h`,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
apiCalls.push(() => Promise.resolve(null));
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
currentTTLValues?.traces_move_ttl_duration_hrs ===
|
||||
tracesS3RetentionPeriod &&
|
||||
currentTTLValues.traces_ttl_duration_hrs === tracesTotalRetentionPeriod
|
||||
)
|
||||
) {
|
||||
apiCalls.push(() =>
|
||||
setRetentionApi({
|
||||
type: 'traces',
|
||||
totalDuration: `${tracesTotalRetentionPeriod || -1}h`,
|
||||
coldStorage: s3Enabled ? 's3' : null,
|
||||
toColdDuration: `${tracesS3RetentionPeriod || -1}h`,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
apiCalls.push(() => Promise.resolve(null));
|
||||
}
|
||||
const apiCallSequence = ['metrics', 'traces'];
|
||||
const apiResponses = await Promise.all(apiCalls.map((api) => api()));
|
||||
|
||||
apiResponses.forEach((apiResponse, idx) => {
|
||||
const name = apiCallSequence[idx];
|
||||
if (apiResponse) {
|
||||
if (apiResponse.statusCode === 200) {
|
||||
notifications.success({
|
||||
message: 'Success!',
|
||||
placement: 'topRight',
|
||||
|
||||
description: t('settings.retention_success_message', { name }),
|
||||
});
|
||||
} else {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('settings.retention_error_message', { name }),
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
onModalToggleHandler();
|
||||
setPostApiLoading(false);
|
||||
} catch (error) {
|
||||
notifications.error({
|
||||
message: 'Error',
|
||||
description: t('settings.retention_failed_message'),
|
||||
placement: 'topRight',
|
||||
});
|
||||
}
|
||||
// Updates the currentTTL Values in order to avoid pushing the same values.
|
||||
setCurrentTTLValues({
|
||||
metrics_ttl_duration_hrs: metricsTotalRetentionPeriod || -1,
|
||||
metrics_move_ttl_duration_hrs: metricsS3RetentionPeriod || -1,
|
||||
traces_ttl_duration_hrs: tracesTotalRetentionPeriod || -1,
|
||||
traces_move_ttl_duration_hrs: tracesS3RetentionPeriod || -1,
|
||||
});
|
||||
|
||||
setModal(false);
|
||||
};
|
||||
|
||||
const [isDisabled, errorText] = useMemo((): [boolean, string] => {
|
||||
// Various methods to return dynamic error message text.
|
||||
const messages = {
|
||||
compareError: (name: string | number): string =>
|
||||
t('settings.retention_comparison_error', { name }),
|
||||
nullValueError: (name: string | number): string =>
|
||||
t('settings.retention_null_value_error', { name }),
|
||||
};
|
||||
|
||||
// Defaults to button not disabled and empty error message text.
|
||||
let isDisabled = false;
|
||||
let errorText = '';
|
||||
|
||||
if (s3Enabled) {
|
||||
if (
|
||||
(metricsTotalRetentionPeriod || metricsS3RetentionPeriod) &&
|
||||
Number(metricsTotalRetentionPeriod) <= Number(metricsS3RetentionPeriod)
|
||||
) {
|
||||
isDisabled = true;
|
||||
errorText = messages.compareError('metrics');
|
||||
} else if (
|
||||
(tracesTotalRetentionPeriod || tracesS3RetentionPeriod) &&
|
||||
Number(tracesTotalRetentionPeriod) <= Number(tracesS3RetentionPeriod)
|
||||
) {
|
||||
isDisabled = true;
|
||||
errorText = messages.compareError('traces');
|
||||
}
|
||||
}
|
||||
|
||||
if (!metricsTotalRetentionPeriod || !tracesTotalRetentionPeriod) {
|
||||
isDisabled = true;
|
||||
if (!metricsTotalRetentionPeriod && !tracesTotalRetentionPeriod) {
|
||||
errorText = messages.nullValueError('metrics and traces');
|
||||
} else if (!metricsTotalRetentionPeriod) {
|
||||
errorText = messages.nullValueError('metrics');
|
||||
} else if (!tracesTotalRetentionPeriod) {
|
||||
errorText = messages.nullValueError('traces');
|
||||
}
|
||||
}
|
||||
if (
|
||||
currentTTLValues?.metrics_ttl_duration_hrs === metricsTotalRetentionPeriod &&
|
||||
currentTTLValues.metrics_move_ttl_duration_hrs ===
|
||||
metricsS3RetentionPeriod &&
|
||||
currentTTLValues.traces_ttl_duration_hrs === tracesTotalRetentionPeriod &&
|
||||
currentTTLValues.traces_move_ttl_duration_hrs === tracesS3RetentionPeriod
|
||||
) {
|
||||
isDisabled = true;
|
||||
}
|
||||
return [isDisabled, errorText];
|
||||
}, [
|
||||
currentTTLValues,
|
||||
metricsS3RetentionPeriod,
|
||||
metricsTotalRetentionPeriod,
|
||||
s3Enabled,
|
||||
t,
|
||||
tracesS3RetentionPeriod,
|
||||
tracesTotalRetentionPeriod,
|
||||
]);
|
||||
|
||||
if (error) {
|
||||
return <Typography>{errorMessage}</Typography>;
|
||||
if (getRetentionPeriodApiResponse.isError || getDisksResponse.isError) {
|
||||
return (
|
||||
<Typography>
|
||||
{getRetentionPeriodApiResponse.data?.error ||
|
||||
getDisksResponse.data?.error ||
|
||||
t('something_went_wrong')}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
if (loading || currentTTLValues === undefined) {
|
||||
if (
|
||||
getRetentionPeriodApiResponse.isLoading ||
|
||||
getDisksResponse.isLoading ||
|
||||
!getDisksResponse.data?.payload ||
|
||||
!getRetentionPeriodApiResponse.data?.payload
|
||||
) {
|
||||
return <Spinner tip="Loading.." height="70vh" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}>
|
||||
{Element}
|
||||
<ErrorTextContainer>
|
||||
<TextToolTip
|
||||
{...{
|
||||
text: `More details on how to set retention period`,
|
||||
url: 'https://signoz.io/docs/userguide/retention-period/',
|
||||
}}
|
||||
/>
|
||||
{errorText && <ErrorText>{errorText}</ErrorText>}
|
||||
</ErrorTextContainer>
|
||||
|
||||
<Row justify="space-around">{renderConfig}</Row>
|
||||
|
||||
<Modal
|
||||
title={t('settings.retention_confirmation')}
|
||||
focusTriggerAfterClose
|
||||
forceRender
|
||||
destroyOnClose
|
||||
closable
|
||||
onCancel={onModalToggleHandler}
|
||||
onOk={onOkHandler}
|
||||
centered
|
||||
visible={modal}
|
||||
confirmLoading={postApiLoading}
|
||||
>
|
||||
<Typography>{t('settings.retention_confirmation_description')}</Typography>
|
||||
</Modal>
|
||||
|
||||
<ButtonContainer>
|
||||
<Button onClick={onClickSaveHandler} disabled={isDisabled} type="primary">
|
||||
Save
|
||||
</Button>
|
||||
</ButtonContainer>
|
||||
</Col>
|
||||
<GeneralSettingsContainer
|
||||
{...{
|
||||
getAvailableDiskPayload: getDisksResponse.data?.payload,
|
||||
ttlValuesPayload: getRetentionPeriodApiResponse.data?.payload,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,29 @@
|
||||
import getAll from 'api/alerts/getAll';
|
||||
import Spinner from 'components/Spinner';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import React from 'react';
|
||||
import { PayloadProps } from 'types/api/alerts/getAll';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import ListAlert from './ListAlert';
|
||||
|
||||
function ListAlertRules(): JSX.Element {
|
||||
const { loading, payload, error, errorMessage } = useFetch<
|
||||
PayloadProps,
|
||||
undefined
|
||||
>(getAll);
|
||||
const { t } = useTranslation('common');
|
||||
const { data, isError, isLoading } = useQuery('allAlerts', {
|
||||
queryFn: getAll,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return <div>{errorMessage}</div>;
|
||||
if (isError) {
|
||||
return <div>{data?.error || t('something_went_wrong')}</div>;
|
||||
}
|
||||
|
||||
if (loading || payload === undefined) {
|
||||
if (isLoading || !data?.payload) {
|
||||
return <Spinner height="75vh" tip="Loading Rules..." />;
|
||||
}
|
||||
|
||||
return (
|
||||
<ListAlert
|
||||
{...{
|
||||
allAlertRules: payload,
|
||||
allAlertRules: data.payload,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Select } from 'antd';
|
||||
import getTagValue from 'api/trace/getTagValue';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import React from 'react';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { PayloadProps, Props } from 'types/api/trace/getTagValue';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
import { TraceReducer } from 'types/reducer/trace';
|
||||
|
||||
@ -22,11 +21,17 @@ function TagValue(props: TagValueProps): JSX.Element {
|
||||
(state) => state.globalTime,
|
||||
);
|
||||
|
||||
const valueSuggestion = useFetch<PayloadProps, Props>(getTagValue, {
|
||||
end: globalReducer.maxTime,
|
||||
start: globalReducer.minTime,
|
||||
tagKey,
|
||||
});
|
||||
const { isLoading, data } = useQuery(
|
||||
['tagKey', globalReducer.minTime, globalReducer.maxTime, tagKey],
|
||||
{
|
||||
queryFn: () =>
|
||||
getTagValue({
|
||||
end: globalReducer.maxTime,
|
||||
start: globalReducer.minTime,
|
||||
tagKey,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<SelectComponent
|
||||
@ -44,10 +49,11 @@ function TagValue(props: TagValueProps): JSX.Element {
|
||||
]);
|
||||
}
|
||||
}}
|
||||
loading={valueSuggestion.loading || false}
|
||||
loading={isLoading || false}
|
||||
>
|
||||
{valueSuggestion.payload &&
|
||||
valueSuggestion.payload.map((suggestion) => (
|
||||
{data &&
|
||||
data.payload &&
|
||||
data.payload.map((suggestion) => (
|
||||
<Select.Option key={suggestion.tagValues} value={suggestion.tagValues}>
|
||||
{suggestion.tagValues}
|
||||
</Select.Option>
|
||||
|
@ -8,32 +8,33 @@ import {
|
||||
WebhookType,
|
||||
} from 'container/CreateAlertChannels/config';
|
||||
import EditAlertChannels from 'container/EditAlertChannels';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { PayloadProps, Props } from 'types/api/channels/get';
|
||||
|
||||
function ChannelsEdit(): JSX.Element {
|
||||
const { id } = useParams<Params>();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { errorMessage, payload, error, loading } = useFetch<
|
||||
PayloadProps,
|
||||
Props
|
||||
>(get, {
|
||||
id,
|
||||
const { isLoading, isError, data } = useQuery(['getChannel', id], {
|
||||
queryFn: () =>
|
||||
get({
|
||||
id,
|
||||
}),
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return <Typography>{errorMessage}</Typography>;
|
||||
if (isError) {
|
||||
return <Typography>{data?.error || t('something_went_wrong')}</Typography>;
|
||||
}
|
||||
|
||||
if (loading || payload === undefined) {
|
||||
if (isLoading || !data?.payload) {
|
||||
return <Spinner tip="Loading Channels..." />;
|
||||
}
|
||||
|
||||
const { data } = payload;
|
||||
const { data: ChannelData } = data.payload;
|
||||
|
||||
const value = JSON.parse(data);
|
||||
const value = JSON.parse(ChannelData);
|
||||
let type = '';
|
||||
let channel: SlackChannel & WebhookChannel = { name: '' };
|
||||
|
||||
@ -57,7 +58,7 @@ function ChannelsEdit(): JSX.Element {
|
||||
}
|
||||
type = WebhookType;
|
||||
}
|
||||
console.log('channel:', channel);
|
||||
|
||||
return (
|
||||
<EditAlertChannels
|
||||
{...{
|
||||
|
@ -1,30 +1,31 @@
|
||||
import get from 'api/alerts/get';
|
||||
import Spinner from 'components/Spinner';
|
||||
import EditRulesContainer from 'container/EditRules';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { PayloadProps, Props } from 'types/api/alerts/get';
|
||||
|
||||
function EditRules(): JSX.Element {
|
||||
const { ruleId } = useParams<EditRulesParam>();
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const { loading, error, payload, errorMessage } = useFetch<
|
||||
PayloadProps,
|
||||
Props
|
||||
>(get, {
|
||||
id: parseInt(ruleId, 10),
|
||||
const { isLoading, data, isError } = useQuery(['ruleId', ruleId], {
|
||||
queryFn: () =>
|
||||
get({
|
||||
id: parseInt(ruleId, 10),
|
||||
}),
|
||||
});
|
||||
|
||||
if (error) {
|
||||
return <div>{errorMessage}</div>;
|
||||
if (isError) {
|
||||
return <div>{data?.error || t('something_went_wrong')}</div>;
|
||||
}
|
||||
|
||||
if (loading || payload === undefined) {
|
||||
if (isLoading || !data?.payload) {
|
||||
return <Spinner tip="Loading Rules..." />;
|
||||
}
|
||||
|
||||
return <EditRulesContainer ruleId={ruleId} initialData={payload.data} />;
|
||||
return <EditRulesContainer ruleId={ruleId} initialData={data.payload.data} />;
|
||||
}
|
||||
|
||||
interface EditRulesParam {
|
||||
|
Loading…
x
Reference in New Issue
Block a user