import React from 'react'; import {CloudSlash} from '@gravity-ui/icons'; import {Flex, HelpMark, Icon, Label, Progress, Text} from '@gravity-ui/uikit'; import {cn} from '../../../../../utils/cn'; import {formatNumber} from '../../../../../utils/dataFormatters/dataFormatters'; import {LegendItems, SegmentedProgressBar} from './TenantStorageSegments'; import type { TenantStorageSegmentOpenChange, TenantStorageSegmentOpenSource, } from './TenantStorageSegments'; import {formatSummaryPercent} from './displayFormatters'; import i18n from './i18n'; import type { TenantStorageSegment, TenantStorageSegmentKey, TenantStorageSummary, TenantStorageSystemDetail, } from './utils'; import './TenantStorageSummaryCard.scss'; const b = cn('ydb-tenant-storage-summary-card'); export interface SummaryMetricProps { label: string; note?: string; notePlacement?: 'label' | 'value'; noteTitle?: string; noData?: boolean; value: string; emphasize?: boolean; hideDivider?: boolean; } interface SummaryCardRowBaseProps { summary: TenantStorageSummary; metrics: SummaryMetricProps[]; displayNoLimit?: 'empty' | 'filled'; segments?: TenantStorageSegment[]; formatLegendValue?: (value: number) => string; formatSystemDetailValue?: (value: number) => string; formatTooltipValue?: (value: number) => string; systemDetails?: TenantStorageSystemDetail[]; tooltipTotalLabel: string; } interface SummaryCardProps { title: string; description: string; descriptionHelpText?: string; position?: 'first' | 'last'; qa?: string; } type SummaryCardPropsWithRow = SummaryCardProps & SummaryCardRowBaseProps; interface ActiveStorageSegment { key: TenantStorageSegmentKey; source: TenantStorageSegmentOpenSource; } export interface GroupedSummaryCardRow extends SummaryCardRowBaseProps { id: string; mediaLabel?: string; } interface GroupedSummaryCardProps extends SummaryCardProps { rows: GroupedSummaryCardRow[]; } function SummaryMetricNote({note, noteTitle}: Pick) { if (!note && !noteTitle) { return null; } const content = noteTitle ? (
{noteTitle} {note ? {note} : null}
) : ( note ); return {content}; } function NoDataLabel({label}: {label?: string}) { const content = label ? `${label}: ${i18n('value_no-data')}` : i18n('value_no-data'); return ( ); } function SummaryMetric({ label, note, notePlacement = 'label', noteTitle, noData, value, emphasize, hideDivider, }: SummaryMetricProps) { const noteElement = ; return (
{noData ? ( ) : ( {value} )} {notePlacement === 'value' ? noteElement : null} {label} {notePlacement === 'label' ? noteElement : null}
); } function GroupedSummaryMetric({ label, note, notePlacement = 'label', noteTitle, noData, value, emphasize, hideDivider, }: SummaryMetricProps) { const noteElement = ; if (emphasize) { return (
{noData ? ( ) : ( )} {noteElement}
); } return (
{label} {notePlacement === 'label' ? noteElement : null} {noData ? ( ) : ( {value} )} {notePlacement === 'value' ? noteElement : null}
); } function SummaryCardCopy({ description, descriptionHelpText, title, }: { description: string; descriptionHelpText?: string; title: string; }) { return (
{title} {description} {descriptionHelpText ? ( {descriptionHelpText} ) : null}
); } function SummaryCardRow({ displayNoLimit, formatLegendValue, formatSystemDetailValue, formatTooltipValue, header, grouped, metrics, segments, summary, systemDetails, tooltipTotalLabel, }: SummaryCardRowBaseProps & {grouped?: boolean; header: React.ReactNode}) { const total = summary.quota ?? summary.total; const activeSegments = (segments ?? []).filter((s) => s.value > 0); const hasSegments = activeSegments.length > 0; const [activeSegment, setActiveSegment] = React.useState(); const activeSegmentKey = activeSegment?.key; const handleSegmentOpenChange = React.useCallback( (segmentKey, open, source) => { setActiveSegment((currentSegment) => { if (open) { return {key: segmentKey, source}; } return currentSegment?.key === segmentKey && currentSegment.source === source ? undefined : currentSegment; }); }, [], ); let percent = 0; if (total) { percent = summary.usedPercent; } else if (displayNoLimit === 'filled') { percent = 100; } return (
{header}
{metrics.map((metric) => grouped ? ( ) : ( ), )}
{hasSegments ? ( ) : ( )}
{hasSegments && formatLegendValue ? ( ) : (
)} {!total && displayNoLimit === 'filled' ? i18n('value_no-limit') : formatSummaryPercent(summary.usedPercent)}
); } export function SummaryCard({ title, description, descriptionHelpText, position, qa, ...rowProps }: SummaryCardPropsWithRow) { return (
} />
); } export function GroupedSummaryCard({ title, description, descriptionHelpText, position, qa, rows, }: GroupedSummaryCardProps) { return (
{rows.map(({id, mediaLabel, ...rowProps}) => ( {mediaLabel} } /> ))}
); }