diff --git a/web/src/i18n/translations.ts b/web/src/i18n/translations.ts index 3074959b..321ba2e7 100644 --- a/web/src/i18n/translations.ts +++ b/web/src/i18n/translations.ts @@ -956,6 +956,10 @@ const translations: Record> = { 'groupMgmt.stopped': { zh: '已停止', en: 'Stopped' }, 'groupMgmt.createGroup': { zh: '创建消费组', en: 'Create Group' }, 'groupMgmt.searchPlaceholder': { zh: '搜索消费组', en: 'Search group' }, + 'groupMgmt.providerUnavailable': { + zh: '当前版本尚未接入真实消费组管理接口,已停止展示模拟消费组数据。', + en: 'The real consumer group management API is not connected yet, so mock consumer group data is no longer displayed.', + }, 'groupMgmt.manual': { zh: '手动', en: 'Manual' }, 'groupMgmt.overview': { zh: '概览', en: 'Overview' }, 'groupMgmt.totalDiff': { zh: '总堆积量', en: 'Total Diff' }, diff --git a/web/src/pages/studio/GroupManagement.tsx b/web/src/pages/studio/GroupManagement.tsx index 47102e16..0a648b04 100644 --- a/web/src/pages/studio/GroupManagement.tsx +++ b/web/src/pages/studio/GroupManagement.tsx @@ -21,16 +21,11 @@ import { Button, Input, Tag, - Modal, - Tabs, Card, - Row, - Col, - Descriptions, Space, Switch, } from 'antd'; -import { MagnifyingGlass, Plus, ArrowClockwise, Users, Eye } from '@phosphor-icons/react'; +import { MagnifyingGlass, Plus, ArrowClockwise, Users } from '@phosphor-icons/react'; import { useLang } from '../../i18n/LangContext'; // ─── Types ────────────────────────────────────────────────────── @@ -46,187 +41,14 @@ interface GroupRecord { status: 'running' | 'warning' | 'stopped'; } -interface SubscriptionRecord { - key: string; - topic: string; - consistency: 'consistent' | 'inconsistent'; - subMode: string; - expression: string; -} - -interface InstanceRecord { - key: string; - instanceId: string; - address: string; - version: string; - status: string; -} - -interface ProgressRecord { - key: string; - topic: string; - queueId: string; - brokerOffset: string; - consumerOffset: string; - diff: number; -} - -// ─── Mock Data ────────────────────────────────────────────────── -const groupData: GroupRecord[] = [ - { - key: '1', - group: 'order-consumer-group', - namespace: 'default', - cluster: 'cluster-production', - count: 4, - consumeType: 'PUSH', - messageModel: 'CLUSTERING', - diff: 1280, - status: 'running', - }, - { - key: '2', - group: 'payment-consumer-group', - namespace: 'default', - cluster: 'cluster-production', - count: 2, - consumeType: 'PUSH', - messageModel: 'CLUSTERING', - diff: 0, - status: 'running', - }, - { - key: '3', - group: 'inventory-sync-group', - namespace: 'ns-warehouse', - cluster: 'cluster-warehouse', - count: 3, - consumeType: 'PUSH', - messageModel: 'CLUSTERING', - diff: 56800, - status: 'warning', - }, - { - key: '4', - group: 'log-processor-group', - namespace: 'default', - cluster: 'cluster-production', - count: 1, - consumeType: 'PUSH', - messageModel: 'BROADCASTING', - diff: 0, - status: 'running', - }, - { - key: '5', - group: 'notification-group', - namespace: 'ns-notify', - cluster: 'cluster-production', - count: 2, - consumeType: 'PUSH', - messageModel: 'CLUSTERING', - diff: 3, - status: 'running', - }, -]; - -const subscriptionData: SubscriptionRecord[] = [ - { key: '1', topic: 'ORDER_TOPIC', consistency: 'consistent', subMode: 'TAG', expression: '*' }, - { - key: '2', - topic: 'PAYMENT_TOPIC', - consistency: 'consistent', - subMode: 'TAG', - expression: 'pay_success || pay_fail', - }, - { - key: '3', - topic: 'INVENTORY_TOPIC', - consistency: 'inconsistent', - subMode: 'TAG', - expression: 'stock_update', - }, -]; - -const instanceData: InstanceRecord[] = [ - { - key: '1', - instanceId: 'cid-001', - address: '10.0.1.10:10911', - version: '5.3.0', - status: 'online', - }, - { - key: '2', - instanceId: 'cid-002', - address: '10.0.1.11:10911', - version: '5.3.0', - status: 'online', - }, - { - key: '3', - instanceId: 'cid-003', - address: '10.0.1.12:10911', - version: '5.3.0', - status: 'online', - }, - { - key: '4', - instanceId: 'cid-004', - address: '10.0.1.13:10911', - version: '5.3.0', - status: 'online', - }, -]; - -const progressData: ProgressRecord[] = [ - { - key: '1', - topic: 'ORDER_TOPIC', - queueId: '0', - brokerOffset: '125,680', - consumerOffset: '125,400', - diff: 280, - }, - { - key: '2', - topic: 'ORDER_TOPIC', - queueId: '1', - brokerOffset: '98,200', - consumerOffset: '98,200', - diff: 0, - }, - { - key: '3', - topic: 'PAYMENT_TOPIC', - queueId: '0', - brokerOffset: '45,300', - consumerOffset: '45,300', - diff: 0, - }, - { - key: '4', - topic: 'INVENTORY_TOPIC', - queueId: '0', - brokerOffset: '230,100', - consumerOffset: '173,300', - diff: 56800, - }, -]; +const groupData: GroupRecord[] = []; // ─── Component ────────────────────────────────────────────────── const GroupManagementPage = () => { const [searchText, setSearchText] = useState(''); - const [modalVisible, setModalVisible] = useState(false); - const [selectedGroup, setSelectedGroup] = useState(null); const [autoRefresh, setAutoRefresh] = useState(false); const { t } = useLang(); - const handleViewDetail = (groupName: string) => { - setSelectedGroup(groupName); - setModalVisible(true); - }; - const normalizedSearchText = searchText.trim().toLowerCase(); const filteredGroupData = groupData.filter( (record) => !normalizedSearchText || record.group.toLowerCase().includes(normalizedSearchText), @@ -238,9 +60,9 @@ const GroupManagementPage = () => { dataIndex: 'group', key: 'group', render: (text: string) => ( - handleViewDetail(text)} style={{ color: '#1677ff', fontWeight: 500 }}> + {text} - + ), }, { title: t('groupMgmt.namespace'), dataIndex: 'namespace', key: 'namespace' }, @@ -293,12 +115,12 @@ const GroupManagementPage = () => { { title: t('common.actions'), key: 'action', - render: (_: unknown, record: GroupRecord) => ( + render: () => ( - - @@ -306,45 +128,6 @@ const GroupManagementPage = () => { }, ]; - const subscriptionColumns = [ - { - title: t('groupMgmt.topic'), - dataIndex: 'topic', - key: 'topic', - render: (text: string) => {text}, - }, - { - title: t('groupMgmt.consistency'), - dataIndex: 'consistency', - key: 'consistency', - render: (consistency: string) => ( - - {consistency === 'consistent' ? t('groupMgmt.consistent') : t('groupMgmt.inconsistent')} - - ), - }, - { title: t('groupMgmt.subMode'), dataIndex: 'subMode', key: 'subMode' }, - { - title: t('groupMgmt.expression'), - dataIndex: 'expression', - key: 'expression', - render: (text: string) => ( - - {text} - - ), - }, - { - title: t('common.actions'), - key: 'action', - render: () => ( - - ), - }, - ]; - return (
{ `${t('common.total')} ${total} Group`, @@ -404,151 +188,6 @@ const GroupManagementPage = () => { size="middle" /> - - setModalVisible(false)} - footer={null} - width={720} - destroyOnClose - > -
-

- - {selectedGroup} -

-
- - -
- -
- {t('groupMgmt.onlineInstances')} -
-
- 4{' '} - - {t('groupMgmt.online')} - -
-
- - - -
- {t('groupMgmt.totalDiff')} -
-
1,280
-
- - - -
- {t('groupMgmt.subscribedTopics')} -
-
3
-
- - - - - order-consumer-group - - default - - cluster-production - - - {t('groupMgmt.clustering')} - - PUSH - 12ms - 16 - - 2025-03-15 10:30:00 - - - ORDER_TOPIC, PAYMENT_TOPIC, INVENTORY_TOPIC - - -

{t('groupMgmt.subscription')}

-
- - ), - }, - { - key: 'instances', - label: t('groupMgmt.onlineInstances'), - children: ( -
{t('groupMgmt.online')}, - }, - ]} - dataSource={instanceData} - pagination={false} - size="small" - /> - ), - }, - { - key: 'progress', - label: t('groupMgmt.consumeProgress'), - children: ( -
( - 100 ? '#ff4d4f' : '#52c41a', fontWeight: 500 }}> - {v} - - ), - }, - ]} - dataSource={progressData} - pagination={false} - size="small" - /> - ), - }, - ]} - /> - ); }; diff --git a/web/src/pages/studio/__tests__/GroupManagement.test.tsx b/web/src/pages/studio/__tests__/GroupManagement.test.tsx index 3b93a966..05d48695 100644 --- a/web/src/pages/studio/__tests__/GroupManagement.test.tsx +++ b/web/src/pages/studio/__tests__/GroupManagement.test.tsx @@ -74,24 +74,25 @@ describe('GroupManagement Page', () => { expect(screen.getByText('重置')).toBeInTheDocument(); }); - it('should display mock consumer group data in table', () => { + it('should show an explicit unavailable state instead of mock consumer groups', () => { renderWithProviders(); - expect(screen.getByText('order-consumer-group')).toBeInTheDocument(); - expect(screen.getByText('payment-consumer-group')).toBeInTheDocument(); + expect(screen.getByText('当前版本尚未接入真实消费组管理接口,已停止展示模拟消费组数据。')).toBeInTheDocument(); + expect(screen.queryByText('order-consumer-group')).not.toBeInTheDocument(); + expect(screen.queryByText('payment-consumer-group')).not.toBeInTheDocument(); }); - it('should render detail action buttons for each row', () => { + it('should not render row actions without real consumer group data', () => { renderWithProviders(); - const detailButtons = screen.getAllByText('详情'); - expect(detailButtons.length).toBeGreaterThan(0); + expect(screen.queryByText('详情')).not.toBeInTheDocument(); }); - it('should filter groups by search text', async () => { + it('should keep mock groups hidden when filtering by search text', async () => { const user = userEvent.setup(); renderWithProviders(); const searchInput = screen.getByPlaceholderText('搜索消费组'); await user.type(searchInput, 'ORDER'); - expect(screen.getByText('order-consumer-group')).toBeInTheDocument(); + expect(screen.getByText('当前版本尚未接入真实消费组管理接口,已停止展示模拟消费组数据。')).toBeInTheDocument(); + expect(screen.queryByText('order-consumer-group')).not.toBeInTheDocument(); expect(screen.queryByText('payment-consumer-group')).not.toBeInTheDocument(); }); });