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 da6d98a5e fix(instance): keep cloud instance endpoints read-only in
the edit dialog (#4177)
da6d98a5e is described below
commit da6d98a5eeb09ae6fa4ef68e1d5be021650fa12c
Author: 烤化の初雪 <[email protected]>
AuthorDate: Tue Sep 15 19:18:36 2026 +0800
fix(instance): keep cloud instance endpoints read-only in the edit dialog
(#4177)
Co-authored-by: unbridled-41
<[email protected]>
---
.../pages/instance/__tests__/InstancePage.test.tsx | 34 +++++++++++++++++++++-
web/src/pages/instance/index.tsx | 3 ++
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/web/src/pages/instance/__tests__/InstancePage.test.tsx
b/web/src/pages/instance/__tests__/InstancePage.test.tsx
index ec2494ef3..298b690bd 100644
--- a/web/src/pages/instance/__tests__/InstancePage.test.tsx
+++ b/web/src/pages/instance/__tests__/InstancePage.test.tsx
@@ -24,7 +24,7 @@ import * as aliyunCatalogApi from
'../../../api/aliyunCatalog';
import * as cloudCredentialApi from '../../../api/cloudCredential';
import * as tencentCatalogApi from '../../../api/tencentCatalog';
import type { CloudCredential, CloudCredentialPage } from
'../../../api/cloudCredential';
-import type { Instance } from '../../../api/instance';
+import type { Instance, InstanceType, InstanceVendor } from
'../../../api/instance';
import { LangProvider } from '../../../i18n/LangContext';
import { LANGUAGE_STORAGE_KEY } from '../../../i18n/languagePreference';
import * as instanceService from '../../../services/instanceService';
@@ -372,6 +372,38 @@ describe('InstancePage', () => {
);
});
+ it('keeps the endpoint editable for Apache instances but read-only for cloud
vendors', async () => {
+ 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 },
+ ]);
+
+ renderPage();
+
+ await screen.findByText('production-proxy');
+
+ await user.click(
+ within(screen.getByRole('row', { name: /production-proxy/
})).getByRole('button', {
+ name: /编\s*辑/,
+ }),
+ );
+ const apacheDialog = await screen.findByRole('dialog');
+ expect(within(apacheDialog).getByLabelText('接入地址')).toBeEnabled();
+ await user.click(within(apacheDialog).getByRole('button', { name: /取\s*消/
}));
+ await waitFor(() => expect(apacheDialog).toHaveClass('ant-zoom-leave'));
+
+ await user.click(
+ within(screen.getByRole('row', { name: /aliyun-prod/
})).getByRole('button', {
+ name: /编\s*辑/,
+ }),
+ );
+ const cloudDialog = await screen.findByRole('dialog');
+ const endpointInput = within(cloudDialog).getByLabelText('接入地址');
+ expect(endpointInput).toBeDisabled();
+ expect(endpointInput).toHaveValue('aliyun-prod:8080');
+ });
+
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 9b5e4155d..75376b02d 100644
--- a/web/src/pages/instance/index.tsx
+++ b/web/src/pages/instance/index.tsx
@@ -1041,6 +1041,9 @@ const InstancePage = () => {
extra={getEndpointExtra(editInstanceType)}
>
<Input
+ // Cloud vendors resolve the endpoint from the catalog; the
backend ignores
+ // endpoint changes for them, so editing would only fake a
successful save.
+ disabled={editingInstance?.vendor != null &&
editingInstance.vendor !== 'APACHE'}
placeholder={
editInstanceType === 'DIRECT'
? t('instance.directEndpointPlaceholder')