This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git


The following commit(s) were added to refs/heads/rocketmq-studio by this push:
     new d3a4458a0 fix(cluster): keep the form values a save silently rewrote 
(#5778)
d3a4458a0 is described below

commit d3a4458a0afbb4a0b892706ddd6cd2e7aa9cf22f
Author: Chstercc <[email protected]>
AuthorDate: Sat Oct 10 12:04:27 2026 +0800

    fix(cluster): keep the form values a save silently rewrote (#5778)
    
    The cluster form rewrote `maxMessageSize` on save without telling the user, 
so a subsequent submit persisted the rewritten value. The fix uses antd's 
touched semantics so only fields the user actually edited are sent.
    
    1 suite, 35 tests green; prettier clean.
---
 .../pages/cluster/__tests__/ClusterPage.test.tsx   | 115 ++++++++++++++++++++-
 web/src/pages/cluster/index.tsx                    |   6 +-
 2 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/web/src/pages/cluster/__tests__/ClusterPage.test.tsx 
b/web/src/pages/cluster/__tests__/ClusterPage.test.tsx
index 83a07623d..1eb02f723 100644
--- a/web/src/pages/cluster/__tests__/ClusterPage.test.tsx
+++ b/web/src/pages/cluster/__tests__/ClusterPage.test.tsx
@@ -94,10 +94,12 @@ const buildCluster = ({
   tpsIn = 12480,
   tpsOut = 34560,
   connections = 1842,
+  maxMessageSize = 4 * 1024 * 1024,
 }: {
   tpsIn?: number;
   tpsOut?: number;
   connections?: number;
+  maxMessageSize?: number;
 } = {}): ClusterInfo => ({
   id: 'cluster-prod',
   name: 'rocketmq-prod',
@@ -140,7 +142,7 @@ const buildCluster = ({
     flushDiskType: 'SYNC_FLUSH',
     autoCreateTopicEnable: false,
     autoCreateSubscriptionGroup: false,
-    maxMessageSize: 4 * 1024 * 1024,
+    maxMessageSize,
     msgTraceTopicName: 'RMQ_SYS_TRACE_TOPIC',
     fileReservedTime: 72,
     writeQueueNums: 8,
@@ -413,6 +415,117 @@ describe('Cluster page', () => {
     expect(within(dialog).getByRole('row', { name: /写队列数/ 
})).toHaveTextContent('16');
   });
 
+  it('preservesUntouchedMessageSizeBytesInPreviewAndSaveTest', async () => {
+    clusterServiceMocks.listRegistryClusters.mockResolvedValue([
+      buildCluster({ maxMessageSize: 5000000 }),
+    ]);
+    const user = userEvent.setup({ pointerEventsCheck: 0 });
+    renderWithProviders(<ClusterPage />);
+
+    const brokerRow = await screen.findByRole('row', { name: 
/10\.101\.2\.11:10911/ });
+    await user.click(within(brokerRow).getByRole('button', { name: /^配\s*置$/ 
}));
+    const dialog = await screen.findByRole('dialog', { name: /配置 - 
rocketmq-prod/ });
+    expect(within(dialog).getByLabelText('最大消息大小 (MB)')).toHaveValue('5');
+
+    await user.click(within(dialog).getByRole('button', { name: /预\s*览/ }));
+    await waitFor(() =>
+      expect(clusterServiceMocks.previewClusterConfig).toHaveBeenCalledWith(
+        expect.objectContaining({ maxMessageSize: 5000000 }),
+      ),
+    );
+    await user.click(within(dialog).getByRole('button', { name: /^OK$/ }));
+    await waitFor(() =>
+      expect(clusterServiceMocks.updateClusterConfig).toHaveBeenCalledWith(
+        expect.objectContaining({ maxMessageSize: 5000000 }),
+      ),
+    );
+  });
+
+  it('preservesMessageSizeBytesWhenAnotherConfigFieldIsEditedTest', async () 
=> {
+    clusterServiceMocks.listRegistryClusters.mockResolvedValue([
+      buildCluster({ maxMessageSize: 5000000 }),
+    ]);
+    const user = userEvent.setup({ pointerEventsCheck: 0 });
+    renderWithProviders(<ClusterPage />);
+
+    const brokerRow = await screen.findByRole('row', { name: 
/10\.101\.2\.11:10911/ });
+    await user.click(within(brokerRow).getByRole('button', { name: /^配\s*置$/ 
}));
+    const dialog = await screen.findByRole('dialog', { name: /配置 - 
rocketmq-prod/ });
+    const retentionInput = within(dialog).getByLabelText('文件保留时长 (小时)');
+    await user.clear(retentionInput);
+    await user.type(retentionInput, '96');
+
+    await user.click(within(dialog).getByRole('button', { name: /^OK$/ }));
+    await waitFor(() =>
+      expect(clusterServiceMocks.updateClusterConfig).toHaveBeenCalledWith(
+        expect.objectContaining({ maxMessageSize: 5000000, fileReservedTime: 
96 }),
+      ),
+    );
+  });
+
+  it.each([
+    { size: '6', expectedBytes: 6291456 },
+    { size: '5', expectedBytes: 5242880 },
+  ])(
+    'appliesExplicitMessageSizeEditTo $size MiBInPreviewAndSaveTest',
+    async ({ size, expectedBytes }) => {
+      clusterServiceMocks.listRegistryClusters.mockResolvedValue([
+        buildCluster({ maxMessageSize: 5000000 }),
+      ]);
+      const user = userEvent.setup({ pointerEventsCheck: 0 });
+      renderWithProviders(<ClusterPage />);
+
+      const brokerRow = await screen.findByRole('row', { name: 
/10\.101\.2\.11:10911/ });
+      await user.click(within(brokerRow).getByRole('button', { name: /^配\s*置$/ 
}));
+      const dialog = await screen.findByRole('dialog', { name: /配置 - 
rocketmq-prod/ });
+      const sizeInput = within(dialog).getByLabelText('最大消息大小 (MB)');
+      expect(sizeInput).toHaveValue('5');
+      await user.clear(sizeInput);
+      await user.type(sizeInput, size);
+
+      await user.click(within(dialog).getByRole('button', { name: /预\s*览/ }));
+      await waitFor(() =>
+        expect(clusterServiceMocks.previewClusterConfig).toHaveBeenCalledWith(
+          expect.objectContaining({ maxMessageSize: expectedBytes }),
+        ),
+      );
+      await user.click(within(dialog).getByRole('button', { name: /^OK$/ }));
+      await waitFor(() =>
+        expect(clusterServiceMocks.updateClusterConfig).toHaveBeenCalledWith(
+          expect.objectContaining({ maxMessageSize: expectedBytes }),
+        ),
+      );
+    },
+  );
+
+  it('resetsMessageSizeEditTrackingWhenTheConfigDialogReopensTest', async () 
=> {
+    clusterServiceMocks.listRegistryClusters.mockResolvedValue([
+      buildCluster({ maxMessageSize: 5000000 }),
+    ]);
+    const user = userEvent.setup({ pointerEventsCheck: 0 });
+    renderWithProviders(<ClusterPage />);
+
+    const brokerRow = await screen.findByRole('row', { name: 
/10\.101\.2\.11:10911/ });
+    const openConfigDialog = async () => {
+      await user.click(within(brokerRow).getByRole('button', { name: /^配\s*置$/ 
}));
+      return screen.findByRole('dialog', { name: /配置 - rocketmq-prod/ });
+    };
+    let dialog = await openConfigDialog();
+    const sizeInput = within(dialog).getByLabelText('最大消息大小 (MB)');
+    await user.clear(sizeInput);
+    await user.type(sizeInput, '6');
+    await user.click(within(dialog).getByRole('button', { name: /^cancel$/i 
}));
+
+    dialog = await openConfigDialog();
+    expect(within(dialog).getByLabelText('最大消息大小 (MB)')).toHaveValue('5');
+    await user.click(within(dialog).getByRole('button', { name: /^OK$/ }));
+    await waitFor(() =>
+      expect(clusterServiceMocks.updateClusterConfig).toHaveBeenCalledWith(
+        expect.objectContaining({ maxMessageSize: 5000000 }),
+      ),
+    );
+  });
+
   it('keeps the latest broker config preview after a superseded response 
finishes last', async () => {
     const user = userEvent.setup({ pointerEventsCheck: 0 });
     const stalePreview = deferred<ClusterConfigPreviewResult>();
diff --git a/web/src/pages/cluster/index.tsx b/web/src/pages/cluster/index.tsx
index d3f9e7ba9..86fd9b36d 100644
--- a/web/src/pages/cluster/index.tsx
+++ b/web/src/pages/cluster/index.tsx
@@ -712,6 +712,8 @@ const ClusterPage = () => {
       readQueueNums: cfg.readQueueNums ?? 8,
       brokerPermission: cfg.brokerPermission ?? 6,
     });
+    // setFieldsValue marks fields touched; only a user edit should replace 
the original bytes.
+    configForm.setFields([{ name: 'maxMessageSizeMB', touched: false }]);
     setConfigModalOpen(true);
   };
 
@@ -725,7 +727,9 @@ const ClusterPage = () => {
       instanceId: selectedInstanceIdRef.current,
       ...(selectedCluster.config ?? {}),
       ...configValues,
-      maxMessageSize: maxMessageSizeMB * 1048576,
+      maxMessageSize: configForm.isFieldTouched('maxMessageSizeMB')
+        ? maxMessageSizeMB * 1048576
+        : (selectedCluster.config?.maxMessageSize ?? 4194304),
     };
   };
 

Reply via email to