fix: adjust component sizes on demo page
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -39,6 +39,8 @@
|
||||
"eslint-plugin-regexp": "2.7.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"gridstack": "^12.2.1",
|
||||
"highcharts": "^12.3.0",
|
||||
"highcharts-vue": "^2.0.1",
|
||||
"jspdf": "^3.0.1",
|
||||
"jspdf-autotable": "^5.0.2",
|
||||
"jwt-decode": "4.0.0",
|
||||
@@ -9065,6 +9067,22 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/highcharts": {
|
||||
"version": "12.3.0",
|
||||
"resolved": "https://registry.npmjs.org/highcharts/-/highcharts-12.3.0.tgz",
|
||||
"integrity": "sha512-QIKmaemgheRa1K2Ia9MLj1KLtBU1Tu/VQ6KAMqtMBMsAC4NzcFq6g96LF03ZO3IFFiSifmZx8ItEyRcz4w75cg==",
|
||||
"license": "https://www.highcharts.com/license"
|
||||
},
|
||||
"node_modules/highcharts-vue": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/highcharts-vue/-/highcharts-vue-2.0.1.tgz",
|
||||
"integrity": "sha512-7yVaKvsWlx7OgmKFXE2D99fi/0tr2A85H4KUz3jL7CRQhAwvEvXgtDIyTBGLHJsOC5L9VlppAI7k6KfIi0j0hg==",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"peerDependencies": {
|
||||
"highcharts": ">=5.0.0",
|
||||
"vue": ">=3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hookable": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
"eslint-plugin-regexp": "2.7.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"gridstack": "^12.2.1",
|
||||
"highcharts": "^12.3.0",
|
||||
"highcharts-vue": "^2.0.1",
|
||||
"jspdf": "^3.0.1",
|
||||
"jspdf-autotable": "^5.0.2",
|
||||
"jwt-decode": "4.0.0",
|
||||
|
||||
@@ -102,7 +102,6 @@ const cardOrder = ref([
|
||||
"leads2",
|
||||
"leads3",
|
||||
"project-activity",
|
||||
"gantt-chart", // اضافه کردن gantt chart
|
||||
"analysis1",
|
||||
"analysis2",
|
||||
"cost-overview",
|
||||
@@ -120,7 +119,6 @@ const defaultWidgetIds = [
|
||||
"leads2",
|
||||
"leads3",
|
||||
"project-activity",
|
||||
"gantt-chart", // اضافه کردن
|
||||
"analysis1",
|
||||
"analysis2",
|
||||
"cost-overview",
|
||||
@@ -147,7 +145,6 @@ 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 },
|
||||
@@ -186,7 +183,6 @@ 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: {} },
|
||||
|
||||
@@ -2,96 +2,78 @@
|
||||
import { onMounted, nextTick } from 'vue'
|
||||
import { GridStack } from 'gridstack'
|
||||
|
||||
import EcommerceCongratulationsJohn from '@/views/dashboards/ecommerce/EcommerceCongratulationsJohn.vue'
|
||||
import EcommerceEarningReports from '@/views/dashboards/ecommerce/EcommerceEarningReports.vue'
|
||||
import EcommerceExpensesRadialBarCharts from '@/views/dashboards/ecommerce/EcommerceExpensesRadialBarCharts.vue'
|
||||
import EcommerceGeneratedLeads from '@/views/dashboards/ecommerce/EcommerceGeneratedLeads.vue'
|
||||
import EcommerceInvoiceTable from '@/views/dashboards/ecommerce/EcommerceInvoiceTable.vue'
|
||||
import EcommerceOrder from '@/views/dashboards/ecommerce/EcommerceOrder.vue'
|
||||
import EcommercePopularProducts from '@/views/dashboards/ecommerce/EcommercePopularProducts.vue'
|
||||
import EcommerceRevenueReport from '@/views/dashboards/ecommerce/EcommerceRevenueReport.vue'
|
||||
import EcommerceStatistics from '@/views/dashboards/ecommerce/EcommerceStatistics.vue'
|
||||
import EcommerceTotalProfitLineCharts from '@/views/dashboards/ecommerce/EcommerceTotalProfitLineCharts.vue'
|
||||
import EcommerceTransactions from '@/views/dashboards/ecommerce/EcommerceTransactions.vue'
|
||||
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'
|
||||
|
||||
onMounted(async () => {
|
||||
const grid = GridStack.init({
|
||||
column: 12,
|
||||
cellHeight: 50,
|
||||
cellHeight: '110',
|
||||
float: true,
|
||||
draggable: { handle: '.grid-stack-item-content' },
|
||||
resizable: true
|
||||
resizable: true,
|
||||
maxRow: 20,
|
||||
})
|
||||
|
||||
await nextTick()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid-stack">
|
||||
<div class="grid-stack-item" gs-w="8" gs-h="4" gs-max-h="4" gs-x="0" gs-y="0">
|
||||
<div class="grid-stack-item" gs-min-w="4" gs-h="2" gs-max-h="2">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceCongratulationsJohn />
|
||||
<GeneratedLeadsCard :progress="32" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="4" gs-h="4" gs-max-h="4" gs-x="8" gs-y="0">
|
||||
<div class="grid-stack-item" gs-min-w="4" gs-h="2" gs-max-h="2">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceStatistics />
|
||||
<GeneratedLeadsCard :donut-colors="['primary']" :progress="71" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="7" gs-h="3" gs-max-h="3" gs-x="0" gs-y="4">
|
||||
<div class="grid-stack-item" gs-min-w="4" gs-h="2" gs-max-h="2">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceTotalProfitLineCharts />
|
||||
<GeneratedLeadsCard :donut-colors="['warning']" :progress="32" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="5" gs-h="3" gs-max-h="3" gs-x="7" gs-y="4">
|
||||
<div class="grid-stack-item" gs-w="8" gs-h="7" gs-max-h="7">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceExpensesRadialBarCharts />
|
||||
<ProjectActivityBarChart />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="3" gs-h="5" gs-max-h="5" gs-x="0" gs-y="7">
|
||||
<div class="grid-stack-item" gs-w="4" gs-h="7" gs-max-h="7">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceGeneratedLeads />
|
||||
<AnalysisCard />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="6" gs-h="5" gs-max-h="5" gs-x="3" gs-y="7">
|
||||
<div class="grid-stack-item" gs-w="12" gs-h="8" gs-max-h="8">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceRevenueReport />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="3" gs-h="3" gs-max-h="3" gs-x="9" gs-y="7">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceOrder />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="4" gs-h="10" gs-max-h="10" gs-x="0" gs-y="12">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceEarningReports />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="4" gs-h="10" gs-max-h="10" gs-x="4" gs-y="12">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommercePopularProducts />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="4" gs-h="4" gs-max-h="4" gs-x="8" gs-y="12">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceTransactions />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-stack-item" gs-w="12" gs-h="6" gs-max-h="6" gs-x="0" gs-y="16">
|
||||
<div class="grid-stack-item-content">
|
||||
<EcommerceInvoiceTable />
|
||||
<GanttChart />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.grid-stack-item-content {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.grid-stack-item-content>* {
|
||||
flex: 1;
|
||||
margin-bottom: 3.2rem;
|
||||
}
|
||||
|
||||
.grid-stack-item:has(GanttChart) {
|
||||
height: 100vh !important;
|
||||
}
|
||||
|
||||
.grid-stack-item:has(GanttChart) .grid-stack-item-content {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
@@ -1,23 +1,36 @@
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { gantt } from 'dhtmlx-gantt'
|
||||
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
|
||||
|
||||
export default {
|
||||
name: 'GanttChart',
|
||||
data() {
|
||||
return {
|
||||
showDeleteModal: false,
|
||||
showEditModal: false,
|
||||
showAddModal: false,
|
||||
currentTaskId: null,
|
||||
currentTask: null,
|
||||
taskForm: {
|
||||
const props = defineProps({
|
||||
initialTasks: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
data: [],
|
||||
links: []
|
||||
})
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const ganttContainer = ref(null)
|
||||
const showDeleteModal = ref(false)
|
||||
const showEditModal = ref(false)
|
||||
const showAddModal = ref(false)
|
||||
const currentTaskId = ref(null)
|
||||
const currentTask = ref(null)
|
||||
const taskForm = ref({
|
||||
text: '',
|
||||
start_date: '',
|
||||
duration: 3,
|
||||
progress: 0
|
||||
},
|
||||
tasks: {
|
||||
})
|
||||
|
||||
const tasks = props.initialTasks.data.length > 0 ? props.initialTasks : {
|
||||
data: [
|
||||
{
|
||||
id: 1,
|
||||
@@ -204,19 +217,9 @@ export default {
|
||||
{ id: 10, source: 23, target: 24, type: "0" },
|
||||
{ id: 11, source: 241, target: 242, type: "0" }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initGantt()
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (gantt.$container) {
|
||||
gantt.clearAll()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initGantt() {
|
||||
}
|
||||
|
||||
const initGantt = () => {
|
||||
gantt.config.date_format = "%d-%m-%Y"
|
||||
gantt.config.fit_tasks = true
|
||||
gantt.config.start_date = null
|
||||
@@ -310,17 +313,18 @@ export default {
|
||||
|
||||
gantt.attachEvent("onContextMenu", function(taskId, linkId, e) {
|
||||
if (taskId) {
|
||||
this.showContextMenu(e, taskId)
|
||||
showContextMenu(e, taskId)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}.bind(this))
|
||||
})
|
||||
|
||||
gantt.init(this.$refs.ganttContainer)
|
||||
gantt.parse(this.tasks)
|
||||
},
|
||||
showContextMenu(e, taskId) {
|
||||
this.hideContextMenu()
|
||||
gantt.init(ganttContainer.value)
|
||||
gantt.parse(tasks)
|
||||
}
|
||||
|
||||
const showContextMenu = (e, taskId) => {
|
||||
hideContextMenu()
|
||||
|
||||
const contextMenu = document.createElement('div')
|
||||
contextMenu.id = 'gantt-context-menu'
|
||||
@@ -364,139 +368,156 @@ export default {
|
||||
|
||||
document.body.appendChild(contextMenu)
|
||||
|
||||
document.addEventListener('click', this.hideContextMenu)
|
||||
window.ganttComponent = this
|
||||
},
|
||||
hideContextMenu() {
|
||||
document.addEventListener('click', hideContextMenu)
|
||||
window.ganttComponent = {
|
||||
addSubTask,
|
||||
editTask,
|
||||
deleteTaskFromContext,
|
||||
markTaskComplete
|
||||
}
|
||||
}
|
||||
|
||||
const hideContextMenu = () => {
|
||||
const existingMenu = document.getElementById('gantt-context-menu')
|
||||
if (existingMenu) {
|
||||
existingMenu.remove()
|
||||
}
|
||||
document.removeEventListener('click', this.hideContextMenu)
|
||||
},
|
||||
addSubTask(parentId) {
|
||||
this.currentTaskId = parentId
|
||||
this.taskForm = {
|
||||
document.removeEventListener('click', hideContextMenu)
|
||||
}
|
||||
|
||||
const addSubTask = (parentId) => {
|
||||
currentTaskId.value = parentId
|
||||
taskForm.value = {
|
||||
text: 'New Sub Task',
|
||||
start_date: new Date().toISOString().split('T')[0],
|
||||
duration: 3,
|
||||
progress: 0
|
||||
}
|
||||
this.showAddModal = true
|
||||
this.hideContextMenu()
|
||||
},
|
||||
editTask(taskId) {
|
||||
this.currentTaskId = taskId
|
||||
showAddModal.value = true
|
||||
hideContextMenu()
|
||||
}
|
||||
|
||||
const editTask = (taskId) => {
|
||||
currentTaskId.value = taskId
|
||||
const task = gantt.getTask(taskId)
|
||||
this.currentTask = task
|
||||
this.taskForm = {
|
||||
currentTask.value = task
|
||||
taskForm.value = {
|
||||
text: task.text,
|
||||
start_date: gantt.date.date_to_str("%Y-%m-%d")(task.start_date),
|
||||
duration: task.duration,
|
||||
progress: task.progress
|
||||
}
|
||||
this.showEditModal = true
|
||||
this.hideContextMenu()
|
||||
},
|
||||
deleteTaskFromContext(taskId) {
|
||||
this.currentTaskId = taskId
|
||||
this.currentTask = gantt.getTask(taskId)
|
||||
this.showDeleteModal = true
|
||||
this.hideContextMenu()
|
||||
},
|
||||
markTaskComplete(taskId) {
|
||||
showEditModal.value = true
|
||||
hideContextMenu()
|
||||
}
|
||||
|
||||
const deleteTaskFromContext = (taskId) => {
|
||||
currentTaskId.value = taskId
|
||||
currentTask.value = gantt.getTask(taskId)
|
||||
showDeleteModal.value = true
|
||||
hideContextMenu()
|
||||
}
|
||||
|
||||
const markTaskComplete = (taskId) => {
|
||||
let task = gantt.getTask(taskId)
|
||||
task.progress = task.progress === 1 ? 0 : 1
|
||||
gantt.updateTask(taskId)
|
||||
gantt.render()
|
||||
this.hideContextMenu()
|
||||
},
|
||||
addTask() {
|
||||
this.currentTaskId = null
|
||||
this.taskForm = {
|
||||
hideContextMenu()
|
||||
}
|
||||
|
||||
const addTask = () => {
|
||||
currentTaskId.value = null
|
||||
taskForm.value = {
|
||||
text: 'New Task',
|
||||
start_date: new Date().toISOString().split('T')[0],
|
||||
duration: 3,
|
||||
progress: 0
|
||||
}
|
||||
this.showAddModal = true
|
||||
},
|
||||
deleteTask() {
|
||||
showAddModal.value = true
|
||||
}
|
||||
|
||||
const deleteTask = () => {
|
||||
const selectedTask = gantt.getSelectedId()
|
||||
if (selectedTask) {
|
||||
this.currentTaskId = selectedTask
|
||||
this.currentTask = gantt.getTask(selectedTask)
|
||||
this.showDeleteModal = true
|
||||
currentTaskId.value = selectedTask
|
||||
currentTask.value = gantt.getTask(selectedTask)
|
||||
showDeleteModal.value = true
|
||||
} else {
|
||||
this.showNotification('Please select a task to delete', 'warning')
|
||||
showNotification('Please select a task to delete', 'warning')
|
||||
}
|
||||
},
|
||||
confirmDelete() {
|
||||
if (this.currentTaskId) {
|
||||
gantt.deleteTask(this.currentTaskId)
|
||||
this.showDeleteModal = false
|
||||
this.currentTaskId = null
|
||||
this.currentTask = null
|
||||
this.showNotification('Task deleted successfully', 'success')
|
||||
}
|
||||
|
||||
const confirmDelete = () => {
|
||||
if (currentTaskId.value) {
|
||||
gantt.deleteTask(currentTaskId.value)
|
||||
showDeleteModal.value = false
|
||||
currentTaskId.value = null
|
||||
currentTask.value = null
|
||||
showNotification('Task deleted successfully', 'success')
|
||||
}
|
||||
},
|
||||
saveTask() {
|
||||
if (!this.taskForm.text.trim()) {
|
||||
this.showNotification('Task name is required', 'error')
|
||||
}
|
||||
|
||||
const saveTask = () => {
|
||||
if (!taskForm.value.text.trim()) {
|
||||
showNotification('Task name is required', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
const taskData = {
|
||||
text: this.taskForm.text,
|
||||
start_date: gantt.date.str_to_date("%Y-%m-%d")(this.taskForm.start_date),
|
||||
duration: parseInt(this.taskForm.duration),
|
||||
progress: parseFloat(this.taskForm.progress)
|
||||
text: taskForm.value.text,
|
||||
start_date: gantt.date.str_to_date("%Y-%m-%d")(taskForm.value.start_date),
|
||||
duration: parseInt(taskForm.value.duration),
|
||||
progress: parseFloat(taskForm.value.progress)
|
||||
}
|
||||
|
||||
if (this.showEditModal) {
|
||||
Object.assign(this.currentTask, taskData)
|
||||
gantt.updateTask(this.currentTaskId)
|
||||
if (showEditModal.value) {
|
||||
Object.assign(currentTask.value, taskData)
|
||||
gantt.updateTask(currentTaskId.value)
|
||||
gantt.render()
|
||||
this.showEditModal = false
|
||||
this.showNotification('Task updated successfully', 'success')
|
||||
} else if (this.showAddModal) {
|
||||
showEditModal.value = false
|
||||
showNotification('Task updated successfully', 'success')
|
||||
} else if (showAddModal.value) {
|
||||
const newTaskId = gantt.uid()
|
||||
const newTask = {
|
||||
id: newTaskId,
|
||||
...taskData
|
||||
}
|
||||
|
||||
if (this.currentTaskId) {
|
||||
newTask.parent = this.currentTaskId
|
||||
if (currentTaskId.value) {
|
||||
newTask.parent = currentTaskId.value
|
||||
}
|
||||
|
||||
gantt.addTask(newTask)
|
||||
gantt.refreshData()
|
||||
gantt.selectTask(newTaskId)
|
||||
gantt.showTask(newTaskId)
|
||||
this.showAddModal = false
|
||||
this.showNotification('Task added successfully', 'success')
|
||||
showAddModal.value = false
|
||||
showNotification('Task added successfully', 'success')
|
||||
}
|
||||
|
||||
this.resetForm()
|
||||
},
|
||||
resetForm() {
|
||||
this.currentTaskId = null
|
||||
this.currentTask = null
|
||||
this.taskForm = {
|
||||
resetForm()
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
currentTaskId.value = null
|
||||
currentTask.value = null
|
||||
taskForm.value = {
|
||||
text: '',
|
||||
start_date: '',
|
||||
duration: 3,
|
||||
progress: 0
|
||||
}
|
||||
},
|
||||
closeModal() {
|
||||
this.showDeleteModal = false
|
||||
this.showEditModal = false
|
||||
this.showAddModal = false
|
||||
this.resetForm()
|
||||
},
|
||||
showNotification(message, type = 'info') {
|
||||
}
|
||||
|
||||
const closeModal = () => {
|
||||
showDeleteModal.value = false
|
||||
showEditModal.value = false
|
||||
showAddModal.value = false
|
||||
resetForm()
|
||||
}
|
||||
|
||||
const showNotification = (message, type = 'info') => {
|
||||
const notification = document.createElement('div')
|
||||
notification.className = `notification notification-${type}`
|
||||
notification.innerHTML = `
|
||||
@@ -512,28 +533,53 @@ export default {
|
||||
notification.remove()
|
||||
}
|
||||
}, 4000)
|
||||
},
|
||||
markCompleted() {
|
||||
}
|
||||
|
||||
const markCompleted = () => {
|
||||
const selectedTask = gantt.getSelectedId()
|
||||
if (selectedTask) {
|
||||
let task = gantt.getTask(selectedTask)
|
||||
task.progress = task.progress === 1 ? 0 : 1
|
||||
gantt.updateTask(selectedTask)
|
||||
gantt.render()
|
||||
this.showNotification(
|
||||
showNotification(
|
||||
`Task marked as ${task.progress === 1 ? 'completed' : 'incomplete'}`,
|
||||
'success'
|
||||
)
|
||||
} else {
|
||||
this.showNotification('Please select a task to mark as completed', 'warning')
|
||||
}
|
||||
}
|
||||
showNotification('Please select a task to mark as completed', 'warning')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initGantt()
|
||||
|
||||
// Prevent GridStack drag when interacting with Gantt chart
|
||||
const ganttElement = ganttContainer.value
|
||||
if (ganttElement) {
|
||||
ganttElement.addEventListener('mousedown', (e) => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
|
||||
ganttElement.addEventListener('dragstart', (e) => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
|
||||
ganttElement.addEventListener('drag', (e) => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (gantt.$container) {
|
||||
gantt.clearAll()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gantt-container">
|
||||
<div class="gantt-container no-grid-drag">
|
||||
<div class="gantt-toolbar">
|
||||
<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">
|
||||
@@ -557,9 +603,8 @@ export default {
|
||||
Toggle Complete
|
||||
</button>
|
||||
</div>
|
||||
<div ref="ganttContainer" class="gantt-chart"></div>
|
||||
<div ref="ganttContainer" class="gantt-chart no-grid-drag"></div>
|
||||
|
||||
<!-- Delete Modal -->
|
||||
<div v-if="showDeleteModal" class="modal-overlay" @click="closeModal">
|
||||
<div class="modal-container" @click.stop>
|
||||
<div class="modal-header">
|
||||
@@ -586,7 +631,6 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Modal -->
|
||||
<div v-if="showEditModal" class="modal-overlay" @click="closeModal">
|
||||
<div class="modal-container" @click.stop>
|
||||
<div class="modal-header">
|
||||
@@ -659,7 +703,6 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Modal -->
|
||||
<div v-if="showAddModal" class="modal-overlay" @click="closeModal">
|
||||
<div class="modal-container" @click.stop>
|
||||
<div class="modal-header">
|
||||
@@ -965,6 +1008,7 @@ export default {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
@@ -1024,6 +1068,7 @@ export default {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -1046,6 +1091,7 @@ export default {
|
||||
opacity: 0;
|
||||
transform: translateY(-16px) scale(0.98);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
@@ -1234,6 +1280,7 @@ export default {
|
||||
opacity: 0;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
|
||||
Reference in New Issue
Block a user