2022-04-04 19:38:23 +05:30

353 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Button, Col, Modal, notification, Row, 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 convertIntoHr from 'lib/convertIntoHr';
import getSettingsPeroid from 'lib/getSettingsPeroid';
import { find } from 'lodash-es';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { IDiskType } from 'types/api/disks/getDisks';
import { PayloadProps } from 'types/api/settings/getRetention';
import Retention from './Retention';
import {
ButtonContainer,
ErrorText,
ErrorTextContainer,
ToolTipContainer,
} from './styles';
function GeneralSettings(): JSX.Element {
const [
selectedMetricsPeroid,
setSelectedMetricsPeroid,
] = useState<SettingPeriod>('month');
const [notifications, Element] = notification.useNotification();
const [modal, setModal] = useState<boolean>(false);
const [postApiLoading, setPostApiLoading] = useState<boolean>(false);
const [isDefaultMetrics, setIsDefaultMetrics] = useState<boolean>(false);
const [isDefaultTrace, setIsDefaultTrace] = useState<boolean>(false);
const [availableDisks, setAvailableDisks] = useState<IDiskType | null>(null);
useEffect(() => {
getDisks().then((response) => setAvailableDisks(response.payload));
}, []);
const { payload: currentTTLValues, loading, error, errorMessage } = useFetch<
PayloadProps,
undefined
>(getRetentionPeriodApi, undefined);
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);
setTracesTotalRetentionPeriod(currentTTLValues.traces_ttl_duration_hrs);
setTracesS3RetentionPeriod(currentTTLValues.traces_move_ttl_duration_hrs);
console.log({ currentTTLValues });
}
}, [currentTTLValues]);
const onModalToggleHandler = (): void => {
setModal((modal) => !modal);
};
const onClickSaveHandler = useCallback(() => {
onModalToggleHandler();
}, []);
const checkMetricTraceDefault = (trace: number, metric: number): void => {
if (metric === -1) {
setIsDefaultMetrics(true);
} else {
setIsDefaultMetrics(false);
}
if (trace === -1) {
setIsDefaultTrace(true);
} else {
setIsDefaultTrace(false);
}
};
// const retentionRenderConfig = () => { };
const s3Enabled = useMemo(
() => !!find(availableDisks, (disks: IDiskType) => disks?.type === 's3'),
[availableDisks],
);
const renderConfig = [
{
name: 'Metrics',
retentionFields: [
{
name: 'Total Retention Period',
value: metricsTotalRetentionPeriod,
setValue: setMetricsTotalRetentionPeriod,
},
{
name: `Move to S3\n(should be lower than total retention period)`,
value: metricsS3RetentionPeriod,
setValue: setMetricsS3RetentionPeriod,
hide: !s3Enabled,
},
],
},
{
name: 'Traces',
retentionFields: [
{
name: 'Total Retention Period',
value: tracesTotalRetentionPeriod,
setValue: setTracesTotalRetentionPeriod,
},
{
name: `Move to S3\n(should be lower than total retention period)`,
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;
});
const onOkHandler = async (): Promise<void> => {
try {
setPostApiLoading(true);
// const retentionTraceValue =
// retentionPeroidTrace === '0' && (payload?.traces_ttl_duration_hrs || 0) < 0
// ? payload?.traces_ttl_duration_hrs || 0
// : parseInt(retentionPeroidTrace, 10);
// const retentionMetricsValue =
// retentionPeroidMetrics === '0' &&
// (payload?.metrics_ttl_duration_hrs || 0) < 0
// ? payload?.metrics_ttl_duration_hrs || 0
// : parseInt(retentionPeroidMetrics, 10);
const [metricsTTLApiResponse, tracesTTLApiResponse] = await Promise.all([
setRetentionApi({
type: 'metrics',
totalDuration: `${metricsTotalRetentionPeriod || -1}h`,
coldStorage: s3Enabled ? 's3' : null,
toColdDuration: `${metricsS3RetentionPeriod || -1}h`,
}),
setRetentionApi({
type: 'traces',
totalDuration: `${tracesTotalRetentionPeriod || -1}h`,
coldStorage: s3Enabled ? 's3' : null,
toColdDuration: `${tracesS3RetentionPeriod || -1}h`,
}),
]);
[
{
apiResponse: metricsTTLApiResponse,
name: 'metrics',
},
{
apiResponse: tracesTTLApiResponse,
name: 'traces',
},
].forEach(({ apiResponse, name }) => {
if (apiResponse.statusCode === 200) {
notifications.success({
message: 'Success!',
placement: 'topRight',
description: `Congrats. The retention periods for ${name} has been updated successfully.`,
});
// checkMetricTraceDefault(retentionTraceValue, retentionMetricsValue);
onModalToggleHandler();
} else {
notifications.error({
message: 'Error',
description: `There was an issue in changing the retention period for ${name}. Please try again or reach out to support@signoz.io`,
placement: 'topRight',
});
}
});
setPostApiLoading(false);
} catch (error) {
notifications.error({
message: 'Error',
description:
'There was an issue in changing the retention period. Please try again or reach out to support@signoz.io',
placement: 'topRight',
});
}
setModal(false);
};
const [isDisabled, errorText] = useMemo(() => {
// Various methods to return dynamic error message text.
const messages = {
compareError: (value: string | number): string =>
`Total retention period for ${value} cant be lower than period after which data is moved to s3`,
nullValueError: (value: string | number): string =>
`Retention Peroid for ${value} is not set yet. Please set by choosing below`,
};
// 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');
}
}
return [isDisabled, errorText];
}, [
metricsS3RetentionPeriod,
metricsTotalRetentionPeriod,
s3Enabled,
tracesS3RetentionPeriod,
tracesTotalRetentionPeriod,
]);
if (error) {
return <Typography>{errorMessage}</Typography>;
}
if (loading || currentTTLValues === undefined) {
return <Spinner tip="Loading.." height="70vh" />;
}
return (
<Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}>
{Element}
{errorText ? (
<ErrorTextContainer>
<ErrorText>{errorText}</ErrorText>
<TextToolTip
{...{
text: `More details on how to set retention period`,
url: 'https://signoz.io/docs/userguide/retention-period/',
}}
/>
</ErrorTextContainer>
) : (
<ToolTipContainer>
<TextToolTip
{...{
text: `More details on how to set retention period`,
url: 'https://signoz.io/docs/userguide/retention-period/',
}}
/>
</ToolTipContainer>
)}
<Row justify="space-around" style={{ gap: '4%' }}>
{/* {renderConfig.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;
})} */}
{renderConfig}
</Row>
<Modal
title="Are you sure you want to change the retention period?"
focusTriggerAfterClose
forceRender
destroyOnClose
closable
onCancel={onModalToggleHandler}
onOk={onOkHandler}
centered
visible={modal}
confirmLoading={postApiLoading}
>
<Typography>
This will change the amount of storage needed for saving metrics & traces.
</Typography>
</Modal>
<ButtonContainer>
<Button onClick={onClickSaveHandler} disabled={isDisabled} type="primary">
Save
</Button>
</ButtonContainer>
</Col>
);
}
export type SettingPeriod = 'hr' | 'day' | 'month';
export default GeneralSettings;