Skip to content

Commit 3411003

Browse files
Merge pull request #2030 from redpanda-data/front-end/dr/improvements
feat: shadow links UI improvements and bug fixes
2 parents 3a11886 + 54b50ef commit 3411003

16 files changed

+253
-87
lines changed

frontend/src/components/pages/shadowlinks/create/configuration/topics-step.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export const TopicsStep = () => {
6363
<Collapsible onOpenChange={setIsOpen} open={isOpen}>
6464
<Card className="gap-0" size="full">
6565
<CardHeader>
66-
<CardTitle>Topic mirroring</CardTitle>
66+
<CardTitle>Topic shadowing</CardTitle>
6767
<CardAction>
6868
<CollapsibleTrigger asChild>
6969
<Button className="w-fit p-0" data-testid="topics-toggle-button" size="sm" variant="ghost">
@@ -111,7 +111,7 @@ export const TopicsStep = () => {
111111
<TabsContent value="all">
112112
<Alert>
113113
<AlertDescription>
114-
All topics from the source cluster will be mirrored to the destination cluster.
114+
All topics from the source cluster will be shadowed to the destination cluster.
115115
</AlertDescription>
116116
</Alert>
117117
</TabsContent>

frontend/src/components/pages/shadowlinks/create/connection/bootstrap-servers.test.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,15 @@ describe('BootstrapServers', () => {
177177
const input1 = getBootstrapInput(1);
178178
fireEvent.change(input1, { target: { value: 'kafka2.example.com:9092' } });
179179

180-
const disabledTab = screen.getByTestId('tls-disabled-tab');
181-
fireEvent.click(disabledTab);
180+
const tlsToggle = screen.getByTestId('tls-toggle');
181+
182+
// TLS is enabled by default (initialValues.useTls = true), so clicking will disable it
183+
fireEvent.click(tlsToggle);
182184

183185
await waitFor(() => {
184186
expect(input0).toHaveValue('kafka1.example.com:9092');
185187
expect(input1).toHaveValue('kafka2.example.com:9092');
186-
expect(disabledTab).toHaveAttribute('aria-selected', 'true');
188+
expect(tlsToggle).not.toBeChecked();
187189
});
188190
});
189191
});

