feat: remove old vanilla JS/CSS frontend, make React SPA the sole entry for ccw view

Remove the entire old template-based frontend (~106K lines) and make the React
SPA the only way to access the ccw dashboard via `ccw view`.

Key changes:
- Delete all old frontend files: dashboard-css/ (37 CSS), dashboard-js/ (59 JS),
  assets/, dashboard.html, and legacy HTML templates
- Delete dashboard-generator.ts and dashboard-generator-patch.ts
- Simplify server.ts: remove ~234 lines of old frontend code (template constants,
  MODULE_CSS_FILES/MODULE_FILES arrays, generateServerDashboard(), /assets/* serving)
- Rebase React frontend from /react/ to root / (vite.config.ts, react-frontend.ts)
- Add /react/* -> /* 301 redirect for backward compatibility
- Remove --frontend and --new CLI flags from view and serve commands
- Remove generateDashboard export from public API (index.ts)
- Simplify serve.ts and view.ts to always use React without conditional branching
- Update all affected tests (unit, e2e) for React-only architecture

BREAKING CHANGE: --frontend and --new CLI flags removed; generateDashboard export
removed from ccw package; /react/ base path changed to /
This commit is contained in:
catlog22
2026-02-13 17:26:03 +08:00
parent 31f37751fc
commit bcb736709f
136 changed files with 204 additions and 115952 deletions

View File

@@ -9,14 +9,14 @@ import { setupEnhancedMonitoring, switchLanguageAndVerify } from './helpers/i18n
test.describe('[Skills] - Skills Management Tests', () => {
test.beforeEach(async ({ page }) => {
// Navigate to skills page directly and wait for full load
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
});
test('L3.1 - should display skills list', async ({ page }) => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for skills list container
const skillsList = page.getByTestId('skills-list').or(
@@ -43,7 +43,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for skill items
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -90,7 +90,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for skill items
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -124,7 +124,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for skill items
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -157,7 +157,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for category filter
const categoryFilter = page.getByRole('combobox', { name: /category|filter/i }).or(
@@ -192,7 +192,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for search input
const searchInput = page.getByRole('textbox', { name: /search|find/i }).or(
@@ -228,7 +228,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for skill items
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -261,7 +261,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Get language switcher
const languageSwitcher = page.getByRole('combobox', { name: /select language|language/i }).first();
@@ -286,7 +286,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
const monitoring = setupEnhancedMonitoring(page);
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Look for skill items
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -328,7 +328,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
});
// Navigate to skills page
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Try to toggle a skill
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -380,7 +380,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
});
});
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Try to toggle a skill (should fail with 400)
const skillItems = page.getByTestId(/skill-item|skill-card/).or(
@@ -424,7 +424,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
});
});
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Wait for React Query to complete retries and set error state
await page.waitForTimeout(3000);
@@ -453,7 +453,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
});
});
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Wait for React Query to complete retries and set error state
await page.waitForTimeout(3000);
@@ -483,7 +483,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
});
// Try to access a non-existent skill
await page.goto('/react/skills/nonexistent-skill-id', { waitUntil: 'domcontentloaded' as const });
await page.goto('/skills/nonexistent-skill-id', { waitUntil: 'domcontentloaded' as const });
// Wait for React Query to complete retries and set error state
await page.waitForTimeout(3000);
@@ -512,7 +512,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
});
});
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Wait for React Query to complete retries and set error state
await page.waitForTimeout(3000);
@@ -537,7 +537,7 @@ test.describe('[Skills] - Skills Management Tests', () => {
// Never fulfill - simulate timeout
});
await page.goto('/react/skills', { waitUntil: 'networkidle' as const });
await page.goto('/skills', { waitUntil: 'networkidle' as const });
// Wait for timeout handling
await page.waitForTimeout(5000);