mirror of
https://github.com/tenrok/vue-ganttastic.git
synced 2026-06-19 21:40:34 +03:00
205 lines
5.1 KiB
Vue
205 lines
5.1 KiB
Vue
<template>
|
|
<div
|
|
class="g-gantt-row"
|
|
ref="g-gantt-row"
|
|
:style="{ height: `${$parent.rowHeight}px` }"
|
|
v-on="$listeners"
|
|
>
|
|
<div class="g-gantt-row-label" :style="rowLabelStyle">
|
|
<slot name="label">
|
|
{{ label }}
|
|
</slot>
|
|
</div>
|
|
<div
|
|
class="g-gantt-row-bars-container"
|
|
ref="barContainer"
|
|
:style="barsContainerStyle"
|
|
@dragover="onDragover($event)"
|
|
@dragleave="onDragleave($event)"
|
|
@drop="onDrop($event)"
|
|
@dblclick="onDoubleClick($event)"
|
|
@mouseover="onMouseover()"
|
|
@mouseleave="onMouseleave()"
|
|
>
|
|
<g-gantt-bar
|
|
v-for="(bar, index) in bars"
|
|
:key="`ganttastic_bar_${index}`"
|
|
:bar="bar"
|
|
ref="ganttBar"
|
|
:bar-start="barStart"
|
|
:bar-end="barEnd"
|
|
:bar-container="barContainer"
|
|
:all-bars-in-row="bars"
|
|
>
|
|
<template #bar-label="{ bar }">
|
|
<slot name="bar-label" :bar="bar" />
|
|
</template>
|
|
</g-gantt-bar>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import GGanttBar from './GGanttBar.vue'
|
|
import moment from 'moment'
|
|
|
|
export default {
|
|
name: 'GGanttRow',
|
|
|
|
components: {
|
|
GGanttBar,
|
|
},
|
|
|
|
props: {
|
|
label: { type: String, default: 'Row' },
|
|
bars: { type: Array, default: () => [] },
|
|
barStart: { type: String, required: true }, // property name of the bar objects that represents the start datetime
|
|
barEnd: { type: String, required: true }, // property name of the bar objects that represents the end datetime,
|
|
highlightOnHover: Boolean,
|
|
},
|
|
|
|
inject: [
|
|
'ganttChartProps',
|
|
'getThemeColors',
|
|
'getTimeCount',
|
|
'getChartStart',
|
|
'getChartEnd',
|
|
'getDefaultBarLength',
|
|
'getTimeUnit',
|
|
'getTimeFormat',
|
|
],
|
|
|
|
data() {
|
|
return {
|
|
barContainer: {},
|
|
timeUnit: this.getTimeUnit(),
|
|
timeFormat: this.getTimeFormat(),
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
rowLabelStyle() {
|
|
return {
|
|
width: this.ganttChartProps.rowLabelWidth,
|
|
height: this.ganttChartProps.rowHeight,
|
|
background: this.$parent.themeColors.ternary,
|
|
color: this.$parent.themeColors.text,
|
|
}
|
|
},
|
|
|
|
barsContainerStyle() {
|
|
return {
|
|
width: `${100 - this.ganttChartProps.rowLabelWidth.replace('%', '')}%`,
|
|
}
|
|
},
|
|
},
|
|
|
|
mounted() {
|
|
this.barContainer = this.$refs.barContainer.getBoundingClientRect()
|
|
window.addEventListener('resize', this.onWindowResize)
|
|
},
|
|
|
|
methods: {
|
|
onDragover(e) {
|
|
e.preventDefault() // enables dropping content on row
|
|
if (this.highlightOnHover) {
|
|
console.log({
|
|
backgroundColor: this.$refs['g-gantt-row'].style.backgroundColor,
|
|
})
|
|
this.$refs[
|
|
'g-gantt-row'
|
|
].style.backgroundColor = this.getThemeColors().hoverHighlight
|
|
console.log({
|
|
backgroundColor: this.$refs['g-gantt-row'].style.backgroundColor,
|
|
})
|
|
}
|
|
},
|
|
|
|
onDragleave() {
|
|
this.$refs['g-gantt-row'].style.backgroundColor = null
|
|
},
|
|
|
|
onDrop(e) {
|
|
let barContainer = this.$refs.barContainer.getBoundingClientRect()
|
|
let xPos = e.clientX - barContainer.left
|
|
let timeDiffFromStart = (xPos / barContainer.width) * this.getTimeCount()
|
|
let time = moment(this.getChartStart()).add(
|
|
timeDiffFromStart,
|
|
this.timeUnit
|
|
)
|
|
let bar = this.bars.find((bar) =>
|
|
time.isBetween(bar[this.barStart], bar[this.barEnd])
|
|
)
|
|
this.$emit('drop', { event: e, bar, time: time.format(this.timeFormat) })
|
|
},
|
|
|
|
onDoubleClick(e) {
|
|
let barContainer = this.$refs.barContainer.getBoundingClientRect()
|
|
let xPos = e.clientX - barContainer.left
|
|
let timeDiffFromStart = (xPos / barContainer.width) * this.getTimeCount()
|
|
let time = moment(this.getChartStart()).add(
|
|
timeDiffFromStart,
|
|
this.timeUnit
|
|
)
|
|
let bar = {}
|
|
bar[this.barStart] = time
|
|
bar[this.barEnd] = time.add(this.getDefaultBarLength(), this.timeUnit)
|
|
|
|
bar.ganttBarConfig = { handles: true }
|
|
this.bars.push(bar)
|
|
},
|
|
|
|
onMouseover() {
|
|
if (this.highlightOnHover) {
|
|
this.$refs[
|
|
'g-gantt-row'
|
|
].style.backgroundColor = this.getThemeColors().hoverHighlight
|
|
}
|
|
},
|
|
|
|
onMouseleave() {
|
|
this.$refs['g-gantt-row'].style.backgroundColor = null
|
|
},
|
|
|
|
onWindowResize() {
|
|
// re-initialize the barContainer DOMRect variable, which will trigger re-rendering in the gantt bars
|
|
this.barContainer = this.$refs.barContainer.getBoundingClientRect()
|
|
},
|
|
},
|
|
|
|
watch: {
|
|
'ganttChartProps.rowLabelWidth': function () {
|
|
this.barContainer = this.$refs.barContainer.getBoundingClientRect()
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.g-gantt-row {
|
|
display: flex;
|
|
width: 100%;
|
|
height: 40px;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.g-gantt-row > .g-gantt-row-label {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 20%;
|
|
background: #e8e8e8;
|
|
color: #424242;
|
|
font-size: 0.9em;
|
|
z-index: 3;
|
|
overflow: hidden;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.g-gantt-row > .g-gantt-row-bars-container {
|
|
position: relative;
|
|
border-top: 1px solid #eaeaea;
|
|
width: 70%;
|
|
border-bottom: 1px solid #eaeaea;
|
|
}
|
|
</style> |