feat: add subtask support
This commit is contained in:
@@ -13,6 +13,7 @@ import ProjectActivityBarChart from "@/components/ProjectActivityBarChart.vue";
|
||||
import AnalysisCard from "@/components/AnalysisCard.vue";
|
||||
import CostOverview from "@/components/CostOverview.vue";
|
||||
import GeneratedLeadsCard from "@/views/dashboards/ecommerce/EcommerceGeneratedLeads.vue";
|
||||
import GanttChart from "./gantt.vue";
|
||||
|
||||
import EcommerceCongratulationsJohn from '@/views/dashboards/ecommerce/EcommerceCongratulationsJohn.vue'
|
||||
import EcommerceEarningReports from '@/views/dashboards/ecommerce/EcommerceEarningReports.vue'
|
||||
@@ -101,6 +102,7 @@ const cardOrder = ref([
|
||||
"leads2",
|
||||
"leads3",
|
||||
"project-activity",
|
||||
"gantt-chart", // اضافه کردن gantt chart
|
||||
"analysis1",
|
||||
"analysis2",
|
||||
"cost-overview",
|
||||
@@ -115,9 +117,10 @@ const cardOrder = ref([
|
||||
|
||||
const defaultWidgetIds = [
|
||||
"leads1",
|
||||
"leads2",
|
||||
"leads2",
|
||||
"leads3",
|
||||
"project-activity",
|
||||
"gantt-chart", // اضافه کردن
|
||||
"analysis1",
|
||||
"analysis2",
|
||||
"cost-overview",
|
||||
@@ -144,6 +147,7 @@ const cardSizes = ref({
|
||||
"project-status": { cols: 4, height: 33.33 },
|
||||
"active-project": { cols: 4, height: 33.33 },
|
||||
"recent-transactions": { cols: 6, height: 33.33 },
|
||||
"gantt-chart": { cols: 12, height: 50 },
|
||||
"activity-timeline": { cols: 6, height: 33.33 },
|
||||
"ecommerce-congratulations": { cols: 6, height: 33.33 },
|
||||
"ecommerce-earning-reports": { cols: 8, height: 33.33 },
|
||||
@@ -182,6 +186,7 @@ const cardComponents = {
|
||||
"project-status": { component: CrmProjectStatus, props: {} },
|
||||
"active-project": { component: CrmActiveProject, props: {} },
|
||||
"recent-transactions": { component: CrmRecentTransactions, props: {} },
|
||||
"gantt-chart": { component: GanttChart, props: {} },
|
||||
"activity-timeline": { component: CrmActivityTimeline, props: {} },
|
||||
"ecommerce-congratulations": { component: EcommerceCongratulationsJohn, props: {} },
|
||||
"ecommerce-earning-reports": { component: EcommerceEarningReports, props: {} },
|
||||
@@ -251,6 +256,7 @@ const restoreAllCards = async () => {
|
||||
"leads2",
|
||||
"leads3",
|
||||
"project-activity",
|
||||
"gantt-chart",
|
||||
"analysis1",
|
||||
"analysis2",
|
||||
"cost-overview",
|
||||
|
||||
@@ -327,32 +327,31 @@ export default {
|
||||
contextMenu.className = 'gantt-context-menu'
|
||||
contextMenu.innerHTML = `
|
||||
<div class="context-menu-item" onclick="window.ganttComponent.addSubTask('${taskId}')">
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M12 5v14m-7-7h14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 5v14m-7-7h14"/>
|
||||
</svg>
|
||||
Add Sub Task
|
||||
</div>
|
||||
<div class="context-menu-item" onclick="window.ganttComponent.editTask('${taskId}')">
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2"/>
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5"/>
|
||||
<path d="m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
</svg>
|
||||
Edit Task
|
||||
</div>
|
||||
<div class="context-menu-item" onclick="window.ganttComponent.deleteTaskFromContext('${taskId}')">
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none">
|
||||
<path d="m3 6 3 16h12l3-16" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" stroke="currentColor" stroke-width="2"/>
|
||||
<line x1="10" y1="11" x2="10" y2="17" stroke="currentColor" stroke-width="2"/>
|
||||
<line x1="14" y1="11" x2="14" y2="17" stroke="currentColor" stroke-width="2"/>
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
|
||||
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
|
||||
</svg>
|
||||
Delete Task
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item" onclick="window.ganttComponent.markTaskComplete('${taskId}')">
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2"/>
|
||||
<svg class="menu-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<polyline points="9,11 12,14 22,4"/>
|
||||
<path d="M21,12v7a2,2 0 0,1 -2,2H5a2,2 0 0,1 -2,-2V5a2,2 0 0,1 2,-2h11"/>
|
||||
</svg>
|
||||
Toggle Complete
|
||||
</div>
|
||||
@@ -413,8 +412,7 @@ export default {
|
||||
this.hideContextMenu()
|
||||
},
|
||||
addTask() {
|
||||
const selectedId = gantt.getSelectedId()
|
||||
this.currentTaskId = selectedId
|
||||
this.currentTaskId = null
|
||||
this.taskForm = {
|
||||
text: 'New Task',
|
||||
start_date: new Date().toISOString().split('T')[0],
|
||||
@@ -537,9 +535,27 @@ export default {
|
||||
<template>
|
||||
<div class="gantt-container">
|
||||
<div class="gantt-toolbar">
|
||||
<button @click="addTask" class="btn btn-primary">Add Task</button>
|
||||
<button @click="deleteTask" class="btn btn-danger">Delete Selected</button>
|
||||
<button @click="markCompleted" class="btn btn-success">Toggle Complete</button>
|
||||
<button @click="addTask" class="btn btn-primary">
|
||||
<svg class="btn-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 5v14m-7-7h14"/>
|
||||
</svg>
|
||||
Add Task
|
||||
</button>
|
||||
<button @click="deleteTask" class="btn btn-danger">
|
||||
<svg class="btn-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
|
||||
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
|
||||
</svg>
|
||||
Delete Selected
|
||||
</button>
|
||||
<button @click="markCompleted" class="btn btn-success">
|
||||
<svg class="btn-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<polyline points="9,11 12,14 22,4"/>
|
||||
<path d="M21,12v7a2,2 0 0,1 -2,2H5a2,2 0 0,1 -2,-2V5a2,2 0 0,1 2,-2h11"/>
|
||||
</svg>
|
||||
Toggle Complete
|
||||
</button>
|
||||
</div>
|
||||
<div ref="ganttContainer" class="gantt-chart"></div>
|
||||
|
||||
@@ -548,11 +564,10 @@ export default {
|
||||
<div class="modal-container" @click.stop>
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">
|
||||
<svg class="modal-icon delete-icon" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="m3 6 3 16h12l3-16" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" stroke="currentColor" stroke-width="2"/>
|
||||
<line x1="10" y1="11" x2="10" y2="17" stroke="currentColor" stroke-width="2"/>
|
||||
<line x1="14" y1="11" x2="14" y2="17" stroke="currentColor" stroke-width="2"/>
|
||||
<svg class="modal-icon delete-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M3 6h18"/>
|
||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
|
||||
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
|
||||
</svg>
|
||||
Delete Task
|
||||
</h3>
|
||||
@@ -576,9 +591,9 @@ export default {
|
||||
<div class="modal-container" @click.stop>
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">
|
||||
<svg class="modal-icon edit-icon" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z" stroke="currentColor" stroke-width="2"/>
|
||||
<svg class="modal-icon edit-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5"/>
|
||||
<path d="m18.5 2.5 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
||||
</svg>
|
||||
Edit Task
|
||||
</h3>
|
||||
@@ -649,8 +664,8 @@ export default {
|
||||
<div class="modal-container" @click.stop>
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">
|
||||
<svg class="modal-icon add-icon" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M12 5v14m-7-7h14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<svg class="modal-icon add-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 5v14m-7-7h14"/>
|
||||
</svg>
|
||||
Add New Task
|
||||
</h3>
|
||||
@@ -723,52 +738,78 @@ export default {
|
||||
width: 100%;
|
||||
height: 650px;
|
||||
background: white;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
|
||||
.gantt-toolbar {
|
||||
padding: 10px;
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding: 12px 16px;
|
||||
background: #fafbfc;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 8px 14px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
transition: all 0.15s ease;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #007bff;
|
||||
background: #0969da;
|
||||
color: white;
|
||||
border-color: #0969da;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #0056b3;
|
||||
background: #0860ca;
|
||||
border-color: #0860ca;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: #dc3545;
|
||||
background: #d1242f;
|
||||
color: white;
|
||||
border-color: #d1242f;
|
||||
}
|
||||
|
||||
.btn-danger:hover {
|
||||
background: #c82333;
|
||||
background: #b91c1c;
|
||||
border-color: #b91c1c;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: #28a745;
|
||||
background: #1a7f37;
|
||||
color: white;
|
||||
border-color: #1a7f37;
|
||||
}
|
||||
|
||||
.btn-success:hover {
|
||||
background: #218838;
|
||||
background: #166a2e;
|
||||
border-color: #166a2e;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #f6f8fa;
|
||||
color: #24292f;
|
||||
border-color: #d1d9e0;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #f3f4f6;
|
||||
border-color: #c7d2da;
|
||||
}
|
||||
|
||||
.gantt-chart {
|
||||
@@ -779,212 +820,189 @@ export default {
|
||||
|
||||
<style>
|
||||
.gantt_container {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.gantt_grid_head_cell,
|
||||
.gantt_grid_data .gantt_cell {
|
||||
border-right: 1px solid #dee2e6;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
border-right: 1px solid #e1e5e9;
|
||||
border-bottom: 1px solid #e1e5e9;
|
||||
}
|
||||
|
||||
.gantt_grid_head_cell {
|
||||
background: #f8f9fa;
|
||||
background: #f6f8fa;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
padding: 12px 8px;
|
||||
color: #495057;
|
||||
padding: 10px 8px;
|
||||
color: #24292f;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.gantt_cell {
|
||||
padding: 10px 8px;
|
||||
padding: 8px;
|
||||
vertical-align: middle;
|
||||
line-height: 1.4;
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.gantt_tree_content {
|
||||
padding-left: 5px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.gantt_tree_icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 5px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 4px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.gantt_task_line.completed-task {
|
||||
background: #28a745;
|
||||
border: 1px solid #1e7e34;
|
||||
background: #1f883d;
|
||||
border: 1px solid #1a7f37;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.gantt_task_line.high-progress-task {
|
||||
background: #17a2b8;
|
||||
border: 1px solid #138496;
|
||||
background: #0969da;
|
||||
border: 1px solid #0860ca;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.gantt_task_line.medium-progress-task {
|
||||
background: #ffc107;
|
||||
border: 1px solid #e0a800;
|
||||
background: #bf8700;
|
||||
border: 1px solid #9a6700;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.gantt_task_line.low-progress-task {
|
||||
background: #dc3545;
|
||||
border: 1px solid #c82333;
|
||||
background: #d1242f;
|
||||
border: 1px solid #b91c1c;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.summary-row {
|
||||
background: #f1f3f4;
|
||||
background: #f6f8fa;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.gantt_task_progress {
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.gantt_scale_cell {
|
||||
border-bottom: 1px solid #ced4da;
|
||||
border-right: 1px solid #ced4da;
|
||||
background: #f8f9fa;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
border-bottom: 1px solid #e1e5e9;
|
||||
border-right: 1px solid #e1e5e9;
|
||||
background: #f6f8fa;
|
||||
font-weight: 500;
|
||||
color: #24292f;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.gantt_task_line {
|
||||
border-radius: 3px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.gantt_side_content {
|
||||
color: #212529;
|
||||
color: #656d76;
|
||||
font-size: 11px;
|
||||
margin-top: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.completed-mark {
|
||||
color: #28a745;
|
||||
color: #1f883d;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.gantt_grid_data .gantt_row:nth-child(odd) {
|
||||
background: #fafafa;
|
||||
background: #fafbfc;
|
||||
}
|
||||
|
||||
.gantt_grid_data .gantt_row:hover {
|
||||
background: #e3f2fd;
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.gantt_selected .gantt_cell {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
background: #ddf4ff;
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.gantt_task_link {
|
||||
stroke: #007bff;
|
||||
stroke-width: 2;
|
||||
stroke: #656d76;
|
||||
stroke-width: 1.5;
|
||||
}
|
||||
|
||||
.gantt_task_link .gantt_link_arrow {
|
||||
fill: #007bff;
|
||||
fill: #656d76;
|
||||
}
|
||||
|
||||
.gantt_milestone {
|
||||
background: #6f42c1;
|
||||
border: 2px solid #5a2d91;
|
||||
background: #8250df;
|
||||
border: 2px solid #6f42c1;
|
||||
}
|
||||
|
||||
.gantt-context-menu {
|
||||
background: #ffffff;
|
||||
border: 1px solid #e1e5e9;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 4px 8px rgba(0, 0, 0, 0.08);
|
||||
padding: 8px 0;
|
||||
min-width: 200px;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
border: 1px solid #d1d9e0;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 8px 24px rgba(140, 149, 159, 0.2);
|
||||
padding: 4px;
|
||||
min-width: 180px;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
font-size: 13px;
|
||||
z-index: 9999;
|
||||
backdrop-filter: blur(10px);
|
||||
animation: contextMenuFadeIn 0.2s ease-out;
|
||||
animation: contextMenuFadeIn 0.15s ease-out;
|
||||
}
|
||||
|
||||
@keyframes contextMenuFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px) scale(0.95);
|
||||
transform: scale(0.95);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
padding: 6px 8px;
|
||||
cursor: pointer;
|
||||
color: #374151;
|
||||
transition: all 0.15s ease;
|
||||
border: none;
|
||||
background: none;
|
||||
font-size: 14px;
|
||||
color: #24292f;
|
||||
transition: background-color 0.1s ease;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.context-menu-item:hover {
|
||||
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
|
||||
color: #1e293b;
|
||||
transform: translateX(2px);
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.context-menu-item:active {
|
||||
background: #e2e8f0;
|
||||
transform: translateX(1px);
|
||||
background: #eaeef2;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
margin-right: 12px;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.15s ease;
|
||||
margin-right: 8px;
|
||||
opacity: 0.8;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.context-menu-item:hover .menu-icon {
|
||||
opacity: 1;
|
||||
color: #656d76;
|
||||
}
|
||||
|
||||
.context-menu-separator {
|
||||
height: 1px;
|
||||
background: #e2e8f0;
|
||||
margin: 8px 16px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.context-menu-item:first-child {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.context-menu-item:last-child {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.context-menu-item:nth-child(1) .menu-icon {
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.context-menu-item:nth-child(2) .menu-icon {
|
||||
color: #3b82f6;
|
||||
}
|
||||
|
||||
.context-menu-item:nth-child(3) .menu-icon {
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
.context-menu-item:nth-child(5) .menu-icon {
|
||||
color: #8b5cf6;
|
||||
background: #d1d9e0;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
@@ -993,13 +1011,13 @@ export default {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
backdrop-filter: blur(4px);
|
||||
background: rgba(31, 35, 40, 0.5);
|
||||
backdrop-filter: blur(3px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
animation: modalOverlayFadeIn 0.3s ease-out;
|
||||
animation: modalOverlayFadeIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes modalOverlayFadeIn {
|
||||
@@ -1013,19 +1031,20 @@ export default {
|
||||
|
||||
.modal-container {
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid #d1d9e0;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 16px 32px rgba(31, 35, 40, 0.15);
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
max-width: 480px;
|
||||
max-height: 80vh;
|
||||
overflow: hidden;
|
||||
animation: modalSlideIn 0.3s ease-out;
|
||||
animation: modalSlideIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes modalSlideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-20px) scale(0.95);
|
||||
transform: translateY(-16px) scale(0.98);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
@@ -1037,185 +1056,177 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px 24px 16px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #d1d9e0;
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #111827;
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.modal-icon {
|
||||
margin-right: 12px;
|
||||
margin-right: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.delete-icon {
|
||||
color: #ef4444;
|
||||
color: #d1242f;
|
||||
}
|
||||
|
||||
.edit-icon {
|
||||
color: #3b82f6;
|
||||
color: #0969da;
|
||||
}
|
||||
|
||||
.add-icon {
|
||||
color: #10b981;
|
||||
color: #1f883d;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 28px;
|
||||
color: #6b7280;
|
||||
font-size: 20px;
|
||||
color: #656d76;
|
||||
cursor: pointer;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
border-radius: 3px;
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
background: #eaeef2;
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 24px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.modal-message {
|
||||
font-size: 16px;
|
||||
color: #374151;
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 14px;
|
||||
color: #24292f;
|
||||
margin: 0 0 6px 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.modal-warning {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
font-size: 12px;
|
||||
color: #656d76;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
color: #374151;
|
||||
font-size: 14px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: 600;
|
||||
color: #24292f;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border: 2px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid #d1d9e0;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: #24292f;
|
||||
background: #ffffff;
|
||||
transition: all 0.2s ease;
|
||||
transition: border-color 0.1s ease;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
outline: none;
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
border-color: #0969da;
|
||||
box-shadow: 0 0 0 2px rgba(9, 105, 218, 0.1);
|
||||
}
|
||||
|
||||
.form-input:invalid {
|
||||
border-color: #ef4444;
|
||||
border-color: #d1242f;
|
||||
}
|
||||
|
||||
.progress-input-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.form-range {
|
||||
flex: 1;
|
||||
height: 6px;
|
||||
background: #e5e7eb;
|
||||
border-radius: 3px;
|
||||
height: 4px;
|
||||
background: #d1d9e0;
|
||||
border-radius: 2px;
|
||||
outline: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.form-range::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: #3b82f6;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: #0969da;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: 2px solid #ffffff;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 1px 3px rgba(31, 35, 40, 0.2);
|
||||
}
|
||||
|
||||
.form-range::-moz-range-thumb {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: #3b82f6;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: #0969da;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: 2px solid #ffffff;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 1px 3px rgba(31, 35, 40, 0.2);
|
||||
}
|
||||
|
||||
.progress-value {
|
||||
min-width: 45px;
|
||||
min-width: 40px;
|
||||
text-align: right;
|
||||
font-weight: 600;
|
||||
color: #3b82f6;
|
||||
font-size: 14px;
|
||||
color: #0969da;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 16px 24px 24px;
|
||||
padding: 12px 20px 16px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
border: 1px solid #d1d5db;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #e5e7eb;
|
||||
color: #1f2937;
|
||||
background: #f6f8fa;
|
||||
border-top: 1px solid #d1d9e0;
|
||||
}
|
||||
|
||||
.notification {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
min-width: 300px;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
min-width: 280px;
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid #d1d9e0;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 8px 24px rgba(31, 35, 40, 0.1);
|
||||
z-index: 10001;
|
||||
animation: notificationSlideIn 0.3s ease-out;
|
||||
animation: notificationSlideIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes notificationSlideIn {
|
||||
@@ -1233,49 +1244,49 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 20px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.notification-message {
|
||||
font-size: 14px;
|
||||
color: #374151;
|
||||
font-size: 13px;
|
||||
color: #24292f;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.notification-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 20px;
|
||||
color: #6b7280;
|
||||
font-size: 16px;
|
||||
color: #656d76;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
border-radius: 3px;
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
.notification-close:hover {
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.notification-success {
|
||||
border-left: 4px solid #10b981;
|
||||
border-left: 3px solid #1f883d;
|
||||
}
|
||||
|
||||
.notification-error {
|
||||
border-left: 4px solid #ef4444;
|
||||
border-left: 3px solid #d1242f;
|
||||
}
|
||||
|
||||
.notification-warning {
|
||||
border-left: 4px solid #f59e0b;
|
||||
border-left: 3px solid #bf8700;
|
||||
}
|
||||
|
||||
.notification-info {
|
||||
border-left: 4px solid #3b82f6;
|
||||
border-left: 3px solid #0969da;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user