frontend/src/components/pages/shadowlinks/create/connection/scram-configuration.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,30 @@ const TestWrapper = ({ defaultValues = initialValues }: { defaultValues?: FormVa
4242

4343
describe('ScramConfiguration', () => {
4444
describe('SCRAM enabled state', () => {
45-
test('should show credentials form when Enabled is selected', () => {
45+
test('should show credentials form when switch is enabled', () => {
4646
const customValues: FormValues = {
4747
...initialValues,
4848
useScram: true,
4949
};
5050

5151
render(<TestWrapper defaultValues={customValues} />);
5252

53-
expect(screen.getByTestId('scram-enabled-tab')).toHaveAttribute('aria-selected', 'true');
53+
expect(screen.getByTestId('scram-toggle')).toBeChecked();
5454
expect(screen.getByTestId('scram-credentials-form')).toBeInTheDocument();
5555
expect(screen.getByTestId('scram-username-field')).toBeInTheDocument();
5656
expect(screen.getByTestId('scram-password-field')).toBeInTheDocument();
5757
expect(screen.getByTestId('scram-mechanism-field')).toBeInTheDocument();
5858
});
5959

60-
test('should hide credentials form when Disabled is selected', () => {
60+
test('should hide credentials form when switch is disabled', () => {
6161
const customValues: FormValues = {
6262
...initialValues,
6363
useScram: false,
6464
};
6565

6666
render(<TestWrapper defaultValues={customValues} />);
6767

68-
expect(screen.getByTestId('scram-disabled-tab')).toHaveAttribute('aria-selected', 'true');
68+
expect(screen.getByTestId('scram-toggle')).not.toBeChecked();
6969
expect(screen.queryByTestId('scram-credentials-form')).not.toBeInTheDocument();
7070
expect(screen.queryByTestId('scram-username-field')).not.toBeInTheDocument();
7171
expect(screen.queryByTestId('scram-password-field')).not.toBeInTheDocument();

frontend/src/components/pages/shadowlinks/create/connection/scram-configuration.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,29 @@ import {
1919
SelectTrigger,
2020
SelectValue,
2121
} from 'components/redpanda-ui/components/select';
22+
import { Switch } from 'components/redpanda-ui/components/switch';
2223
import { ScramMechanism } from 'protogen/redpanda/core/admin/v2/shadow_link_pb';
24+
import { useEffect } from 'react';
2325
import { useFormContext, useWatch } from 'react-hook-form';
2426

25-
import { Tabs, TabsList, TabsTrigger } from '../../../../redpanda-ui/components/tabs';
2627
import type { FormValues } from '../model';
2728

2829
export const ScramConfiguration = () => {
29-
const { control } = useFormContext<FormValues>();
30+
const { control, setValue } = useFormContext<FormValues>();
3031
const useScram = useWatch({ control, name: 'useScram' });
3132

33+
useEffect(() => {
34+
if (useScram) {
35+
setValue('scramCredentials', {
36+
username: '',
37+
password: '',
38+
mechanism: ScramMechanism.SCRAM_SHA_256,
39+
});
40+
} else {
41+
setValue('scramCredentials', undefined);
42+
}
43+
}, [useScram, setValue]);
44+
3245
return (
3346
<Card size="full">
3447
<CardHeader>
@@ -38,21 +51,10 @@ export const ScramConfiguration = () => {
3851
control={control}
3952
name="useScram"
4053
render={({ field }) => (
41-
<FormItem className="flex flex-col">
42-
<div>
43-
<FormLabel>Use SCRAM authentication</FormLabel>
44-
</div>
54+
<FormItem className="flex flex-row items-center gap-3">
55+
<FormLabel>Use SCRAM authentication</FormLabel>
4556
<FormControl>
46-
<Tabs onValueChange={(value) => field.onChange(value === 'true')} value={String(field.value)}>
47-
<TabsList variant="default">
48-
<TabsTrigger data-testid="scram-enabled-tab" value="true">
49-
Enabled
50-
</TabsTrigger>
51-
<TabsTrigger data-testid="scram-disabled-tab" value="false">
52-
Disabled
53-
</TabsTrigger>
54-
</TabsList>
55-
</Tabs>
57+
<Switch checked={field.value} onCheckedChange={field.onChange} testId="scram-toggle" />
5658
</FormControl>
5759
</FormItem>
5860
)}

frontend/src/components/pages/shadowlinks/create/connection/tls-configuration.tsx

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*/
1111

1212
import { FormControl, FormField, FormItem, FormLabel } from 'components/redpanda-ui/components/form';
13-
import { Tabs, TabsList, TabsTrigger } from 'components/redpanda-ui/components/tabs';
13+
import { Switch } from 'components/redpanda-ui/components/switch';
1414
import { useFormContext } from 'react-hook-form';
1515

1616
import type { FormValues } from '../model';
@@ -23,25 +23,10 @@ export const TlsConfiguration = () => {
2323
control={control}
2424
name="useTls"
2525
render={({ field }) => (
26-
<FormItem className="flex flex-col">
27-
<div>
28-
<FormLabel>Enable TLS</FormLabel>
29-
</div>
26+
<FormItem className="flex flex-row items-center gap-3">
27+
<FormLabel>Enable TLS</FormLabel>
3028
<FormControl>
31-
<Tabs
32-
data-testid="tls-toggle"
33-
onValueChange={(value) => field.onChange(value === 'true')}
34-
value={String(field.value)}
35-
>
36-
<TabsList variant="default">
37-
<TabsTrigger data-testid="tls-enabled-tab" value="true">
38-
Enabled
39-
</TabsTrigger>
40-
<TabsTrigger data-testid="tls-disabled-tab" value="false">
41-
Disabled
42-
</TabsTrigger>
43-
</TabsList>
44-
</Tabs>
29+
<Switch checked={field.value} onCheckedChange={field.onChange} testId="tls-toggle" />
4530
</FormControl>
4631
</FormItem>
4732
)}

frontend/src/components/pages/shadowlinks/details/config/configuration-mirroring.tsx renamed to frontend/src/components/pages/shadowlinks/details/config/configuration-shadowing.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
getResourceTypeLabel,
2727
} from '../../shadowlink-helpers';
2828

29-
export interface ConfigurationMirroringProps {
29+
export interface ConfigurationShadowingProps {
3030
shadowLink: ShadowLink;
3131
}
3232

@@ -166,7 +166,7 @@ const ACLFilterSection = ({ filters }: { filters: ACLFilter[] }) => {
166166
);
167167
};
168168

169-
export const ConfigurationMirroring = ({ shadowLink }: ConfigurationMirroringProps) => {
169+
export const ConfigurationShadowing = ({ shadowLink }: ConfigurationShadowingProps) => {
170170
const topicSyncOptions = shadowLink.configurations?.topicMetadataSyncOptions;
171171
const consumerSyncOptions = shadowLink.configurations?.consumerOffsetSyncOptions;
172172
const securitySyncOptions = shadowLink.configurations?.securitySyncOptions;

frontend/src/components/pages/shadowlinks/details/config/configuration-topic-replication.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ export const ConfigurationTopicReplication = ({ shadowLink }: ConfigurationTopic
9797
return (
9898
<Card size="full" testId="topic-replication-placeholder-card">
9999
<CardContent className="py-8 text-center">
100-
<Text className="text-muted-foreground">No topic properties configured for replication</Text>
100+
<Text className="text-muted-foreground">No topic properties configured for shadowing</Text>
101101
</CardContent>
102102
</Card>
103103
);
@@ -106,7 +106,7 @@ export const ConfigurationTopicReplication = ({ shadowLink }: ConfigurationTopic
106106
return (
107107
<div className="flex flex-col gap-6">
108108
<Heading level={2} testId="shadowing-title">
109-
Topic config replication
109+
Topic config shadow
110110
</Heading>
111111
{sortedCategories.map((category) => {
112112
const properties = categorizedProperties[category];

frontend/src/components/pages/shadowlinks/details/config/shadow-link-configuration.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import { Tabs, TabsContent, TabsContents, TabsList, TabsTrigger } from 'components/redpanda-ui/components/tabs';
1515
import type { ShadowLink } from 'protogen/redpanda/api/console/v1alpha1/shadowlink_pb';
1616

17-
import { ConfigurationMirroring } from './configuration-mirroring';
17+
import { ConfigurationShadowing } from './configuration-shadowing';
1818
import { ConfigurationSource } from './configuration-source';
1919
import { ConfigurationTopicReplication } from './configuration-topic-replication';
2020

@@ -31,7 +31,7 @@ export const ShadowLinkConfiguration = ({ shadowLink }: ShadowLinkConfigurationP
3131
<TabsTrigger testId="source-tab" value="source" variant="underline">
3232
Source
3333
</TabsTrigger>
34-
<TabsTrigger testId="mirroring-tab" value="mirroring" variant="underline">
34+
<TabsTrigger testId="shadowing-tab" value="shadowing" variant="underline">
3535
Shadowing
3636
</TabsTrigger>
3737
<TabsTrigger testId="topic-config-replication-tab" value="topic-config-replication" variant="underline">
@@ -43,7 +43,7 @@ export const ShadowLinkConfiguration = ({ shadowLink }: ShadowLinkConfigurationP
4343
<TabsContent testId="all-content" value="all">
4444
<div className="flex flex-col gap-6">
4545
<ConfigurationSource shadowLink={shadowLink} />
46-
<ConfigurationMirroring shadowLink={shadowLink} />
46+
<ConfigurationShadowing shadowLink={shadowLink} />
4747
<ConfigurationTopicReplication shadowLink={shadowLink} />
4848
</div>
4949
</TabsContent>
@@ -52,8 +52,8 @@ export const ShadowLinkConfiguration = ({ shadowLink }: ShadowLinkConfigurationP
5252
<ConfigurationSource shadowLink={shadowLink} />
5353
</TabsContent>
5454

55-
<TabsContent testId="mirroring-content" value="mirroring">
56-
<ConfigurationMirroring shadowLink={shadowLink} />
55+
<TabsContent testId="shadowing-content" value="shadowing">
56+
<ConfigurationShadowing shadowLink={shadowLink} />
5757
</TabsContent>
5858

5959
<TabsContent testId="topic-config-replication-content" value="topic-config-replication">

frontend/src/components/pages/shadowlinks/details/shadow-link-diagram.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const SourceClusterNode = ({ data }: { data: { brokers: string[] } }) => (
2626
<ItemTitle>Source cluster</ItemTitle>
2727
<div className="flex flex-col gap-1 text-muted-foreground text-xs">
2828
{data.brokers.map((broker) => (
29-
<Text key={broker} variant={'muted'}>
29+
<Text className="max-w-[240px] truncate" key={broker} variant={'muted'}>
3030
{broker}
3131
</Text>
3232
))}
@@ -105,6 +105,7 @@ export const ShadowLinkDiagram = ({ shadowLink }: ShadowLinkDiagramProps) => {
105105
nodeTypes={nodeTypes}
106106
panOnDrag={false}
107107
preventScrolling={false}
108+
proOptions={{ hideAttribution: true }}
108109
zoomOnPinch={false}
109110
zoomOnScroll={false}
110111
>

frontend/src/components/pages/shadowlinks/edit/shadowlink-edit-page.test.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ const enableTLS = async (
172172
user: ReturnType<typeof userEvent.setup>,
173173
scr: typeof import('@testing-library/react').screen
174174
) => {
175-
const tlsEnabledTab = scr.getByTestId('tls-enabled-tab');
176-
await user.click(tlsEnabledTab);
175+
const tlsToggle = scr.getByTestId('tls-toggle');
176+
await user.click(tlsToggle);
177177
};
178178

179179
const updateMetadataMaxAge = async (
@@ -337,8 +337,8 @@ const enableMTLS = async (
337337
user: ReturnType<typeof userEvent.setup>,
338338
scr: typeof import('@testing-library/react').screen
339339
) => {
340-
const mtlsEnabledTab = scr.getByTestId('mtls-enabled-tab');
341-
await user.click(mtlsEnabledTab);
340+
const mtlsToggle = scr.getByTestId('mtls-toggle');
341+
await user.click(mtlsToggle);
342342
};
343343

344344
const uploadCACertificate = async (

0 commit comments

Comments
 (0)