feat(fleet): card-only UI with progressive load and restart ops
Drop the redundant advanced table so fleet stays resource-first cards. Keep multi-select batch service/system restart via prepare→execute, card restarts, overview system ops, and progressive fleet loading.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// @vitest-environment jsdom
|
||||
import { cleanup, render, screen, within } from '@testing-library/react';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { cleanup, fireEvent, render, screen, within } from '@testing-library/react';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { FleetPage, type FleetSnapshot } from './fleet-page.js';
|
||||
|
||||
@@ -11,13 +11,13 @@ const snapshot: FleetSnapshot = {
|
||||
name: 'Alpha modem',
|
||||
url: 'http://192.168.1.2',
|
||||
tags: [],
|
||||
revision: 3,
|
||||
},
|
||||
],
|
||||
statuses: new Map([
|
||||
[
|
||||
'alpha',
|
||||
{
|
||||
instanceId: 'alpha',
|
||||
reachable: true,
|
||||
authenticated: true,
|
||||
summary: { freshness: 'fresh', resources: { cpuPercent: 24, memoryPercent: 51 } },
|
||||
@@ -52,3 +52,65 @@ describe('FleetPage card navigation', () => {
|
||||
expect(within(card).getByRole('group', { name: '实例管理操作' })).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('FleetPage batch and restart actions', () => {
|
||||
it('exposes card restart controls and batch restart entry for selected instances', async () => {
|
||||
const prepare = vi.fn(async () => ({
|
||||
id: 'prep-1',
|
||||
status: 'prepared',
|
||||
operationId: 'postServiceRestart',
|
||||
risk: 'R3',
|
||||
expiresAt: '2030-01-01T00:00:00.000Z',
|
||||
confirmationPrompt: 'Confirm restart',
|
||||
targetCount: 1,
|
||||
}));
|
||||
const execute = vi.fn(async () => ({
|
||||
id: 'job-1',
|
||||
operationId: 'postServiceRestart',
|
||||
status: 'succeeded',
|
||||
rootJobId: 'job-1',
|
||||
items: [{ id: 'item-1', targetId: 'alpha', state: 'succeeded' }],
|
||||
attempts: [],
|
||||
createdAt: '2029-01-01T00:00:00.000Z',
|
||||
}));
|
||||
const list = vi.fn(async () => ({
|
||||
items: [
|
||||
{
|
||||
operationId: 'postServiceRestart',
|
||||
title: 'Restart Service',
|
||||
risk: 'R3',
|
||||
capability: 'job',
|
||||
batchable: false,
|
||||
parameterSchemaId: 'simadmin.58e2204.postServiceRestart.parameters.v1',
|
||||
},
|
||||
{
|
||||
operationId: 'postSystemReboot',
|
||||
title: 'Reboot System',
|
||||
risk: 'R3',
|
||||
capability: 'job',
|
||||
batchable: false,
|
||||
parameterSchemaId: 'simadmin.58e2204.postSystemReboot.parameters.v1',
|
||||
},
|
||||
],
|
||||
page: { page: 1, pageSize: 100, total: 2 },
|
||||
}));
|
||||
vi.stubGlobal('confirm', () => true);
|
||||
render(
|
||||
<FleetPage
|
||||
initialData={snapshot}
|
||||
operationClient={{ list, prepare, execute } as never}
|
||||
/>,
|
||||
);
|
||||
const card = screen.getByRole('article', { name: 'Alpha modem 实例概览' });
|
||||
expect(within(card).getByRole('button', { name: '重启服务 Alpha modem' })).toBeTruthy();
|
||||
expect(within(card).getByRole('button', { name: '系统重启 Alpha modem' })).toBeTruthy();
|
||||
fireEvent.click(within(card).getByRole('checkbox', { name: '选择 Alpha modem' }));
|
||||
expect(screen.getByText(/已选择 1 项/).textContent).toMatch(/已选择 1 项/);
|
||||
fireEvent.click(screen.getByRole('button', { name: '批量操作' }));
|
||||
const batch = await screen.findByRole('region', { name: '批量操作入口' });
|
||||
expect(batch.textContent).toMatch(/已选择 1 项/);
|
||||
fireEvent.click(screen.getByRole('button', { name: '批量重启服务' }));
|
||||
await vi.waitFor(() => expect(prepare).toHaveBeenCalled());
|
||||
expect(execute).toHaveBeenCalledWith('prep-1');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user