Skip to content

Commit 20a390a

Browse files
committed
fix(storage): clarify legacy replication status
1 parent 5a83bf7 commit 20a390a

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

‎src/components/VDiskStatus/i18n/en.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"value_waiting-for-token": "Waiting for token",
1717
"value_phantoms-only": "Phantoms only",
1818
"label_not-replicated": "Not replicated",
19+
"value_no-detailed-status": "No detailed status",
1920
"context_state-ok": "The VDisk is operating normally",
2021
"context_state-initial": "The VDisk is starting",
2122
"context_state-sync-guid-recovery": "The VDisk is synchronizing with other VDisks of the group",

‎src/components/VDiskStatus/statuses.test.ts‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import {ArrowsRotateLeft, ArrowsRotateLeftSlash} from '@gravity-ui/icons';
2+
13
import type {EVDiskDetailedReplicationStatus} from '../../types/api/vdisk';
24
import {EVDiskState} from '../../types/api/vdisk';
35

@@ -31,8 +33,39 @@ describe('VDisk replication label', () => {
3133
});
3234

3335
test('uses the boolean fallback only when the detailed status is absent', () => {
34-
expect(getVDiskReplicationLabel({Replicated: false})?.value).toBe('Not replicated');
36+
expect(getVDiskReplicationLabel({Replicated: false})).toMatchObject({
37+
value: 'Not replicated',
38+
theme: 'normal',
39+
icon: ArrowsRotateLeftSlash,
40+
});
3541
expect(getVDiskReplicationLabel({Replicated: true})?.value).toBe('Replicated');
3642
expect(getVDiskReplicationLabel({})).toBeUndefined();
3743
});
44+
45+
test.each([
46+
{ReplicationProgress: 0},
47+
{ReplicationProgress: 0.77},
48+
{ReplicationProgress: 1},
49+
{ReplicationSecondsRemaining: 0},
50+
{ReplicationSecondsRemaining: 125},
51+
])('shows No detailed status with available replication metrics %p', (metrics) => {
52+
expect(getVDiskReplicationLabel({Replicated: false, ...metrics})).toMatchObject({
53+
title: 'Replication',
54+
value: 'No detailed status',
55+
theme: 'info',
56+
icon: ArrowsRotateLeft,
57+
});
58+
});
59+
60+
test.each([
61+
{ReplicationProgress: -0.1},
62+
{ReplicationProgress: 1.1},
63+
{ReplicationProgress: NaN},
64+
{ReplicationSecondsRemaining: -1},
65+
{ReplicationSecondsRemaining: Infinity},
66+
])('keeps Not replicated when replication metrics are invalid %p', (metrics) => {
67+
expect(getVDiskReplicationLabel({Replicated: false, ...metrics})?.value).toBe(
68+
'Not replicated',
69+
);
70+
});
3871
});

‎src/components/VDiskStatus/statuses.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '../../utils/disks/constants';
1717
import {calculateStateIcon} from '../../utils/disks/iconCalculators';
1818
import type {PreparedVDisk} from '../../utils/disks/types';
19+
import {parseOptionalNonNegativeNumber} from '../../utils/utils';
1920
import type {DiskStatusLabelData} from '../DiskStatus/DiskStatus';
2021

2122
import {vDiskStatusKeyset as i18n} from './i18n';
@@ -105,6 +106,17 @@ export function getVDiskReplicationLabel(data: PreparedVDisk): DiskStatusLabelDa
105106
return replicatedLabel();
106107
}
107108
if (data.Replicated === false) {
109+
const progress = parseOptionalNonNegativeNumber(data.ReplicationProgress);
110+
const seconds = parseOptionalNonNegativeNumber(data.ReplicationSecondsRemaining);
111+
if ((progress !== undefined && progress <= 1) || seconds !== undefined) {
112+
return {
113+
title: i18n('label_replication'),
114+
value: i18n('value_no-detailed-status'),
115+
theme: 'info',
116+
icon: ArrowsRotateLeft,
117+
tooltip: i18n('context_not-replicated'),
118+
};
119+
}
108120
return {
109121
value: i18n('label_not-replicated'),
110122
theme: 'normal',

0 commit comments

Comments
 (0)