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 d5196bf13 fix(instance): let a cloud instance with a blank endpoint 
still be saved (#4198)
d5196bf13 is described below

commit d5196bf1371d8747cbe1945bba642621075d73d7
Author: jokerzsd <[email protected]>
AuthorDate: Tue Sep 15 20:50:36 2026 +0800

    fix(instance): let a cloud instance with a blank endpoint still be saved 
(#4198)
    
    The endpoint input is disabled for non-APACHE vendors, because the cloud
    endpoint is resolved from the catalog and the backend ignores edits to it.
    The field kept its required rule, though, so a cloud instance whose stored
    endpoint is blank rendered a disabled, empty input that could never pass
    validation: the edit dialog became unsubmitable with no way to fix it from
    the UI.
    
    Drop the required rule for non-APACHE vendors only. Apache instances still
    have to supply an endpoint.
    
    Signed-off-by: jokerzsd <[email protected]>
---
 .../pages/instance/__tests__/InstancePage.test.tsx | 38 +++++++++++++++++++++-
 web/src/pages/instance/index.tsx                   |  8 ++++-
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/web/src/pages/instance/__tests__/InstancePage.test.tsx 
b/web/src/pages/instance/__tests__/InstancePage.test.tsx
index 298b690bd..2e1cc2b7b 100644
--- a/web/src/pages/instance/__tests__/InstancePage.test.tsx
+++ b/web/src/pages/instance/__tests__/InstancePage.test.tsx
@@ -376,7 +376,11 @@ describe('InstancePage', () => {
     const user = userEvent.setup();
     vi.mocked(instanceService.listInstances).mockResolvedValue([
       instance(1, 'production-proxy'),
-      { ...instance(2, 'aliyun-prod'), vendor: 'ALIYUN' as InstanceVendor, 
type: 'CLOUD' as InstanceType },
+      {
+        ...instance(2, 'aliyun-prod'),
+        vendor: 'ALIYUN' as InstanceVendor,
+        type: 'CLOUD' as InstanceType,
+      },
     ]);
 
     renderPage();
@@ -404,6 +408,38 @@ describe('InstancePage', () => {
     expect(endpointInput).toHaveValue('aliyun-prod:8080');
   });
 
+  it('submits a cloud instance whose stored endpoint is blank', async () => {
+    const user = userEvent.setup();
+    const blankEndpointCloud = {
+      ...instance(2, 'aliyun-prod'),
+      vendor: 'ALIYUN' as InstanceVendor,
+      type: 'CLOUD' as InstanceType,
+      endpoint: '',
+    };
+    
vi.mocked(instanceService.listInstances).mockResolvedValue([blankEndpointCloud]);
+    
vi.mocked(instanceService.updateInstance).mockResolvedValue(blankEndpointCloud);
+
+    renderPage();
+    await screen.findByText('aliyun-prod');
+
+    await user.click(
+      within(screen.getByRole('row', { name: /aliyun-prod/ 
})).getByRole('button', {
+        name: /编\s*辑/,
+      }),
+    );
+    const dialog = await screen.findByRole('dialog');
+    const endpointInput = within(dialog).getByLabelText('接入地址');
+    expect(endpointInput).toBeDisabled();
+    expect(endpointInput).toHaveValue('');
+
+    await user.click(within(dialog).getByRole('button', { name: /保\s*存/ }));
+
+    // The cloud endpoint is resolved from the catalog and the input is 
disabled, so keeping the
+    // required rule would leave an instance with a blank stored endpoint 
permanently unsaveable.
+    await waitFor(() => 
expect(instanceService.updateInstance).toHaveBeenCalled());
+    expect(screen.queryByText('请输入接入地址')).not.toBeInTheDocument();
+  });
+
   it('reloads the latest filters after a pending instance deletion completes', 
async () => {
     const user = userEvent.setup();
     const pendingDelete = deferred<void>();
diff --git a/web/src/pages/instance/index.tsx b/web/src/pages/instance/index.tsx
index 75376b02d..23eb74185 100644
--- a/web/src/pages/instance/index.tsx
+++ b/web/src/pages/instance/index.tsx
@@ -1037,7 +1037,13 @@ const InstancePage = () => {
               </span>
             }
             name="endpoint"
-            rules={[{ required: true, message: t('instance.endpointRequired') 
}]}
+            rules={
+              // A cloud endpoint is resolved from the catalog and the input 
is disabled below,
+              // so a stored blank value must not make this dialog impossible 
to submit.
+              editingInstance?.vendor != null && editingInstance.vendor !== 
'APACHE'
+                ? []
+                : [{ required: true, message: t('instance.endpointRequired') }]
+            }
             extra={getEndpointExtra(editInstanceType)}
           >
             <Input

Reply via email to