import React from 'react'; import type {SelectOption} from '@gravity-ui/uikit'; import {SegmentedRadioGroup, Select, TextInput} from '@gravity-ui/uikit'; import {Controller, useFormContext, useWatch} from 'react-hook-form'; import {cn} from '../../../../utils/cn'; import {FormFieldError, FormRow, FormSection} from '../components/layout'; import i18n from '../i18n'; import type {FormValues, OriginalTableInfo} from '../types'; import { acceptIntegerInput, epochModeOptions, formatOptionalIntegerInput, getAvailableTtlColumns, isValidTtlNumType, lifetimeUnitOptions, parseOptionalIntegerInput, ttlStatusOptions, } from '../utils'; const b = cn('ydb-table-form-dialog'); function formatEpochModeValue(value: string) { const normalized = value .replace(/^UNIT_/, '') .toLowerCase() .replace(/_/g, ' '); return normalized ? normalized[0].toUpperCase() + normalized.slice(1) : value; } interface TTLSectionProps { originalInfo?: OriginalTableInfo; } export function TTLSection({originalInfo}: TTLSectionProps) { const {control, setValue, formState} = useFormContext(); const status = useWatch({control, name: 'settings.ttl.status'}); const column = useWatch({control, name: 'settings.ttl.column'}); const columnWithEpochMode = useWatch({control, name: 'settings.ttl.columnWithEpochMode'}); const formColumns = useWatch({control, name: 'columns'}); const deletedColumns = useWatch({control, name: 'deletedColumns'}); const enabled = status === 'enabled'; const isEpochMode = Boolean(columnWithEpochMode); const ttlColumns = React.useMemo(() => { return getAvailableTtlColumns(originalInfo?.columns, formColumns, deletedColumns); }, [originalInfo, formColumns, deletedColumns]); const columnOptions = React.useMemo( () => ttlColumns.length === 0 ? [ { value: '', content: i18n('label_ttl-warning'), disabled: true, }, ] : ttlColumns.map(({name}) => ({value: name, content: name})), [ttlColumns], ); const renderEpochModeSelectedOption = React.useCallback( (option: SelectOption) => ( {option.content ?? formatEpochModeValue(option.value)} ), [], ); React.useEffect(() => { if (!enabled || !column) { return; } const matchedType = ttlColumns.find(({name}) => name === column)?.type; if (!matchedType) { setValue('settings.ttl.columnWithEpochMode', false, {shouldValidate: false}); setValue('settings.ttl.epochMode', undefined, {shouldValidate: false}); return; } const withEpochMode = isValidTtlNumType(matchedType); setValue('settings.ttl.columnWithEpochMode', withEpochMode, {shouldValidate: false}); if (!withEpochMode) { setValue('settings.ttl.epochMode', undefined, {shouldValidate: false}); } }, [enabled, column, ttlColumns, setValue]); const columnError = formState.errors.settings?.ttl?.column?.message; const epochError = formState.errors.settings?.ttl?.epochMode?.message; const lifetimeError = formState.errors.settings?.ttl?.lifetime?.message; return ( ( field.onChange(value)} > {ttlStatusOptions.map((option) => ( {option.content} ))} )} /> {enabled ? ( (
field.onChange(value)} width="max" validationState={epochError ? 'invalid' : undefined} renderSelectedOption={renderEpochModeSelectedOption} />
)} />
) : null}
( { if (!acceptIntegerInput(value)) { return; } field.onChange(parseOptionalIntegerInput(value)); }} validationState={lifetimeError ? 'invalid' : undefined} errorMessage={lifetimeError} /> )} /> (