Add frontend rebuild warning indicator to version display

- Return bool from check_frontend_build()
- Add ⚠️ symbol to outdated versions
- Show tooltip with rebuild message
- Add translations for warning text
- Fix tailwind config filename typo
This commit is contained in:
yangdx 2025-10-31 06:09:46 +08:00
parent e5414c61ef
commit 7ccc1fdd27
7 changed files with 45 additions and 13 deletions

View file

@ -131,7 +131,11 @@ class LLMConfigCache:
def check_frontend_build(): def check_frontend_build():
"""Check if frontend is built and optionally check if source is up-to-date""" """Check if frontend is built and optionally check if source is up-to-date
Returns:
bool: True if frontend is outdated, False if up-to-date or production environment
"""
webui_dir = Path(__file__).parent / "webui" webui_dir = Path(__file__).parent / "webui"
index_html = webui_dir / "index.html" index_html = webui_dir / "index.html"
@ -166,7 +170,7 @@ def check_frontend_build():
logger.debug( logger.debug(
"Production environment detected, skipping source freshness check" "Production environment detected, skipping source freshness check"
) )
return return False
# Development environment, perform source code timestamp check # Development environment, perform source code timestamp check
logger.debug("Development environment detected, checking source freshness") logger.debug("Development environment detected, checking source freshness")
@ -197,7 +201,7 @@ def check_frontend_build():
source_dir / "bun.lock", source_dir / "bun.lock",
source_dir / "vite.config.ts", source_dir / "vite.config.ts",
source_dir / "tsconfig.json", source_dir / "tsconfig.json",
source_dir / "tailwind.config.js", source_dir / "tailraid.config.js",
source_dir / "index.html", source_dir / "index.html",
] ]
@ -241,17 +245,25 @@ def check_frontend_build():
ASCIIColors.cyan(" cd ..") ASCIIColors.cyan(" cd ..")
ASCIIColors.yellow("\nThe server will continue with the current build.") ASCIIColors.yellow("\nThe server will continue with the current build.")
ASCIIColors.yellow("=" * 80 + "\n") ASCIIColors.yellow("=" * 80 + "\n")
return True # Frontend is outdated
else: else:
logger.info("Frontend build is up-to-date") logger.info("Frontend build is up-to-date")
return False # Frontend is up-to-date
except Exception as e: except Exception as e:
# If check fails, log warning but don't affect startup # If check fails, log warning but don't affect startup
logger.warning(f"Failed to check frontend source freshness: {e}") logger.warning(f"Failed to check frontend source freshness: {e}")
return False # Assume up-to-date on error
def create_app(args): def create_app(args):
# Check frontend build first # Check frontend build first and get outdated status
check_frontend_build() is_frontend_outdated = check_frontend_build()
# Create unified API version display with warning symbol if frontend is outdated
api_version_display = (
f"{__api_version__}⚠️" if is_frontend_outdated else __api_version__
)
# Setup logging # Setup logging
logger.setLevel(args.log_level) logger.setLevel(args.log_level)
@ -801,7 +813,7 @@ def create_app(args):
"auth_mode": "disabled", "auth_mode": "disabled",
"message": "Authentication is disabled. Using guest access.", "message": "Authentication is disabled. Using guest access.",
"core_version": core_version, "core_version": core_version,
"api_version": __api_version__, "api_version": api_version_display,
"webui_title": webui_title, "webui_title": webui_title,
"webui_description": webui_description, "webui_description": webui_description,
} }
@ -810,7 +822,7 @@ def create_app(args):
"auth_configured": True, "auth_configured": True,
"auth_mode": "enabled", "auth_mode": "enabled",
"core_version": core_version, "core_version": core_version,
"api_version": __api_version__, "api_version": api_version_display,
"webui_title": webui_title, "webui_title": webui_title,
"webui_description": webui_description, "webui_description": webui_description,
} }
@ -828,7 +840,7 @@ def create_app(args):
"auth_mode": "disabled", "auth_mode": "disabled",
"message": "Authentication is disabled. Using guest access.", "message": "Authentication is disabled. Using guest access.",
"core_version": core_version, "core_version": core_version,
"api_version": __api_version__, "api_version": api_version_display,
"webui_title": webui_title, "webui_title": webui_title,
"webui_description": webui_description, "webui_description": webui_description,
} }
@ -845,7 +857,7 @@ def create_app(args):
"token_type": "bearer", "token_type": "bearer",
"auth_mode": "enabled", "auth_mode": "enabled",
"core_version": core_version, "core_version": core_version,
"api_version": __api_version__, "api_version": api_version_display,
"webui_title": webui_title, "webui_title": webui_title,
"webui_description": webui_description, "webui_description": webui_description,
} }
@ -909,7 +921,7 @@ def create_app(args):
"pipeline_busy": pipeline_status.get("busy", False), "pipeline_busy": pipeline_status.get("busy", False),
"keyed_locks": keyed_lock_info, "keyed_locks": keyed_lock_info,
"core_version": core_version, "core_version": core_version,
"api_version": __api_version__, "api_version": api_version_display,
"webui_title": webui_title, "webui_title": webui_title,
"webui_description": webui_description, "webui_description": webui_description,
} }

