feat(wip): migrate WIP trio pages from Jinja2 to Vue 3 + Vite

Migrate /wip-overview, /wip-detail, and /hold-detail (1,941 lines vanilla JS)
to Vue 3 SFC architecture. Extract shared CSS/constants/components to
wip-shared/. Switch Pareto charts to vue-echarts with autoresize. Replace
Jinja2 template injection with frontend URL params + constant classification
for Hold Detail. Add 10-min auto-refresh + AbortController to Hold Detail.
Remove three Jinja2 templates, update Flask routes to send_from_directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
egg
2026-02-09 16:39:20 +08:00
parent dcbf6dcf1f
commit a2653b8139
53 changed files with 5397 additions and 6646 deletions

View File

@@ -36,23 +36,23 @@ class TestTemplateIntegration(unittest.TestCase):
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
def test_wip_overview_includes_base_scripts(self):
def test_wip_overview_serves_pure_vite_module(self):
response = self.client.get('/wip-overview')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
self.assertIn('/static/dist/wip-overview.js', html)
self.assertIn('type="module"', html)
self.assertNotIn('mes-toast-container', html)
def test_wip_detail_includes_base_scripts(self):
def test_wip_detail_serves_pure_vite_module(self):
response = self.client.get('/wip-detail')
self.assertEqual(response.status_code, 200)
html = response.data.decode('utf-8')
self.assertIn('toast.js', html)
self.assertIn('mes-api.js', html)
self.assertIn('mes-toast-container', html)
self.assertIn('/static/dist/wip-detail.js', html)
self.assertIn('type="module"', html)
self.assertNotIn('mes-toast-container', html)
def test_tables_page_serves_pure_vite_module(self):
response = self.client.get('/tables')
@@ -219,19 +219,19 @@ class TestToastCSSIntegration(unittest.TestCase):
self.assertIn('.mes-toast-container', html)
self.assertIn('.mes-toast', html)
def test_wip_overview_includes_toast_css(self):
def test_wip_overview_excludes_toast_css(self):
response = self.client.get('/wip-overview')
html = response.data.decode('utf-8')
self.assertIn('.mes-toast-container', html)
self.assertIn('.mes-toast', html)
self.assertNotIn('.mes-toast-container', html)
self.assertNotIn('.mes-toast', html)
def test_wip_detail_includes_toast_css(self):
def test_wip_detail_excludes_toast_css(self):
response = self.client.get('/wip-detail')
html = response.data.decode('utf-8')
self.assertIn('.mes-toast-container', html)
self.assertIn('.mes-toast', html)
self.assertNotIn('.mes-toast-container', html)
self.assertNotIn('.mes-toast', html)
class TestMesApiUsageInTemplates(unittest.TestCase):