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('month'); const [notifications, Element] = notification.useNotification(); const [modal, setModal] = useState(false); const [postApiLoading, setPostApiLoading] = useState(false); const [isDefaultMetrics, setIsDefaultMetrics] = useState(false); const [isDefaultTrace, setIsDefaultTrace] = useState(false); const [availableDisks, setAvailableDisks] = useState(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 ( {category.name} {category.retentionFields.map((retentionField) => ( ))} ); } return null; }); const onOkHandler = async (): Promise => { 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} can’t 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 {errorMessage}; } if (loading || currentTTLValues === undefined) { return ; } return ( {Element} {errorText ? ( {errorText} ) : ( )} {/* {renderConfig.map((category): JSX.Element | null => { if ( Array.isArray(category.retentionFields) && category.retentionFields.length > 0 ) { return ( {category.name} {category.retentionFields.map((retentionField) => ( ))} ); } return null; })} */} {renderConfig} This will change the amount of storage needed for saving metrics & traces. ); } export type SettingPeriod = 'hr' | 'day' | 'month'; export default GeneralSettings;