mirror of
https://github.com/Zie619/n8n-workflows.git
synced 2025-11-25 11:29:34 +08:00
feat: Add GitHub Pages public search interface and enhanced documentation system
## 🌐 GitHub Pages Public Search Interface - Complete client-side search application solving Issue #84 - Responsive HTML/CSS/JavaScript with mobile optimization - Real-time search across 2,057+ workflows with instant results - Category filtering across 15 workflow categories - Dark/light theme support with system preference detection - Direct workflow JSON download functionality ## 🤖 GitHub Actions Automation - deploy-pages.yml: Automated deployment to GitHub Pages - update-readme.yml: Weekly automated README statistics updates - Comprehensive workflow indexing and category generation ## 🔍 Enhanced Search & Categorization - Static search index generation for GitHub Pages - Developer-chosen category prioritization system - CalcsLive custom node integration and categorization - Enhanced workflow database with better custom node detection - Fixed README corruption with live database statistics ## 📚 Documentation & Infrastructure - Comprehensive CHANGELOG.md with proper versioning - Enhanced README with accurate statistics and public interface links - Professional documentation solving repository infrastructure needs ## Technical Improvements - Fixed Unicode encoding issues in Python scripts - Enhanced CalcsLive detection with false positive prevention - Improved JSON description preservation and indexing - Mobile-optimized responsive design for all devices 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -199,8 +199,12 @@ class WorkflowDatabase:
|
||||
workflow['trigger_type'] = trigger_type
|
||||
workflow['integrations'] = list(integrations)
|
||||
|
||||
# Generate description
|
||||
workflow['description'] = self.generate_description(workflow, trigger_type, integrations)
|
||||
# Use JSON description if available, otherwise generate one
|
||||
json_description = data.get('description', '').strip()
|
||||
if json_description:
|
||||
workflow['description'] = json_description
|
||||
else:
|
||||
workflow['description'] = self.generate_description(workflow, trigger_type, integrations)
|
||||
|
||||
return workflow
|
||||
|
||||
@@ -353,7 +357,7 @@ class WorkflowDatabase:
|
||||
service_name = service_mappings.get(raw_service, raw_service.title() if raw_service else None)
|
||||
|
||||
# Handle custom nodes
|
||||
elif '-' in node_type:
|
||||
elif '-' in node_type or '@' in node_type:
|
||||
# Try to extract service name from custom node names like "n8n-nodes-youtube-transcription-kasha.youtubeTranscripter"
|
||||
parts = node_type.lower().split('.')
|
||||
for part in parts:
|
||||
@@ -366,10 +370,16 @@ class WorkflowDatabase:
|
||||
elif 'discord' in part:
|
||||
service_name = 'Discord'
|
||||
break
|
||||
elif 'calcslive' in part:
|
||||
service_name = 'CalcsLive'
|
||||
break
|
||||
|
||||
# Also check node names for service hints
|
||||
# Also check node names for service hints (but avoid false positives)
|
||||
for service_key, service_value in service_mappings.items():
|
||||
if service_key in node_name and service_value:
|
||||
# Avoid false positive: "cal" in calcslive-related terms should not match "Cal.com"
|
||||
if service_key == 'cal' and any(term in node_name.lower() for term in ['calcslive', 'calc', 'calculation']):
|
||||
continue
|
||||
service_name = service_value
|
||||
break
|
||||
|
||||
@@ -530,33 +540,16 @@ class WorkflowDatabase:
|
||||
where_conditions.append("w.complexity = ?")
|
||||
params.append(complexity_filter)
|
||||
|
||||
# Use FTS search if query provided and FTS table exists
|
||||
# Use FTS search if query provided
|
||||
if query.strip():
|
||||
# Check if FTS table exists
|
||||
cursor_check = conn.execute("""
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name='workflows_fts'
|
||||
""")
|
||||
fts_exists = cursor_check.fetchone() is not None
|
||||
|
||||
if fts_exists:
|
||||
# FTS search with ranking
|
||||
base_query = """
|
||||
SELECT w.*, rank
|
||||
FROM workflows_fts fts
|
||||
JOIN workflows w ON w.id = fts.rowid
|
||||
WHERE workflows_fts MATCH ?
|
||||
"""
|
||||
params.insert(0, query)
|
||||
else:
|
||||
# Fallback to LIKE search if FTS not available
|
||||
base_query = """
|
||||
SELECT w.*, 0 as rank
|
||||
FROM workflows w
|
||||
WHERE (w.name LIKE ? OR w.description LIKE ? OR w.filename LIKE ?)
|
||||
"""
|
||||
search_term = f"%{query}%"
|
||||
params.extend([search_term, search_term, search_term])
|
||||
# FTS search with ranking
|
||||
base_query = """
|
||||
SELECT w.*, rank
|
||||
FROM workflows_fts fts
|
||||
JOIN workflows w ON w.id = fts.rowid
|
||||
WHERE workflows_fts MATCH ?
|
||||
"""
|
||||
params.insert(0, query)
|
||||
else:
|
||||
# Regular query without FTS
|
||||
base_query = """
|
||||
@@ -566,10 +559,7 @@ class WorkflowDatabase:
|
||||
"""
|
||||
|
||||
if where_conditions:
|
||||
if "WHERE" in base_query:
|
||||
base_query += " AND " + " AND ".join(where_conditions)
|
||||
else:
|
||||
base_query += " WHERE " + " AND ".join(where_conditions)
|
||||
base_query += " AND " + " AND ".join(where_conditions)
|
||||
|
||||
# Count total results
|
||||
count_query = f"SELECT COUNT(*) as total FROM ({base_query}) t"
|
||||
@@ -669,7 +659,7 @@ class WorkflowDatabase:
|
||||
'cloud_storage': ['Google Drive', 'Google Docs', 'Google Sheets', 'Dropbox', 'OneDrive', 'Box'],
|
||||
'database': ['PostgreSQL', 'MySQL', 'MongoDB', 'Redis', 'Airtable', 'Notion'],
|
||||
'project_management': ['Jira', 'GitHub', 'GitLab', 'Trello', 'Asana', 'Monday.com'],
|
||||
'ai_ml': ['OpenAI', 'Anthropic', 'Hugging Face'],
|
||||
'ai_ml': ['OpenAI', 'Anthropic', 'Hugging Face', 'CalcsLive'],
|
||||
'social_media': ['LinkedIn', 'Twitter/X', 'Facebook', 'Instagram'],
|
||||
'ecommerce': ['Shopify', 'Stripe', 'PayPal'],
|
||||
'analytics': ['Google Analytics', 'Mixpanel'],
|
||||
|
||||
Reference in New Issue
Block a user