last ...
This commit is contained in:
+5
-5
@@ -1,5 +1,5 @@
|
||||
آخرین نسخه تایید شده
|
||||
- در گروه بردها از ابزارها یک گزینه بنام "مدیریت تگ ها" اضافه کن و در صورت انتخاب کاربر مودال مدیریت تگ ها را نمایش بده.
|
||||
- قابلیت فیلتر کارتها بر اساس تگ در مودال بردها اضافه شود.
|
||||
- قابلیت Drag & Drop ستونها و کارتها بین ستونها پیادهسازی شود.
|
||||
- قابلیت جستجوی کارتها در برد فعال اضافه شود.
|
||||
- در بردهای انتشار برای هر کارت باید قابلیت های زیر وجود داشته باشد:
|
||||
1. تاریخچه عملیات انجام شده روی کارت
|
||||
2. نام افرادمسئول که وظیفه به آن ها محول یا مربوط می شود باید دریافت شود
|
||||
3. در صورتیکه کارت هایی از قبل موجود باشند، می توان هر کارت را به یک یا چند کارت مرتبط کرد تا از این طریق وابستگی وظایف رو درک کرد.
|
||||
4. در مودال بردهای انتشار در بخش فیلتر بر اساس تگ ها، امکان حذف فیتر وجود ندارد. نحوه فیلتر بر اساس تگها رو اصلاح کن
|
||||
@@ -0,0 +1,176 @@
|
||||
const projectData = {
|
||||
projectId: "550e8400-e29b-41d4-a716-446655440000",
|
||||
projectName: "xReleaseAssistant",
|
||||
projectTitle: "دستیار انتشار",
|
||||
description: "مدیریت نسخهها و نیازمندیهای محصولات",
|
||||
version: "1.1.0",
|
||||
developer: "هادی خزاعی اصل",
|
||||
company: "رایان پرداز کاوش",
|
||||
metadata: {
|
||||
createdAt: "2026-09-13T00:00:00Z",
|
||||
updatedAt: "2026-09-18T00:00:00Z",
|
||||
tags: ["release-management"],
|
||||
customFields: {},
|
||||
},
|
||||
webhook: { url: "", clientId: "", enabled: false },
|
||||
toolGroups: [
|
||||
{
|
||||
id: "product-management",
|
||||
title: "پرونده",
|
||||
icon: "📁",
|
||||
description: "مدیریت چرخه حیات محصول",
|
||||
tools: [
|
||||
{
|
||||
id: "clear-all",
|
||||
title: "پاکسازی",
|
||||
icon: "🗑️",
|
||||
action: "clearAll",
|
||||
description: "پاکسازی کامل",
|
||||
},
|
||||
{
|
||||
id: "save-product",
|
||||
title: "ذخیره",
|
||||
icon: "💾",
|
||||
action: "saveProduct",
|
||||
description: "دانلود دادهها",
|
||||
},
|
||||
{
|
||||
id: "load-product",
|
||||
title: "بارگذاری",
|
||||
icon: "📂",
|
||||
action: "loadProduct",
|
||||
description: "بارگذاری از فایل",
|
||||
},
|
||||
{
|
||||
id: "product-settings",
|
||||
title: "تنظیمات",
|
||||
icon: "⚙️",
|
||||
action: "openProductSettings",
|
||||
description: "پیکربندی",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "boards",
|
||||
title: "بردها",
|
||||
icon: "📋",
|
||||
description: "مدیریت بردهای انتشار",
|
||||
tools: [
|
||||
{
|
||||
id: "release-boards",
|
||||
title: "بردهای انتشار",
|
||||
icon: "🚀",
|
||||
action: "showReleaseBoards",
|
||||
description: "مشاهده و مدیریت بردهای انتشار",
|
||||
},
|
||||
/* ✅ NEW: ابزار مدیریت تگها */
|
||||
{
|
||||
id: "tag-manager",
|
||||
title: "مدیریت تگها",
|
||||
icon: "🏷️",
|
||||
action: "showTagManager",
|
||||
description: "مدیریت تگهای بردها",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "reports",
|
||||
title: "گزارشها",
|
||||
icon: "📊",
|
||||
description: "تحلیل و گزارشگیری",
|
||||
tools: [
|
||||
{
|
||||
id: "executive-dashboard",
|
||||
title: "داشبورد مدیریتی",
|
||||
icon: "📊",
|
||||
action: "showExecutiveDashboard",
|
||||
description: "نمای کلی با نمودارها",
|
||||
},
|
||||
{
|
||||
id: "dependency-analysis",
|
||||
title: "تحلیل وابستگیها",
|
||||
icon: "🔗",
|
||||
action: "showDependencyAnalysis",
|
||||
description: "تحلیل وابستگیها",
|
||||
},
|
||||
{
|
||||
id: "deployment-analysis",
|
||||
title: "تحلیل استقرار",
|
||||
icon: "🚀",
|
||||
action: "showDeploymentAnalysis",
|
||||
description: "تحلیل استقرارها",
|
||||
},
|
||||
{
|
||||
id: "version-analysis",
|
||||
title: "تحلیل نسخه",
|
||||
icon: "🔢",
|
||||
action: "showVersionAnalysis",
|
||||
description: "تحلیل نسخهها",
|
||||
},
|
||||
{
|
||||
id: "risk-analysis",
|
||||
title: "تحلیل ریسک",
|
||||
icon: "⚠️",
|
||||
action: "showRiskAnalysis",
|
||||
description: "تحلیل ریسکها",
|
||||
},
|
||||
{
|
||||
id: "galaxy-chart",
|
||||
title: "نمودار کهکشانی",
|
||||
icon: "🌌",
|
||||
action: "showGalaxyChart",
|
||||
description: "نمودار کهکشانی",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
appData: {
|
||||
environments: [
|
||||
{
|
||||
id: "env-prod-001",
|
||||
name: "Production",
|
||||
description: "محیط عملیاتی اصلی - در دسترس کاربران نهایی",
|
||||
backgroundColor: "#38a169",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-stage-002",
|
||||
name: "Staging",
|
||||
description: "محیط پیش از تولید - شبیهسازی Production",
|
||||
backgroundColor: "#dd6b20",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-dev-003",
|
||||
name: "Development",
|
||||
description: "محیط توسعه - برای تیم فنی",
|
||||
backgroundColor: "#3182ce",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-qa-004",
|
||||
name: "QA",
|
||||
description: "محیط تست کیفیت - کنترل کیفیت خودکار و دستی",
|
||||
backgroundColor: "#805ad5",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-uat-005",
|
||||
name: "UAT",
|
||||
description: "تست پذیرش کاربر - تأیید کارفرما",
|
||||
backgroundColor: "#d69e2e",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-dr-006",
|
||||
name: "Disaster Recovery",
|
||||
description: "محیط بازیابی پس از بحران - پشتیبان Production",
|
||||
backgroundColor: "#e53e3e",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
],
|
||||
products: [],
|
||||
boards: [],
|
||||
boardTags: [],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
"id": "env-1789757606914",
|
||||
"name": "کاوش - توسعه",
|
||||
"description": "این محیط فقط برای تست عملیاتی توسعه دهندگان است",
|
||||
"backgroundColor": "#3f94ee",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757658261",
|
||||
"name": "کاوش تست",
|
||||
"description": "این محیط برای تست محصول توسط تیم های تضمین کیفیت و تحلیل است",
|
||||
"backgroundColor": "#df3416",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757730121",
|
||||
"name": "کانون - قرمز",
|
||||
"description": "محیطی برای تست محصولات در فضای کانون",
|
||||
"backgroundColor": "#ff0000",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757791901",
|
||||
"name": "کانون - آبی",
|
||||
"description": "محیط انتشار عمومی محصولات در کانون",
|
||||
"backgroundColor": "#0000ff",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757853333",
|
||||
"name": "سازمان - قرمز",
|
||||
"description": "محیطی برای تست محصولات در سازمان",
|
||||
"backgroundColor": "#ff0000",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757900213",
|
||||
"name": "سازمان - آبی",
|
||||
"description": "محیط انتشار عمومی محصولات در سازمان",
|
||||
"backgroundColor": "#0000ff",
|
||||
"textColor": "#ffffff"
|
||||
}
|
||||
],
|
||||
"products": [],
|
||||
"boards": [
|
||||
{
|
||||
"id": "board-1789756462321",
|
||||
"title": "ساماندهی",
|
||||
"description": "مدیریت تسک های مرتبط با محصول ساماندهی",
|
||||
"backgroundColor": "#173154",
|
||||
"createdAt": "2026-09-18T18:34:22.321Z",
|
||||
"updatedAt": "2026-09-18T18:34:59.453Z",
|
||||
"columns": [
|
||||
{
|
||||
"id": "col-1789756462321-0",
|
||||
"title": "📥 بک لاگ",
|
||||
"backgroundColor": "#6b7208",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": [
|
||||
{
|
||||
"id": "card-1789757126382",
|
||||
"title": "پلن توسعه",
|
||||
"description": "بررسی کامل پلن توسعه در راستای نسخه جدید",
|
||||
"estimatedDate": null,
|
||||
"backgroundColor": "#787fe8",
|
||||
"tags": [],
|
||||
"checklist": [],
|
||||
"assignees": [],
|
||||
"dependencies": [],
|
||||
"history": [
|
||||
{
|
||||
"from": "—",
|
||||
"to": "📥 بک لاگ",
|
||||
"date": "2026-09-18T18:45:26.382Z"
|
||||
},
|
||||
{
|
||||
"from": "📥 بک لاگ",
|
||||
"to": "📋 برای انجام",
|
||||
"date": "2026-09-18T18:45:30.580Z"
|
||||
},
|
||||
{
|
||||
"from": "📋 برای انجام",
|
||||
"to": "📥 بک لاگ",
|
||||
"date": "2026-09-18T18:45:32.310Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2026-09-18T18:45:26.382Z",
|
||||
"updatedAt": "2026-09-18T18:45:26.382Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-1",
|
||||
"title": "📋 برای انجام",
|
||||
"backgroundColor": "#393e65",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-2",
|
||||
"title": "🔨 در حال انجام",
|
||||
"backgroundColor": "#453111",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-3",
|
||||
"title": "🔍 برای تست",
|
||||
"backgroundColor": "#542881",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-4",
|
||||
"title": "✅ انجام شده",
|
||||
"backgroundColor": "#087224",
|
||||
"textColor": "#d8d96d",
|
||||
"cards": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "board-1789756537937",
|
||||
"title": "دفترچه ای",
|
||||
"description": "مدیریت وظایف مرتبط با انتشار محصول دفترچه ای",
|
||||
"backgroundColor": "#1e3757",
|
||||
"createdAt": "2026-09-18T18:35:37.937Z",
|
||||
"updatedAt": "2026-09-18T18:35:37.937Z",
|
||||
"columns": [
|
||||
{
|
||||
"id": "col-1789756537937-0",
|
||||
"title": "📥 بک لاگ",
|
||||
"backgroundColor": "#6b7208",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-1",
|
||||
"title": "📋 برای انجام",
|
||||
"backgroundColor": "#393e65",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-2",
|
||||
"title": "🔨 در حال انجام",
|
||||
"backgroundColor": "#453111",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-3",
|
||||
"title": "🔍 برای تست",
|
||||
"backgroundColor": "#542881",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-4",
|
||||
"title": "✅ انجام شده",
|
||||
"backgroundColor": "#087224",
|
||||
"textColor": "#d8d96d",
|
||||
"cards": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"boardTags": [
|
||||
{
|
||||
"id": "tag-1789755845541",
|
||||
"name": "فوری",
|
||||
"color": "#e14141"
|
||||
},
|
||||
{
|
||||
"id": "tag-1789755857090",
|
||||
"name": "حساس",
|
||||
"color": "#e1d741"
|
||||
},
|
||||
{
|
||||
"id": "tag-1789755888873",
|
||||
"name": "عادی",
|
||||
"color": "#4299e1"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
{
|
||||
"environments": [
|
||||
{
|
||||
"id": "env-1789757606914",
|
||||
"name": "کاوش - توسعه",
|
||||
"description": "این محیط فقط برای تست عملیاتی توسعه دهندگان است",
|
||||
"backgroundColor": "#3f94ee",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757658261",
|
||||
"name": "کاوش تست",
|
||||
"description": "این محیط برای تست محصول توسط تیم های تضمین کیفیت و تحلیل است",
|
||||
"backgroundColor": "#df3416",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757730121",
|
||||
"name": "کانون - قرمز",
|
||||
"description": "محیطی برای تست محصولات در فضای کانون",
|
||||
"backgroundColor": "#ff0000",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757791901",
|
||||
"name": "کانون - آبی",
|
||||
"description": "محیط انتشار عمومی محصولات در کانون",
|
||||
"backgroundColor": "#0000ff",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757853333",
|
||||
"name": "سازمان - قرمز",
|
||||
"description": "محیطی برای تست محصولات در سازمان",
|
||||
"backgroundColor": "#ff0000",
|
||||
"textColor": "#ffffff"
|
||||
},
|
||||
{
|
||||
"id": "env-1789757900213",
|
||||
"name": "سازمان - آبی",
|
||||
"description": "محیط انتشار عمومی محصولات در سازمان",
|
||||
"backgroundColor": "#0000ff",
|
||||
"textColor": "#ffffff"
|
||||
}
|
||||
],
|
||||
"products": [
|
||||
{
|
||||
"id": "prod-1789758196583",
|
||||
"title": "زیر ساخت کاوش",
|
||||
"description": "ارائه کلیه زیر ساخت های لازم برای محصولات",
|
||||
"metadata": {
|
||||
"createdAt": "2026-09-18T19:03:16.583Z",
|
||||
"owner": "تیم زیر ساخت",
|
||||
"customFields": {}
|
||||
},
|
||||
"projects": [
|
||||
{
|
||||
"id": "proj-1789758302242",
|
||||
"title": "فریمورک",
|
||||
"description": "نوگت فریمورک که کلیه زیر ساخت های لازم برای پروژه ها را ارائه می دهد.",
|
||||
"type": "infrastructure",
|
||||
"repositoryUrl": "",
|
||||
"metadata": {
|
||||
"createdAt": "2026-09-18T19:05:02.242Z",
|
||||
"customFields": {},
|
||||
"framework": ".net",
|
||||
"language": "C#"
|
||||
},
|
||||
"dependencies": [],
|
||||
"deployments": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "prod-1789759034126",
|
||||
"title": "ساماندهی",
|
||||
"description": "فرآیندهی ساماندهی",
|
||||
"metadata": {
|
||||
"createdAt": "2026-09-18T19:17:14.126Z",
|
||||
"owner": "تیم املاک",
|
||||
"customFields": {}
|
||||
},
|
||||
"projects": [
|
||||
{
|
||||
"id": "proj-1789759100918",
|
||||
"title": "Rem13 Dotnet Bo",
|
||||
"description": "سرویس های ساماندهی در بک آفیس",
|
||||
"type": "backend",
|
||||
"repositoryUrl": "",
|
||||
"metadata": {
|
||||
"createdAt": "2026-09-18T19:18:20.918Z",
|
||||
"customFields": {},
|
||||
"framework": ".net",
|
||||
"language": "C#"
|
||||
},
|
||||
"dependencies": [
|
||||
"proj-1789758302242"
|
||||
],
|
||||
"deployments": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"boards": [
|
||||
{
|
||||
"id": "board-1789756462321",
|
||||
"title": "ساماندهی",
|
||||
"description": "مدیریت تسک های مرتبط با محصول ساماندهی",
|
||||
"backgroundColor": "#173154",
|
||||
"createdAt": "2026-09-18T18:34:22.321Z",
|
||||
"updatedAt": "2026-09-18T18:34:59.453Z",
|
||||
"columns": [
|
||||
{
|
||||
"id": "col-1789756462321-0",
|
||||
"title": "📥 بک لاگ",
|
||||
"backgroundColor": "#6b7208",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": [
|
||||
{
|
||||
"id": "card-1789757126382",
|
||||
"title": "پلن توسعه",
|
||||
"description": "بررسی کامل پلن توسعه در راستای نسخه جدید",
|
||||
"estimatedDate": null,
|
||||
"backgroundColor": "#787fe8",
|
||||
"tags": [],
|
||||
"checklist": [],
|
||||
"assignees": [],
|
||||
"dependencies": [],
|
||||
"history": [
|
||||
{
|
||||
"from": "—",
|
||||
"to": "📥 بک لاگ",
|
||||
"date": "2026-09-18T18:45:26.382Z"
|
||||
},
|
||||
{
|
||||
"from": "📥 بک لاگ",
|
||||
"to": "📋 برای انجام",
|
||||
"date": "2026-09-18T18:45:30.580Z"
|
||||
},
|
||||
{
|
||||
"from": "📋 برای انجام",
|
||||
"to": "📥 بک لاگ",
|
||||
"date": "2026-09-18T18:45:32.310Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2026-09-18T18:45:26.382Z",
|
||||
"updatedAt": "2026-09-18T18:45:26.382Z"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-1",
|
||||
"title": "📋 برای انجام",
|
||||
"backgroundColor": "#393e65",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-2",
|
||||
"title": "🔨 در حال انجام",
|
||||
"backgroundColor": "#453111",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-3",
|
||||
"title": "🔍 برای تست",
|
||||
"backgroundColor": "#542881",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756462321-4",
|
||||
"title": "✅ انجام شده",
|
||||
"backgroundColor": "#087224",
|
||||
"textColor": "#d8d96d",
|
||||
"cards": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "board-1789756537937",
|
||||
"title": "دفترچه ای",
|
||||
"description": "مدیریت وظایف مرتبط با انتشار محصول دفترچه ای",
|
||||
"backgroundColor": "#1e3757",
|
||||
"createdAt": "2026-09-18T18:35:37.937Z",
|
||||
"updatedAt": "2026-09-18T18:35:37.937Z",
|
||||
"columns": [
|
||||
{
|
||||
"id": "col-1789756537937-0",
|
||||
"title": "📥 بک لاگ",
|
||||
"backgroundColor": "#6b7208",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-1",
|
||||
"title": "📋 برای انجام",
|
||||
"backgroundColor": "#393e65",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-2",
|
||||
"title": "🔨 در حال انجام",
|
||||
"backgroundColor": "#453111",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-3",
|
||||
"title": "🔍 برای تست",
|
||||
"backgroundColor": "#542881",
|
||||
"textColor": "#b4cbf9",
|
||||
"cards": []
|
||||
},
|
||||
{
|
||||
"id": "col-1789756537937-4",
|
||||
"title": "✅ انجام شده",
|
||||
"backgroundColor": "#087224",
|
||||
"textColor": "#d8d96d",
|
||||
"cards": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"boardTags": [
|
||||
{
|
||||
"id": "tag-1789755845541",
|
||||
"name": "فوری",
|
||||
"color": "#e14141"
|
||||
},
|
||||
{
|
||||
"id": "tag-1789755857090",
|
||||
"name": "حساس",
|
||||
"color": "#e1d741"
|
||||
},
|
||||
{
|
||||
"id": "tag-1789755888873",
|
||||
"name": "عادی",
|
||||
"color": "#4299e1"
|
||||
}
|
||||
]
|
||||
}
|
||||
+32
-318
@@ -1730,7 +1730,6 @@
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
margin: 0 4px;
|
||||
}
|
||||
/* ✅ NEW: استایل جستجو و فیلتر در نوار ابزار بردها */
|
||||
.rb-search-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -1787,7 +1786,6 @@
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
/* ✅ NEW: نوار فیلتر تگها */
|
||||
.rb-tag-filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -2428,9 +2426,6 @@
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: استایلهای Drag & Drop و فیلتر
|
||||
═══════════════════════════════════════════════════ */
|
||||
.card.hidden-by-filter {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -2815,7 +2810,7 @@
|
||||
</div>
|
||||
<div class="modal-body" id="projectDetailBody"></div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-danger btn-sm" id="projectDetailDeleteBtn">
|
||||
<button class="btn btn-danger" id="projectDetailDeleteBtn">
|
||||
🗑️ حذف محصول</button
|
||||
><button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
</div>
|
||||
@@ -3205,9 +3200,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">📊 داشبورد مدیریتی</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="dashboardRefresh">
|
||||
🔄 بهروزرسانی
|
||||
</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3227,7 +3219,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">🔗 تحلیل وابستگیها</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="depAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3250,7 +3241,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">🚀 تحلیل استقرار</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="deployAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3276,7 +3266,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">🔢 تحلیل نسخه</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="verAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3296,7 +3285,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">⚠️ تحلیل ریسک</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="riskAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3329,7 +3317,6 @@
|
||||
🏷️ تگها
|
||||
</button>
|
||||
<div class="rb-toolbar-separator"></div>
|
||||
<!-- ✅ NEW: جستجوی کارتها -->
|
||||
<div class="rb-search-box">
|
||||
<span style="opacity: 0.7; font-size: 12px">🔍</span>
|
||||
<input
|
||||
@@ -3353,13 +3340,12 @@
|
||||
>
|
||||
<div class="rb-toolbar-separator"></div>
|
||||
<button class="btn" id="rbUndoBtn" title="بازگشت (Ctrl+Z)" disabled>
|
||||
↩️ بازگشت
|
||||
↩️
|
||||
</button>
|
||||
<button class="btn" id="rbRedoBtn" title="از نو (Ctrl+Y)" disabled>
|
||||
↪️ از نو
|
||||
↪️
|
||||
</button>
|
||||
</div>
|
||||
<!-- ✅ NEW: نوار فیلتر تگها -->
|
||||
<div class="rb-tag-filter-bar" id="rbTagFilterBar">
|
||||
<span class="rb-tag-filter-label">🏷️ فیلتر تگ:</span>
|
||||
<div
|
||||
@@ -3413,8 +3399,8 @@
|
||||
</div>
|
||||
<!-- Footer -->
|
||||
<div class="modal-footer">
|
||||
<div class="dashboard-footer-stats" id="rbFooterStats"></div>
|
||||
<button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
<div class="dashboard-footer-stats" id="rbFooterStats"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3480,31 +3466,31 @@
|
||||
>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #edf2f7; color: #1a202c"
|
||||
style="background: #6b7208; color: #b4cbf9"
|
||||
>
|
||||
📥 بک لاگ
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #ebf8ff; color: #1a202c"
|
||||
style="background: #393e65; color: #b4cbf9"
|
||||
>
|
||||
📋 برای انجام
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #fef5e7; color: #1a202c"
|
||||
style="background: #453111; color: #b4cbf9"
|
||||
>
|
||||
🔨 در حال انجام
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #faf5ff; color: #1a202c"
|
||||
style="background: #542881; color: #b4cbf9"
|
||||
>
|
||||
🔍 برای تست
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #f0fff4; color: #1a202c"
|
||||
style="background: #087224; color: #d8d96d"
|
||||
>
|
||||
✅ انجام شده
|
||||
</div>
|
||||
@@ -3721,10 +3707,10 @@
|
||||
<div class="rb-tag-list" id="rbTagList"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
<div style="font-size: 11px; color: var(--text-muted)">
|
||||
💡 تغییرات تگها به صورت خودکار در تمام کارتها اعمال میشود
|
||||
</div>
|
||||
<button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3790,177 +3776,21 @@
|
||||
<div class="modal-title">💾 بازیابی خودکار دادهها</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div style="text-align: center; padding: 24px 16px">
|
||||
<div style="font-size: 48px; margin-bottom: 16px">💾</div>
|
||||
<div
|
||||
style="
|
||||
background: linear-gradient(to left, #ebf8ff, #e6f6ff);
|
||||
border: 1px solid #90cdf4;
|
||||
border-right: 4px solid var(--info);
|
||||
padding: 14px 18px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
color: var(--primary);
|
||||
"
|
||||
>
|
||||
⚠️ داده ذخیرهشده خودکار یافت شد
|
||||
</div>
|
||||
<div style="color: var(--text-muted)">
|
||||
به نظر میرسد در جلسه قبلی، تغییراتی در برنامه اعمال شده و به صورت
|
||||
خودکار ذخیره شدهاند.
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
"
|
||||
>
|
||||
📅 تاریخ ذخیره:
|
||||
<strong id="rbAutosaveDate" style="color: var(--primary)"
|
||||
>—</strong
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background: var(--border-light);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin-bottom: 16px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
color: var(--primary);
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
"
|
||||
>
|
||||
📊 محتویات دادههای ذخیرهشده:
|
||||
دادههایی در حافظه موقت وجود دارند
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🌍 محیطها:</span
|
||||
><strong id="rbAutosaveEnvCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
<div style="font-size: 12px; color: var(--text-muted)">
|
||||
آیا مایل به بازیابی آنها هستید؟
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>📦 محصولات:</span
|
||||
><strong id="rbAutosaveProdCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🌿 پروژهها:</span
|
||||
><strong id="rbAutosaveProjCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🚀 استقرارها:</span
|
||||
><strong id="rbAutosaveDepCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>📋 بردها:</span
|
||||
><strong id="rbAutosaveBoardCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🏷️ تگهای برد:</span
|
||||
><strong id="rbAutosaveTagCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size: 13px; color: var(--text); line-height: 1.8">
|
||||
آیا میخواهید این دادهها را بازیابی کنید؟
|
||||
<ul
|
||||
style="
|
||||
margin-top: 8px;
|
||||
padding-right: 20px;
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
"
|
||||
>
|
||||
<li>
|
||||
<strong>بازیابی:</strong> تمام دادههای ذخیرهشده جایگزین
|
||||
دادههای فعلی میشوند
|
||||
</li>
|
||||
<li>
|
||||
<strong>نادیده گرفتن:</strong> دادههای خودکار حذف شده و
|
||||
دادههای فعلی حفظ میشوند
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="justify-content: space-between">
|
||||
@@ -4031,7 +3861,7 @@
|
||||
projectName: "xReleaseAssistant",
|
||||
projectTitle: "دستیار انتشار",
|
||||
description: "مدیریت نسخهها و نیازمندیهای محصولات",
|
||||
version: "1.2.0",
|
||||
version: "1.1.0",
|
||||
developer: "هادی خزاعی اصل",
|
||||
company: "رایان پرداز کاوش",
|
||||
metadata: {
|
||||
@@ -4091,7 +3921,6 @@
|
||||
action: "showReleaseBoards",
|
||||
description: "مشاهده و مدیریت بردهای انتشار",
|
||||
},
|
||||
/* ✅ NEW: ابزار مدیریت تگها */
|
||||
{
|
||||
id: "tag-manager",
|
||||
title: "مدیریت تگها",
|
||||
@@ -4153,50 +3982,7 @@
|
||||
},
|
||||
],
|
||||
appData: {
|
||||
environments: [
|
||||
{
|
||||
id: "env-prod-001",
|
||||
name: "Production",
|
||||
description: "محیط عملیاتی اصلی - در دسترس کاربران نهایی",
|
||||
backgroundColor: "#38a169",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-stage-002",
|
||||
name: "Staging",
|
||||
description: "محیط پیش از تولید - شبیهسازی Production",
|
||||
backgroundColor: "#dd6b20",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-dev-003",
|
||||
name: "Development",
|
||||
description: "محیط توسعه - برای تیم فنی",
|
||||
backgroundColor: "#3182ce",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-qa-004",
|
||||
name: "QA",
|
||||
description: "محیط تست کیفیت - کنترل کیفیت خودکار و دستی",
|
||||
backgroundColor: "#805ad5",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-uat-005",
|
||||
name: "UAT",
|
||||
description: "تست پذیرش کاربر - تأیید کارفرما",
|
||||
backgroundColor: "#d69e2e",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-dr-006",
|
||||
name: "Disaster Recovery",
|
||||
description: "محیط بازیابی پس از بحران - پشتیبان Production",
|
||||
backgroundColor: "#e53e3e",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
],
|
||||
environments: [],
|
||||
products: [],
|
||||
boards: [],
|
||||
boardTags: [],
|
||||
@@ -4546,7 +4332,7 @@
|
||||
getSectionHTML() {
|
||||
const d = this.getData();
|
||||
let h = `<div class="board-section" id="section-dashboard">`;
|
||||
h += `<div class="board-header"><div class="board-header-title"><span class="collapse-icon">▼</span>📊 داشبورد مدیریتی</div><div class="board-header-actions"><button class="btn btn-accent btn-sm" onclick="DashboardManager.open()">📊 مشاهده کامل</button></div></div>`;
|
||||
h += `<div class="board-header"><div class="board-header-title"><span class="collapse-icon">▼</span>📊 داشبورد مدیریتی</div><div class="board-header-actions"><button class="btn btn-accent" onclick="DashboardManager.open()">📊 مشاهده کامل</button></div></div>`;
|
||||
h += `<div class="section-content">`;
|
||||
h += '<div class="dashboard-kpi-row" style="margin-bottom:16px">';
|
||||
h += `<div class="dashboard-kpi-card"><div class="dashboard-kpi-icon">📦</div><div class="dashboard-kpi-value">${d.products}</div><div class="dashboard-kpi-label">محصول</div></div>`;
|
||||
@@ -4972,7 +4758,6 @@
|
||||
showReleaseBoards() {
|
||||
ReleaseBoardsManager.open();
|
||||
},
|
||||
/* ✅ NEW: اکشن مدیریت تگها */
|
||||
showTagManager() {
|
||||
ReleaseBoardsManager.openTagManager();
|
||||
},
|
||||
@@ -5969,8 +5754,6 @@
|
||||
: 0;
|
||||
document.getElementById("dashboardFooterStats").innerHTML =
|
||||
`<span>📦 محصولات: <span class="stat-highlight">${d.products}</span></span><span>🌿 پروژهها: <span class="stat-highlight">${d.projects}</span></span><span>🚀 استقرارها: <span class="stat-highlight">${d.deploys}</span></span><span>📈 پوشش استقرار: <span class="stat-highlight">${coverage}%</span></span>`;
|
||||
document.getElementById("dashboardRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderDonut(cid, data) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -6724,53 +6507,12 @@
|
||||
checkRecovery() {
|
||||
const saved = this.load();
|
||||
if (!saved || !saved.appData) return;
|
||||
const appData = saved.appData;
|
||||
const stats = {
|
||||
environments: (appData.environments || []).length,
|
||||
products: (appData.products || []).length,
|
||||
projects: 0,
|
||||
deployments: 0,
|
||||
boards: (appData.boards || []).length,
|
||||
boardTags: (appData.boardTags || []).length,
|
||||
};
|
||||
(appData.products || []).forEach((prod) => {
|
||||
stats.projects += (prod.projects || []).length;
|
||||
(prod.projects || []).forEach((pr) => {
|
||||
stats.deployments += (pr.deployments || []).filter(
|
||||
(d) => d.status === "active",
|
||||
).length;
|
||||
});
|
||||
});
|
||||
const dateEl = document.getElementById("rbAutosaveDate");
|
||||
const envCountEl = document.getElementById("rbAutosaveEnvCount");
|
||||
const prodCountEl = document.getElementById("rbAutosaveProdCount");
|
||||
const projCountEl = document.getElementById("rbAutosaveProjCount");
|
||||
const depCountEl = document.getElementById("rbAutosaveDepCount");
|
||||
const boardCountEl = document.getElementById("rbAutosaveBoardCount");
|
||||
if (dateEl) {
|
||||
const d = new Date(saved.savedAt);
|
||||
dateEl.textContent =
|
||||
d.toLocaleDateString("fa-IR") +
|
||||
" - " +
|
||||
d.toLocaleTimeString("fa-IR", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
}
|
||||
if (envCountEl)
|
||||
envCountEl.textContent = stats.environments.toLocaleString("fa-IR");
|
||||
if (prodCountEl)
|
||||
prodCountEl.textContent = stats.products.toLocaleString("fa-IR");
|
||||
if (projCountEl)
|
||||
projCountEl.textContent = stats.projects.toLocaleString("fa-IR");
|
||||
if (depCountEl)
|
||||
depCountEl.textContent = stats.deployments.toLocaleString("fa-IR");
|
||||
if (boardCountEl)
|
||||
boardCountEl.textContent = stats.boards.toLocaleString("fa-IR");
|
||||
|
||||
document.getElementById("rbRecoverAutosaveBtn").onclick = () =>
|
||||
this.recover();
|
||||
document.getElementById("rbDiscardAutosaveBtn").onclick = () =>
|
||||
this.discard();
|
||||
|
||||
setTimeout(() => {
|
||||
ModalManager.open("rbAutosaveModal");
|
||||
}, 600);
|
||||
@@ -6825,28 +6567,28 @@
|
||||
DEFAULT_COLUMNS: [
|
||||
{
|
||||
title: "📥 بک لاگ",
|
||||
backgroundColor: "#edf2f7",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#6b7208",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "📋 برای انجام",
|
||||
backgroundColor: "#ebf8ff",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#393e65",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "🔨 در حال انجام",
|
||||
backgroundColor: "#fef5e7",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#453111",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "🔍 برای تست",
|
||||
backgroundColor: "#faf5ff",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#542881",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "✅ انجام شده",
|
||||
backgroundColor: "#f0fff4",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#087224",
|
||||
textColor: "#d8d96d",
|
||||
},
|
||||
],
|
||||
open() {
|
||||
@@ -6897,7 +6639,6 @@
|
||||
} else {
|
||||
this._incrementalRender(board);
|
||||
}
|
||||
/* ✅ NEW: اعمال فیلترها و اتصال درگ پس از رندر */
|
||||
this.applyFilters();
|
||||
this.initDragAndDrop();
|
||||
this.updateFooterStats();
|
||||
@@ -7098,9 +6839,6 @@ ${checklistTotal > 0 ? `<span class="card-meta-item">✅ ${checklistDone}/${chec
|
||||
${checklistHtml}
|
||||
</div>`;
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: فیلتر تگها
|
||||
═══════════════════════════════════════════════════ */
|
||||
renderFilterBar() {
|
||||
const container = document.getElementById("rbTagFilterContainer");
|
||||
const clearBtn = document.getElementById("rbClearTagFilter");
|
||||
@@ -7138,9 +6876,6 @@ ${checklistHtml}
|
||||
};
|
||||
}
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: اعمال فیلتر و جستجو
|
||||
═══════════════════════════════════════════════════ */
|
||||
applyFilters() {
|
||||
const board = this.getActiveBoard();
|
||||
if (!board) return;
|
||||
@@ -7224,9 +6959,6 @@ ${checklistHtml}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: رویدادهای جستجو
|
||||
═══════════════════════════════════════════════════ */
|
||||
bindSearchEvents() {
|
||||
const inp = document.getElementById("rbCardSearchInput");
|
||||
const clr = document.getElementById("rbCardSearchClear");
|
||||
@@ -7253,9 +6985,6 @@ ${checklistHtml}
|
||||
inp.focus();
|
||||
};
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: Drag & Drop
|
||||
═══════════════════════════════════════════════════ */
|
||||
initDragAndDrop() {
|
||||
const wrapper = document.getElementById("rbBoardWrapper");
|
||||
if (!wrapper) return;
|
||||
@@ -7350,7 +7079,6 @@ ${checklistHtml}
|
||||
.querySelectorAll(".drag-over-column")
|
||||
.forEach((el) => el.classList.remove("drag-over-column"));
|
||||
},
|
||||
/* ── جابجایی کارت بین ستونها ── */
|
||||
moveCard(cardId, targetColumnId) {
|
||||
const board = this.getActiveBoard();
|
||||
if (!board) return;
|
||||
@@ -7387,7 +7115,6 @@ ${checklistHtml}
|
||||
2000,
|
||||
);
|
||||
},
|
||||
/* ── جابجایی ستونها ── */
|
||||
moveColumn(sourceColId, targetColId) {
|
||||
const board = this.getActiveBoard();
|
||||
if (!board) return;
|
||||
@@ -7406,7 +7133,6 @@ ${checklistHtml}
|
||||
this.render(true);
|
||||
showToast("📊 ستون جابجا شد", "success", 2000);
|
||||
},
|
||||
/* ── مدیریت برد ── */
|
||||
getActiveBoard() {
|
||||
return (projectData.appData.boards || []).find(
|
||||
(b) => b.id === this.activeBoardId,
|
||||
@@ -7525,7 +7251,6 @@ ${checklistHtml}
|
||||
showToast("برد حذف شد", "warning");
|
||||
this.render(true);
|
||||
},
|
||||
/* ── مدیریت ستون ── */
|
||||
openNewColumnModal() {
|
||||
if (!this.getActiveBoard()) {
|
||||
showToast("ابتدا یک برد ایجاد کنید", "warning");
|
||||
@@ -7600,7 +7325,6 @@ ${checklistHtml}
|
||||
showToast("ستون حذف شد", "warning");
|
||||
this.render(true);
|
||||
},
|
||||
/* ── مدیریت کارت ── */
|
||||
openNewCardModal(columnId) {
|
||||
this.editing.cardId = null;
|
||||
this.editing.columnForCard = columnId;
|
||||
@@ -7818,7 +7542,6 @@ ${checklistHtml}
|
||||
document.getElementById("rbDeleteCardBtn").onclick = () =>
|
||||
this.deleteCard();
|
||||
},
|
||||
/* ── Toolbar Events ── */
|
||||
bindToolbarEvents() {
|
||||
document.getElementById("rbEditBoard").onclick = () =>
|
||||
this.openEditBoardModal();
|
||||
@@ -7852,7 +7575,6 @@ ${checklistHtml}
|
||||
document.getElementById("rbFooterStats").innerHTML =
|
||||
`<span>📋 بردها: <span class="stat-highlight">${boards.length}</span></span><span>📑 ستونها: <span class="stat-highlight">${boards.reduce((s, b) => s + b.columns.length, 0)}</span></span><span>📝 کارتها: <span class="stat-highlight">${totalCards}</span></span>`;
|
||||
},
|
||||
/* ── Tag Manager ── */
|
||||
openTagManager() {
|
||||
ModalManager.open("rbTagManagerModal");
|
||||
this.renderTagList();
|
||||
@@ -8089,8 +7811,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("depRiskList", d);
|
||||
document.getElementById("depAnalysisFooterStats").innerHTML =
|
||||
`<span>🔗 کل: <span class="stat-highlight">${d.totalDeps}</span></span><span>⚠️ گلوگاه: <span class="stat-highlight">${d.bottlenecks.length}</span></span><span>🔴 شکسته: <span class="stat-highlight">${d.brokenDeps}</span></span><span>🔵 ایزوله: <span class="stat-highlight">${d.isolated.length}</span></span>`;
|
||||
document.getElementById("depAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderHubChart(cid, bottlenecks) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -8463,8 +8183,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("deployRiskList", d.riskList);
|
||||
document.getElementById("deployAnalysisFooterStats").innerHTML =
|
||||
`<span>🚀 کل: <span class="stat-highlight">${d.total}</span></span><span>📈 پوشش: <span class="stat-highlight">${d.coverage}%</span></span><span>⚠️ ریسکها: <span class="stat-highlight">${d.riskList.length}</span></span>`;
|
||||
document.getElementById("deployAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderEnvBarChart(cid, edc) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -8888,8 +8606,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("verRiskList", d.riskList);
|
||||
document.getElementById("verAnalysisFooterStats").innerHTML =
|
||||
`<span>🔢 کل: <span class="stat-highlight">${d.total}</span></span><span>📦 یکتا: <span class="stat-highlight">${d.uniqueVersions}</span></span><span>📈 میانگین: <span class="stat-highlight">${d.avgVersion}</span></span><span>⚠️ ریسکها: <span class="stat-highlight">${d.riskList.length}</span></span>`;
|
||||
document.getElementById("verAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderMajorBarChart(cid, majorCounts) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -9274,8 +8990,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("riskDetailList", d.risks);
|
||||
document.getElementById("riskAnalysisFooterStats").innerHTML =
|
||||
`<span>🎯 سلامت: <span class="stat-highlight">${d.healthScore}%</span></span><span>⚠️ ریسکها: <span class="stat-highlight">${d.total}</span></span><span>🔴 بحرانی: <span class="stat-highlight">${d.crit}</span></span><span>🟠 بالا: <span class="stat-highlight">${d.high}</span></span>`;
|
||||
document.getElementById("riskAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderSeverityDonut(cid, d) {
|
||||
const c = document.getElementById(cid);
|
||||
|
||||
+32
-318
@@ -1730,7 +1730,6 @@
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
margin: 0 4px;
|
||||
}
|
||||
/* ✅ NEW: استایل جستجو و فیلتر در نوار ابزار بردها */
|
||||
.rb-search-box {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -1787,7 +1786,6 @@
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
/* ✅ NEW: نوار فیلتر تگها */
|
||||
.rb-tag-filter-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -2428,9 +2426,6 @@
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: استایلهای Drag & Drop و فیلتر
|
||||
═══════════════════════════════════════════════════ */
|
||||
.card.hidden-by-filter {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -2815,7 +2810,7 @@
|
||||
</div>
|
||||
<div class="modal-body" id="projectDetailBody"></div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-danger btn-sm" id="projectDetailDeleteBtn">
|
||||
<button class="btn btn-danger" id="projectDetailDeleteBtn">
|
||||
🗑️ حذف محصول</button
|
||||
><button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
</div>
|
||||
@@ -3205,9 +3200,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">📊 داشبورد مدیریتی</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="dashboardRefresh">
|
||||
🔄 بهروزرسانی
|
||||
</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3227,7 +3219,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">🔗 تحلیل وابستگیها</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="depAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3250,7 +3241,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">🚀 تحلیل استقرار</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="deployAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3276,7 +3266,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">🔢 تحلیل نسخه</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="verAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3296,7 +3285,6 @@
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">⚠️ تحلیل ریسک</div>
|
||||
<div class="galaxy-toolbar">
|
||||
<button class="btn btn-sm" id="riskAnalysisRefresh">🔄</button>
|
||||
</div>
|
||||
<button class="modal-close" data-close-modal>✕</button>
|
||||
</div>
|
||||
@@ -3329,7 +3317,6 @@
|
||||
🏷️ تگها
|
||||
</button>
|
||||
<div class="rb-toolbar-separator"></div>
|
||||
<!-- ✅ NEW: جستجوی کارتها -->
|
||||
<div class="rb-search-box">
|
||||
<span style="opacity: 0.7; font-size: 12px">🔍</span>
|
||||
<input
|
||||
@@ -3353,13 +3340,12 @@
|
||||
>
|
||||
<div class="rb-toolbar-separator"></div>
|
||||
<button class="btn" id="rbUndoBtn" title="بازگشت (Ctrl+Z)" disabled>
|
||||
↩️ بازگشت
|
||||
↩️
|
||||
</button>
|
||||
<button class="btn" id="rbRedoBtn" title="از نو (Ctrl+Y)" disabled>
|
||||
↪️ از نو
|
||||
↪️
|
||||
</button>
|
||||
</div>
|
||||
<!-- ✅ NEW: نوار فیلتر تگها -->
|
||||
<div class="rb-tag-filter-bar" id="rbTagFilterBar">
|
||||
<span class="rb-tag-filter-label">🏷️ فیلتر تگ:</span>
|
||||
<div
|
||||
@@ -3413,8 +3399,8 @@
|
||||
</div>
|
||||
<!-- Footer -->
|
||||
<div class="modal-footer">
|
||||
<div class="dashboard-footer-stats" id="rbFooterStats"></div>
|
||||
<button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
<div class="dashboard-footer-stats" id="rbFooterStats"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3480,31 +3466,31 @@
|
||||
>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #edf2f7; color: #1a202c"
|
||||
style="background: #6b7208; color: #b4cbf9"
|
||||
>
|
||||
📥 بک لاگ
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #ebf8ff; color: #1a202c"
|
||||
style="background: #393e65; color: #b4cbf9"
|
||||
>
|
||||
📋 برای انجام
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #fef5e7; color: #1a202c"
|
||||
style="background: #453111; color: #b4cbf9"
|
||||
>
|
||||
🔨 در حال انجام
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #faf5ff; color: #1a202c"
|
||||
style="background: #542881; color: #b4cbf9"
|
||||
>
|
||||
🔍 برای تست
|
||||
</div>
|
||||
<div
|
||||
class="rb-preview-column"
|
||||
style="background: #f0fff4; color: #1a202c"
|
||||
style="background: #087224; color: #d8d96d"
|
||||
>
|
||||
✅ انجام شده
|
||||
</div>
|
||||
@@ -3721,10 +3707,10 @@
|
||||
<div class="rb-tag-list" id="rbTagList"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
<div style="font-size: 11px; color: var(--text-muted)">
|
||||
💡 تغییرات تگها به صورت خودکار در تمام کارتها اعمال میشود
|
||||
</div>
|
||||
<button class="btn btn-ghost" data-close-modal>بستن</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3790,177 +3776,21 @@
|
||||
<div class="modal-title">💾 بازیابی خودکار دادهها</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div style="text-align: center; padding: 24px 16px">
|
||||
<div style="font-size: 48px; margin-bottom: 16px">💾</div>
|
||||
<div
|
||||
style="
|
||||
background: linear-gradient(to left, #ebf8ff, #e6f6ff);
|
||||
border: 1px solid #90cdf4;
|
||||
border-right: 4px solid var(--info);
|
||||
padding: 14px 18px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 13px;
|
||||
line-height: 1.8;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
color: var(--primary);
|
||||
"
|
||||
>
|
||||
⚠️ داده ذخیرهشده خودکار یافت شد
|
||||
</div>
|
||||
<div style="color: var(--text-muted)">
|
||||
به نظر میرسد در جلسه قبلی، تغییراتی در برنامه اعمال شده و به صورت
|
||||
خودکار ذخیره شدهاند.
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
"
|
||||
>
|
||||
📅 تاریخ ذخیره:
|
||||
<strong id="rbAutosaveDate" style="color: var(--primary)"
|
||||
>—</strong
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
background: var(--border-light);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin-bottom: 16px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
font-weight: 700;
|
||||
font-size: 13px;
|
||||
margin-bottom: 10px;
|
||||
color: var(--primary);
|
||||
color: var(--text);
|
||||
margin-bottom: 8px;
|
||||
"
|
||||
>
|
||||
📊 محتویات دادههای ذخیرهشده:
|
||||
دادههایی در حافظه موقت وجود دارند
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🌍 محیطها:</span
|
||||
><strong id="rbAutosaveEnvCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
<div style="font-size: 12px; color: var(--text-muted)">
|
||||
آیا مایل به بازیابی آنها هستید؟
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>📦 محصولات:</span
|
||||
><strong id="rbAutosaveProdCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🌿 پروژهها:</span
|
||||
><strong id="rbAutosaveProjCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🚀 استقرارها:</span
|
||||
><strong id="rbAutosaveDepCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>📋 بردها:</span
|
||||
><strong id="rbAutosaveBoardCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 10px;
|
||||
background: var(--card-bg);
|
||||
border-radius: 6px;
|
||||
"
|
||||
>
|
||||
<span>🏷️ تگهای برد:</span
|
||||
><strong id="rbAutosaveTagCount" style="color: var(--primary)"
|
||||
>0</strong
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="font-size: 13px; color: var(--text); line-height: 1.8">
|
||||
آیا میخواهید این دادهها را بازیابی کنید؟
|
||||
<ul
|
||||
style="
|
||||
margin-top: 8px;
|
||||
padding-right: 20px;
|
||||
color: var(--text-muted);
|
||||
font-size: 12px;
|
||||
"
|
||||
>
|
||||
<li>
|
||||
<strong>بازیابی:</strong> تمام دادههای ذخیرهشده جایگزین
|
||||
دادههای فعلی میشوند
|
||||
</li>
|
||||
<li>
|
||||
<strong>نادیده گرفتن:</strong> دادههای خودکار حذف شده و
|
||||
دادههای فعلی حفظ میشوند
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="justify-content: space-between">
|
||||
@@ -4031,7 +3861,7 @@
|
||||
projectName: "xReleaseAssistant",
|
||||
projectTitle: "دستیار انتشار",
|
||||
description: "مدیریت نسخهها و نیازمندیهای محصولات",
|
||||
version: "1.2.0",
|
||||
version: "1.1.0",
|
||||
developer: "هادی خزاعی اصل",
|
||||
company: "رایان پرداز کاوش",
|
||||
metadata: {
|
||||
@@ -4091,7 +3921,6 @@
|
||||
action: "showReleaseBoards",
|
||||
description: "مشاهده و مدیریت بردهای انتشار",
|
||||
},
|
||||
/* ✅ NEW: ابزار مدیریت تگها */
|
||||
{
|
||||
id: "tag-manager",
|
||||
title: "مدیریت تگها",
|
||||
@@ -4153,50 +3982,7 @@
|
||||
},
|
||||
],
|
||||
appData: {
|
||||
environments: [
|
||||
{
|
||||
id: "env-prod-001",
|
||||
name: "Production",
|
||||
description: "محیط عملیاتی اصلی - در دسترس کاربران نهایی",
|
||||
backgroundColor: "#38a169",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-stage-002",
|
||||
name: "Staging",
|
||||
description: "محیط پیش از تولید - شبیهسازی Production",
|
||||
backgroundColor: "#dd6b20",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-dev-003",
|
||||
name: "Development",
|
||||
description: "محیط توسعه - برای تیم فنی",
|
||||
backgroundColor: "#3182ce",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-qa-004",
|
||||
name: "QA",
|
||||
description: "محیط تست کیفیت - کنترل کیفیت خودکار و دستی",
|
||||
backgroundColor: "#805ad5",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-uat-005",
|
||||
name: "UAT",
|
||||
description: "تست پذیرش کاربر - تأیید کارفرما",
|
||||
backgroundColor: "#d69e2e",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
{
|
||||
id: "env-dr-006",
|
||||
name: "Disaster Recovery",
|
||||
description: "محیط بازیابی پس از بحران - پشتیبان Production",
|
||||
backgroundColor: "#e53e3e",
|
||||
textColor: "#ffffff",
|
||||
},
|
||||
],
|
||||
environments: [],
|
||||
products: [],
|
||||
boards: [],
|
||||
boardTags: [],
|
||||
@@ -4546,7 +4332,7 @@
|
||||
getSectionHTML() {
|
||||
const d = this.getData();
|
||||
let h = `<div class="board-section" id="section-dashboard">`;
|
||||
h += `<div class="board-header"><div class="board-header-title"><span class="collapse-icon">▼</span>📊 داشبورد مدیریتی</div><div class="board-header-actions"><button class="btn btn-accent btn-sm" onclick="DashboardManager.open()">📊 مشاهده کامل</button></div></div>`;
|
||||
h += `<div class="board-header"><div class="board-header-title"><span class="collapse-icon">▼</span>📊 داشبورد مدیریتی</div><div class="board-header-actions"><button class="btn btn-accent" onclick="DashboardManager.open()">📊 مشاهده کامل</button></div></div>`;
|
||||
h += `<div class="section-content">`;
|
||||
h += '<div class="dashboard-kpi-row" style="margin-bottom:16px">';
|
||||
h += `<div class="dashboard-kpi-card"><div class="dashboard-kpi-icon">📦</div><div class="dashboard-kpi-value">${d.products}</div><div class="dashboard-kpi-label">محصول</div></div>`;
|
||||
@@ -4972,7 +4758,6 @@
|
||||
showReleaseBoards() {
|
||||
ReleaseBoardsManager.open();
|
||||
},
|
||||
/* ✅ NEW: اکشن مدیریت تگها */
|
||||
showTagManager() {
|
||||
ReleaseBoardsManager.openTagManager();
|
||||
},
|
||||
@@ -5969,8 +5754,6 @@
|
||||
: 0;
|
||||
document.getElementById("dashboardFooterStats").innerHTML =
|
||||
`<span>📦 محصولات: <span class="stat-highlight">${d.products}</span></span><span>🌿 پروژهها: <span class="stat-highlight">${d.projects}</span></span><span>🚀 استقرارها: <span class="stat-highlight">${d.deploys}</span></span><span>📈 پوشش استقرار: <span class="stat-highlight">${coverage}%</span></span>`;
|
||||
document.getElementById("dashboardRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderDonut(cid, data) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -6724,53 +6507,12 @@
|
||||
checkRecovery() {
|
||||
const saved = this.load();
|
||||
if (!saved || !saved.appData) return;
|
||||
const appData = saved.appData;
|
||||
const stats = {
|
||||
environments: (appData.environments || []).length,
|
||||
products: (appData.products || []).length,
|
||||
projects: 0,
|
||||
deployments: 0,
|
||||
boards: (appData.boards || []).length,
|
||||
boardTags: (appData.boardTags || []).length,
|
||||
};
|
||||
(appData.products || []).forEach((prod) => {
|
||||
stats.projects += (prod.projects || []).length;
|
||||
(prod.projects || []).forEach((pr) => {
|
||||
stats.deployments += (pr.deployments || []).filter(
|
||||
(d) => d.status === "active",
|
||||
).length;
|
||||
});
|
||||
});
|
||||
const dateEl = document.getElementById("rbAutosaveDate");
|
||||
const envCountEl = document.getElementById("rbAutosaveEnvCount");
|
||||
const prodCountEl = document.getElementById("rbAutosaveProdCount");
|
||||
const projCountEl = document.getElementById("rbAutosaveProjCount");
|
||||
const depCountEl = document.getElementById("rbAutosaveDepCount");
|
||||
const boardCountEl = document.getElementById("rbAutosaveBoardCount");
|
||||
if (dateEl) {
|
||||
const d = new Date(saved.savedAt);
|
||||
dateEl.textContent =
|
||||
d.toLocaleDateString("fa-IR") +
|
||||
" - " +
|
||||
d.toLocaleTimeString("fa-IR", {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
}
|
||||
if (envCountEl)
|
||||
envCountEl.textContent = stats.environments.toLocaleString("fa-IR");
|
||||
if (prodCountEl)
|
||||
prodCountEl.textContent = stats.products.toLocaleString("fa-IR");
|
||||
if (projCountEl)
|
||||
projCountEl.textContent = stats.projects.toLocaleString("fa-IR");
|
||||
if (depCountEl)
|
||||
depCountEl.textContent = stats.deployments.toLocaleString("fa-IR");
|
||||
if (boardCountEl)
|
||||
boardCountEl.textContent = stats.boards.toLocaleString("fa-IR");
|
||||
|
||||
document.getElementById("rbRecoverAutosaveBtn").onclick = () =>
|
||||
this.recover();
|
||||
document.getElementById("rbDiscardAutosaveBtn").onclick = () =>
|
||||
this.discard();
|
||||
|
||||
setTimeout(() => {
|
||||
ModalManager.open("rbAutosaveModal");
|
||||
}, 600);
|
||||
@@ -6825,28 +6567,28 @@
|
||||
DEFAULT_COLUMNS: [
|
||||
{
|
||||
title: "📥 بک لاگ",
|
||||
backgroundColor: "#edf2f7",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#6b7208",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "📋 برای انجام",
|
||||
backgroundColor: "#ebf8ff",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#393e65",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "🔨 در حال انجام",
|
||||
backgroundColor: "#fef5e7",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#453111",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "🔍 برای تست",
|
||||
backgroundColor: "#faf5ff",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#542881",
|
||||
textColor: "#b4cbf9",
|
||||
},
|
||||
{
|
||||
title: "✅ انجام شده",
|
||||
backgroundColor: "#f0fff4",
|
||||
textColor: "#1a202c",
|
||||
backgroundColor: "#087224",
|
||||
textColor: "#d8d96d",
|
||||
},
|
||||
],
|
||||
open() {
|
||||
@@ -6897,7 +6639,6 @@
|
||||
} else {
|
||||
this._incrementalRender(board);
|
||||
}
|
||||
/* ✅ NEW: اعمال فیلترها و اتصال درگ پس از رندر */
|
||||
this.applyFilters();
|
||||
this.initDragAndDrop();
|
||||
this.updateFooterStats();
|
||||
@@ -7098,9 +6839,6 @@ ${checklistTotal > 0 ? `<span class="card-meta-item">✅ ${checklistDone}/${chec
|
||||
${checklistHtml}
|
||||
</div>`;
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: فیلتر تگها
|
||||
═══════════════════════════════════════════════════ */
|
||||
renderFilterBar() {
|
||||
const container = document.getElementById("rbTagFilterContainer");
|
||||
const clearBtn = document.getElementById("rbClearTagFilter");
|
||||
@@ -7138,9 +6876,6 @@ ${checklistHtml}
|
||||
};
|
||||
}
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: اعمال فیلتر و جستجو
|
||||
═══════════════════════════════════════════════════ */
|
||||
applyFilters() {
|
||||
const board = this.getActiveBoard();
|
||||
if (!board) return;
|
||||
@@ -7224,9 +6959,6 @@ ${checklistHtml}
|
||||
}
|
||||
}
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: رویدادهای جستجو
|
||||
═══════════════════════════════════════════════════ */
|
||||
bindSearchEvents() {
|
||||
const inp = document.getElementById("rbCardSearchInput");
|
||||
const clr = document.getElementById("rbCardSearchClear");
|
||||
@@ -7253,9 +6985,6 @@ ${checklistHtml}
|
||||
inp.focus();
|
||||
};
|
||||
},
|
||||
/* ═══════════════════════════════════════════════════
|
||||
✅ NEW: Drag & Drop
|
||||
═══════════════════════════════════════════════════ */
|
||||
initDragAndDrop() {
|
||||
const wrapper = document.getElementById("rbBoardWrapper");
|
||||
if (!wrapper) return;
|
||||
@@ -7350,7 +7079,6 @@ ${checklistHtml}
|
||||
.querySelectorAll(".drag-over-column")
|
||||
.forEach((el) => el.classList.remove("drag-over-column"));
|
||||
},
|
||||
/* ── جابجایی کارت بین ستونها ── */
|
||||
moveCard(cardId, targetColumnId) {
|
||||
const board = this.getActiveBoard();
|
||||
if (!board) return;
|
||||
@@ -7387,7 +7115,6 @@ ${checklistHtml}
|
||||
2000,
|
||||
);
|
||||
},
|
||||
/* ── جابجایی ستونها ── */
|
||||
moveColumn(sourceColId, targetColId) {
|
||||
const board = this.getActiveBoard();
|
||||
if (!board) return;
|
||||
@@ -7406,7 +7133,6 @@ ${checklistHtml}
|
||||
this.render(true);
|
||||
showToast("📊 ستون جابجا شد", "success", 2000);
|
||||
},
|
||||
/* ── مدیریت برد ── */
|
||||
getActiveBoard() {
|
||||
return (projectData.appData.boards || []).find(
|
||||
(b) => b.id === this.activeBoardId,
|
||||
@@ -7525,7 +7251,6 @@ ${checklistHtml}
|
||||
showToast("برد حذف شد", "warning");
|
||||
this.render(true);
|
||||
},
|
||||
/* ── مدیریت ستون ── */
|
||||
openNewColumnModal() {
|
||||
if (!this.getActiveBoard()) {
|
||||
showToast("ابتدا یک برد ایجاد کنید", "warning");
|
||||
@@ -7600,7 +7325,6 @@ ${checklistHtml}
|
||||
showToast("ستون حذف شد", "warning");
|
||||
this.render(true);
|
||||
},
|
||||
/* ── مدیریت کارت ── */
|
||||
openNewCardModal(columnId) {
|
||||
this.editing.cardId = null;
|
||||
this.editing.columnForCard = columnId;
|
||||
@@ -7818,7 +7542,6 @@ ${checklistHtml}
|
||||
document.getElementById("rbDeleteCardBtn").onclick = () =>
|
||||
this.deleteCard();
|
||||
},
|
||||
/* ── Toolbar Events ── */
|
||||
bindToolbarEvents() {
|
||||
document.getElementById("rbEditBoard").onclick = () =>
|
||||
this.openEditBoardModal();
|
||||
@@ -7852,7 +7575,6 @@ ${checklistHtml}
|
||||
document.getElementById("rbFooterStats").innerHTML =
|
||||
`<span>📋 بردها: <span class="stat-highlight">${boards.length}</span></span><span>📑 ستونها: <span class="stat-highlight">${boards.reduce((s, b) => s + b.columns.length, 0)}</span></span><span>📝 کارتها: <span class="stat-highlight">${totalCards}</span></span>`;
|
||||
},
|
||||
/* ── Tag Manager ── */
|
||||
openTagManager() {
|
||||
ModalManager.open("rbTagManagerModal");
|
||||
this.renderTagList();
|
||||
@@ -8089,8 +7811,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("depRiskList", d);
|
||||
document.getElementById("depAnalysisFooterStats").innerHTML =
|
||||
`<span>🔗 کل: <span class="stat-highlight">${d.totalDeps}</span></span><span>⚠️ گلوگاه: <span class="stat-highlight">${d.bottlenecks.length}</span></span><span>🔴 شکسته: <span class="stat-highlight">${d.brokenDeps}</span></span><span>🔵 ایزوله: <span class="stat-highlight">${d.isolated.length}</span></span>`;
|
||||
document.getElementById("depAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderHubChart(cid, bottlenecks) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -8463,8 +8183,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("deployRiskList", d.riskList);
|
||||
document.getElementById("deployAnalysisFooterStats").innerHTML =
|
||||
`<span>🚀 کل: <span class="stat-highlight">${d.total}</span></span><span>📈 پوشش: <span class="stat-highlight">${d.coverage}%</span></span><span>⚠️ ریسکها: <span class="stat-highlight">${d.riskList.length}</span></span>`;
|
||||
document.getElementById("deployAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderEnvBarChart(cid, edc) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -8888,8 +8606,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("verRiskList", d.riskList);
|
||||
document.getElementById("verAnalysisFooterStats").innerHTML =
|
||||
`<span>🔢 کل: <span class="stat-highlight">${d.total}</span></span><span>📦 یکتا: <span class="stat-highlight">${d.uniqueVersions}</span></span><span>📈 میانگین: <span class="stat-highlight">${d.avgVersion}</span></span><span>⚠️ ریسکها: <span class="stat-highlight">${d.riskList.length}</span></span>`;
|
||||
document.getElementById("verAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderMajorBarChart(cid, majorCounts) {
|
||||
const c = document.getElementById(cid);
|
||||
@@ -9274,8 +8990,6 @@ ${checklistHtml}
|
||||
this.renderRiskList("riskDetailList", d.risks);
|
||||
document.getElementById("riskAnalysisFooterStats").innerHTML =
|
||||
`<span>🎯 سلامت: <span class="stat-highlight">${d.healthScore}%</span></span><span>⚠️ ریسکها: <span class="stat-highlight">${d.total}</span></span><span>🔴 بحرانی: <span class="stat-highlight">${d.crit}</span></span><span>🟠 بالا: <span class="stat-highlight">${d.high}</span></span>`;
|
||||
document.getElementById("riskAnalysisRefresh").onclick = () =>
|
||||
this.render();
|
||||
},
|
||||
renderSeverityDonut(cid, d) {
|
||||
const c = document.getElementById(cid);
|
||||
|
||||
Reference in New Issue
Block a user