feat(tables): migrate /tables page from Jinja2 to Vue 3 + Vite

Rewrite 237-line vanilla JS + Jinja2 template into Vue 3 SFC components
(App.vue, TableCatalog.vue, DataViewer.vue, useTableData composable).
Establishes apiPost POST request pattern for pure Vite pages. Removes
templates/index.html, updates Vite entry to HTML, and Flask route to
send_from_directory. Includes sql_fragments WHERE_CLAUSE escaping fix,
updated integration tests, and OpenSpec artifact archive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
egg
2026-02-09 14:52:14 +08:00
parent 44b89599a4
commit dcbf6dcf1f
23 changed files with 1483 additions and 838 deletions

View File

@@ -11,7 +11,6 @@ import threading
from flask import Flask, jsonify, redirect, render_template, request, send_from_directory, session, url_for
from mes_dashboard.config.tables import TABLES_CONFIG
from mes_dashboard.config.settings import get_config
from mes_dashboard.core.cache import create_default_cache_backend
from mes_dashboard.core.database import (
@@ -380,8 +379,26 @@ def create_app(config_name: str | None = None) -> Flask:
@app.route('/tables')
def tables_page():
"""Table viewer page."""
return render_template('index.html', tables_config=TABLES_CONFIG)
"""Table viewer page served as pure Vite HTML output."""
dist_dir = os.path.join(app.static_folder or "", "dist")
dist_html = os.path.join(dist_dir, "tables.html")
if os.path.exists(dist_html):
return send_from_directory(dist_dir, 'tables.html')
nested_dist_dir = os.path.join(dist_dir, "src", "tables")
nested_dist_html = os.path.join(nested_dist_dir, "index.html")
if os.path.exists(nested_dist_html):
return send_from_directory(nested_dist_dir, "index.html")
# Test/local fallback when frontend build artifacts are absent.
return (
"<!doctype html><html lang=\"zh-Hant\"><head><meta charset=\"UTF-8\">"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
"<title>MES 數據表查詢工具</title>"
"<script type=\"module\" src=\"/static/dist/tables.js\"></script>"
"</head><body><div id='app'></div></body></html>",
200,
)
@app.route('/wip-overview')
def wip_overview_page():
@@ -453,6 +470,8 @@ def create_app(config_name: str | None = None) -> Flask:
@app.route('/api/get_table_info', methods=['GET'])
def get_table_info():
"""API: get tables config."""
from mes_dashboard.config.tables import TABLES_CONFIG
return jsonify(TABLES_CONFIG)
# ========================================================