View file

@ -62,6 +62,12 @@ export default function SiteHeader() {
? `${coreVersion}/${apiVersion}` ? `${coreVersion}/${apiVersion}`
: null; : null;
// Check if frontend needs rebuild (apiVersion ends with warning symbol)
const hasWarning = apiVersion?.endsWith('⚠️');
const versionTooltip = hasWarning
? t('header.frontendNeedsRebuild')
: versionDisplay ? `v${versionDisplay}` : '';
const handleLogout = () => { const handleLogout = () => {
navigationService.navigateToLogin(); navigationService.navigateToLogin();
} }
@ -106,9 +112,18 @@ export default function SiteHeader() {
<nav className="w-[200px] flex items-center justify-end"> <nav className="w-[200px] flex items-center justify-end">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
{versionDisplay && ( {versionDisplay && (
<span className="text-xs text-gray-500 dark:text-gray-400 mr-1"> <TooltipProvider>
v{versionDisplay} <Tooltip>
</span> <TooltipTrigger asChild>
<span className="text-xs text-gray-500 dark:text-gray-400 mr-1 cursor-default">
v{versionDisplay}
</span>
</TooltipTrigger>
<TooltipContent side="bottom">
{versionTooltip}
</TooltipContent>
</Tooltip>
</TooltipProvider>
)} )}
<Button variant="ghost" size="icon" side="bottom" tooltip={t('header.projectRepository')}> <Button variant="ghost" size="icon" side="bottom" tooltip={t('header.projectRepository')}>
<a href={SiteInfo.github} target="_blank" rel="noopener noreferrer"> <a href={SiteInfo.github} target="_blank" rel="noopener noreferrer">

View file

@ -13,6 +13,7 @@
"api": "واجهة برمجة التطبيقات", "api": "واجهة برمجة التطبيقات",
"projectRepository": "مستودع المشروع", "projectRepository": "مستودع المشروع",
"logout": "تسجيل الخروج", "logout": "تسجيل الخروج",
"frontendNeedsRebuild": "الواجهة الأمامية تحتاج إلى إعادة البناء",
"themeToggle": { "themeToggle": {
"switchToLight": "التحويل إلى السمة الفاتحة", "switchToLight": "التحويل إلى السمة الفاتحة",
"switchToDark": "التحويل إلى السمة الداكنة" "switchToDark": "التحويل إلى السمة الداكنة"

View file

@ -13,6 +13,7 @@
"api": "API", "api": "API",
"projectRepository": "Project Repository", "projectRepository": "Project Repository",
"logout": "Logout", "logout": "Logout",
"frontendNeedsRebuild": "Frontend needs rebuild",
"themeToggle": { "themeToggle": {
"switchToLight": "Switch to light theme", "switchToLight": "Switch to light theme",
"switchToDark": "Switch to dark theme" "switchToDark": "Switch to dark theme"

View file

@ -13,6 +13,7 @@
"api": "API", "api": "API",
"projectRepository": "Référentiel du projet", "projectRepository": "Référentiel du projet",
"logout": "Déconnexion", "logout": "Déconnexion",
"frontendNeedsRebuild": "Le frontend nécessite une reconstruction",
"themeToggle": { "themeToggle": {
"switchToLight": "Passer au thème clair", "switchToLight": "Passer au thème clair",
"switchToDark": "Passer au thème sombre" "switchToDark": "Passer au thème sombre"

View file

@ -13,6 +13,7 @@
"api": "API", "api": "API",
"projectRepository": "项目仓库", "projectRepository": "项目仓库",
"logout": "退出登录", "logout": "退出登录",
"frontendNeedsRebuild": "前端代码需重新构建",
"themeToggle": { "themeToggle": {
"switchToLight": "切换到浅色主题", "switchToLight": "切换到浅色主题",
"switchToDark": "切换到深色主题" "switchToDark": "切换到深色主题"

View file

@ -13,6 +13,7 @@
"api": "API", "api": "API",
"projectRepository": "專案庫", "projectRepository": "專案庫",
"logout": "登出", "logout": "登出",
"frontendNeedsRebuild": "前端程式碼需重新建置",
"themeToggle": { "themeToggle": {
"switchToLight": "切換至淺色主題", "switchToLight": "切換至淺色主題",
"switchToDark": "切換至深色主題" "switchToDark": "切換至深色主題"