Initial commit: MCP Hub Community Edition v3.0.0
Community edition generated from private repo via sync pipeline. Includes 9 plugins (WordPress, WooCommerce, WP Advanced, Gitea, n8n, Supabase, OpenPanel, Appwrite, Directus) with ~587 tools. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
259
templates/dashboard/projects/list.html
Normal file
259
templates/dashboard/projects/list.html
Normal file
@@ -0,0 +1,259 @@
|
||||
{% extends "dashboard/base.html" %}
|
||||
|
||||
{% block title %}{{ t.projects }}{% endblock %}
|
||||
{% block page_title %}{{ t.projects }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="space-y-6">
|
||||
<!-- Filters -->
|
||||
<div class="bg-gray-800 rounded-xl border border-gray-700 p-4">
|
||||
<form method="GET" class="flex flex-wrap items-center gap-4">
|
||||
{% if lang and lang != 'en' %}<input type="hidden" name="lang" value="{{ lang }}">{% endif %}
|
||||
<!-- Plugin Type Filter -->
|
||||
<div class="flex items-center gap-2">
|
||||
<label class="text-sm text-gray-400">{{ t.filter }}:</label>
|
||||
<select
|
||||
name="plugin_type"
|
||||
onchange="this.form.submit()"
|
||||
class="px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white text-sm focus:outline-none focus:border-primary-500"
|
||||
>
|
||||
<option value="">{{ t.all }} Types</option>
|
||||
{% for plugin_type in available_plugin_types %}
|
||||
<option value="{{ plugin_type }}" {% if selected_plugin_type == plugin_type %}selected{% endif %}>
|
||||
{{ plugin_type|plugin_name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Status Filter -->
|
||||
<div class="flex items-center gap-2">
|
||||
<select
|
||||
name="status"
|
||||
onchange="this.form.submit()"
|
||||
class="px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white text-sm focus:outline-none focus:border-primary-500"
|
||||
>
|
||||
<option value="">{% if lang == 'fa' %}همه وضعیتها{% else %}All Status{% endif %}</option>
|
||||
<option value="healthy" {% if selected_status == 'healthy' %}selected{% endif %}>{{ t.healthy }}</option>
|
||||
<option value="warning" {% if selected_status == 'warning' %}selected{% endif %}>{% if lang == 'fa' %}هشدار{% else %}Warning{% endif %}</option>
|
||||
<option value="unhealthy" {% if selected_status == 'unhealthy' %}selected{% endif %}>{% if lang == 'fa' %}ناسالم{% else %}Unhealthy{% endif %}</option>
|
||||
<option value="unknown" {% if selected_status == 'unknown' %}selected{% endif %}>{% if lang == 'fa' %}نامشخص{% else %}Unknown{% endif %}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Search -->
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<input
|
||||
type="text"
|
||||
name="search"
|
||||
value="{{ search_query }}"
|
||||
placeholder="{{ t.search }}..."
|
||||
class="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white text-sm placeholder-gray-400 focus:outline-none focus:border-primary-500"
|
||||
>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 rounded-lg text-white text-sm transition-colors">
|
||||
{{ t.search }}
|
||||
</button>
|
||||
|
||||
{% if search_query or selected_plugin_type or selected_status %}
|
||||
<a href="/dashboard/projects{% if lang and lang != 'en' %}?lang={{ lang }}{% endif %}" class="px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded-lg text-white text-sm transition-colors">
|
||||
{{ t['clear'] }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Projects Table -->
|
||||
<div class="bg-gray-800 rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-gray-700/50">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-{% if lang == 'fa' %}right{% else %}left{% endif %} text-sm font-medium text-gray-300">
|
||||
{% if lang == 'fa' %}نوع{% else %}Plugin{% endif %}
|
||||
</th>
|
||||
<th class="px-6 py-4 text-{% if lang == 'fa' %}right{% else %}left{% endif %} text-sm font-medium text-gray-300">
|
||||
{% if lang == 'fa' %}شناسه{% else %}Site ID{% endif %}
|
||||
</th>
|
||||
<th class="px-6 py-4 text-{% if lang == 'fa' %}right{% else %}left{% endif %} text-sm font-medium text-gray-300">
|
||||
{% if lang == 'fa' %}نام مستعار{% else %}Alias{% endif %}
|
||||
</th>
|
||||
<th class="px-6 py-4 text-{% if lang == 'fa' %}right{% else %}left{% endif %} text-sm font-medium text-gray-300">
|
||||
URL
|
||||
</th>
|
||||
<th class="px-6 py-4 text-{% if lang == 'fa' %}right{% else %}left{% endif %} text-sm font-medium text-gray-300">
|
||||
{% if lang == 'fa' %}وضعیت{% else %}Status{% endif %}
|
||||
</th>
|
||||
<th class="px-6 py-4 text-{% if lang == 'fa' %}right{% else %}left{% endif %} text-sm font-medium text-gray-300">
|
||||
{% if lang == 'fa' %}عملیات{% else %}Actions{% endif %}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-700">
|
||||
{% if projects %}
|
||||
{% for project in projects %}
|
||||
<tr class="hover:bg-gray-700/30 transition-colors">
|
||||
<!-- Plugin Type -->
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center">
|
||||
{% set plugin_colors = {
|
||||
'wordpress': 'bg-blue-500',
|
||||
'woocommerce': 'bg-purple-500',
|
||||
'wordpress_advanced': 'bg-indigo-500',
|
||||
'gitea': 'bg-green-500',
|
||||
'n8n': 'bg-orange-500',
|
||||
'supabase': 'bg-emerald-500',
|
||||
'openpanel': 'bg-cyan-500',
|
||||
'appwrite': 'bg-pink-500',
|
||||
'directus': 'bg-violet-500',
|
||||
} %}
|
||||
{% set plugin_icons = {
|
||||
'wordpress': 'W',
|
||||
'woocommerce': 'WC',
|
||||
'wordpress_advanced': 'WA',
|
||||
'gitea': 'G',
|
||||
'n8n': 'n8n',
|
||||
'supabase': 'SB',
|
||||
'openpanel': 'OP',
|
||||
'appwrite': 'AW',
|
||||
'directus': 'DI',
|
||||
} %}
|
||||
<div class="w-8 h-8 {{ plugin_colors.get(project.plugin_type, 'bg-gray-500') }} rounded-lg flex items-center justify-center {% if lang == 'fa' %}ml-3{% else %}mr-3{% endif %}">
|
||||
<span class="text-xs font-bold text-white">{{ plugin_icons.get(project.plugin_type, project.plugin_type[:2]|upper) }}</span>
|
||||
</div>
|
||||
<span class="text-sm text-white">{{ project.plugin_type|plugin_name }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<!-- Site ID -->
|
||||
<td class="px-6 py-4">
|
||||
<span class="text-sm text-gray-300 font-mono">{{ project.site_id }}</span>
|
||||
</td>
|
||||
|
||||
<!-- Alias -->
|
||||
<td class="px-6 py-4">
|
||||
{% if project.alias %}
|
||||
<span class="px-2 py-1 bg-primary-500/20 text-primary-400 text-xs rounded-lg font-medium">
|
||||
{{ project.alias }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="text-gray-500 text-sm">-</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<!-- URL -->
|
||||
<td class="px-6 py-4">
|
||||
{% if project.url %}
|
||||
<a href="{{ project.url }}" target="_blank" class="text-sm text-blue-400 hover:text-blue-300 truncate max-w-[200px] block" title="{{ project.url }}">
|
||||
{{ project.url[:40] }}{% if project.url|length > 40 %}...{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="text-gray-500 text-sm">-</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<!-- Status -->
|
||||
<td class="px-6 py-4">
|
||||
{% if project.health_status == 'healthy' %}
|
||||
<div class="flex items-center">
|
||||
<span class="w-2 h-2 bg-green-500 rounded-full status-pulse {% if lang == 'fa' %}ml-2{% else %}mr-2{% endif %}"></span>
|
||||
<span class="text-sm text-green-400">{{ t.healthy }}</span>
|
||||
</div>
|
||||
{% elif project.health_status == 'warning' %}
|
||||
<div class="flex items-center">
|
||||
<span class="w-2 h-2 bg-yellow-500 rounded-full {% if lang == 'fa' %}ml-2{% else %}mr-2{% endif %}"></span>
|
||||
<span class="text-sm text-yellow-400">{% if lang == 'fa' %}هشدار{% else %}Warning{% endif %}</span>
|
||||
</div>
|
||||
{% elif project.health_status == 'unhealthy' %}
|
||||
<div class="flex items-center">
|
||||
<span class="w-2 h-2 bg-red-500 rounded-full {% if lang == 'fa' %}ml-2{% else %}mr-2{% endif %}"></span>
|
||||
<span class="text-sm text-red-400">{% if lang == 'fa' %}ناسالم{% else %}Unhealthy{% endif %}</span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="flex items-center">
|
||||
<span class="w-2 h-2 bg-gray-500 rounded-full {% if lang == 'fa' %}ml-2{% else %}mr-2{% endif %}"></span>
|
||||
<span class="text-sm text-gray-400">{% if lang == 'fa' %}نامشخص{% else %}Unknown{% endif %}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<!-- Actions -->
|
||||
<td class="px-6 py-4">
|
||||
<a
|
||||
href="/dashboard/projects/{{ project.full_id }}{% if lang and lang != 'en' %}?lang={{ lang }}{% endif %}"
|
||||
class="inline-flex items-center px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded-lg text-sm text-white transition-colors"
|
||||
>
|
||||
{{ t.view }}
|
||||
<svg class="w-4 h-4 {% if lang == 'fa' %}mr-1 rotate-180{% else %}ml-1{% endif %}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="6" class="px-6 py-12 text-center">
|
||||
<svg class="w-12 h-12 mx-auto mb-4 text-gray-500 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/>
|
||||
</svg>
|
||||
<p class="text-gray-400">
|
||||
{% if lang == 'fa' %}پروژهای یافت نشد{% else %}No projects found{% endif %}
|
||||
</p>
|
||||
{% if search_query or selected_plugin_type %}
|
||||
<p class="text-gray-500 text-sm mt-2">
|
||||
{% if lang == 'fa' %}فیلترها را پاک کنید{% else %}Try clearing the filters{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if total_pages > 1 %}
|
||||
<div class="px-6 py-4 border-t border-gray-700 flex items-center justify-between">
|
||||
<p class="text-sm text-gray-400">
|
||||
{% if lang == 'fa' %}
|
||||
نمایش {{ ((page_number - 1) * per_page) + 1 }} تا {{ [page_number * per_page, total_count]|min }} از {{ total_count }} پروژه
|
||||
{% else %}
|
||||
Showing {{ ((page_number - 1) * per_page) + 1 }} to {{ [page_number * per_page, total_count]|min }} of {{ total_count }} projects
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
{% if page_number > 1 %}
|
||||
<a href="?page={{ page_number - 1 }}{% if selected_plugin_type %}&plugin_type={{ selected_plugin_type }}{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if lang and lang != 'en' %}&lang={{ lang }}{% endif %}"
|
||||
class="px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded-lg text-sm text-white transition-colors">
|
||||
{% if lang == 'fa' %}قبلی{% else %}Previous{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% for page_num in range(1, total_pages + 1) %}
|
||||
{% if page_num == page_number %}
|
||||
<span class="px-3 py-1.5 bg-primary-600 rounded-lg text-sm text-white">{{ page_num }}</span>
|
||||
{% elif page_num == 1 or page_num == total_pages or (page_num >= page_number - 2 and page_num <= page_number + 2) %}
|
||||
<a href="?page={{ page_num }}{% if selected_plugin_type %}&plugin_type={{ selected_plugin_type }}{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if lang and lang != 'en' %}&lang={{ lang }}{% endif %}"
|
||||
class="px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded-lg text-sm text-white transition-colors">
|
||||
{{ page_num }}
|
||||
</a>
|
||||
{% elif page_num == page_number - 3 or page_num == page_number + 3 %}
|
||||
<span class="text-gray-500">...</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_number < total_pages %}
|
||||
<a href="?page={{ page_number + 1 }}{% if selected_plugin_type %}&plugin_type={{ selected_plugin_type }}{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if lang and lang != 'en' %}&lang={{ lang }}{% endif %}"
|
||||
class="px-3 py-1.5 bg-gray-700 hover:bg-gray-600 rounded-lg text-sm text-white transition-colors">
|
||||
{% if lang == 'fa' %}بعدی{% else %}Next{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user