mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 22:39:34 +00:00
[timeline] sticky header, scroll to hour....
This commit is contained in:
1 parent
1fe2bd1c9b
commit
affc96fc73
9 files changed
+68
-37
No files matched your search
@@ -30,7 +30,11 @@ export default {
|
|||||||
flex: 1 1 100%
|
flex: 1 1 100%
|
||||||
|
|
||||||
#main-content
|
#main-content
|
||||||
height: fit-content
|
overflow-y: scroll
|
||||||
|
height: 100%
|
||||||
|
max-height: 100%
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
|
||||||
.split-pane-right-side
|
.split-pane-right-side
|
||||||
width: 100vw
|
width: 100vw
|
||||||
|
|||||||
@@ -279,7 +279,6 @@ export default {
|
|||||||
width = width - (parentNotSameOverlaps.length * (10 / sameOverlapsLength))
|
width = width - (parentNotSameOverlaps.length * (10 / sameOverlapsLength))
|
||||||
left = left + (5 * parentNotSameOverlaps.length - ((10 * parentNotSameOverlaps.length / sameOverlapsLength) * (this.eventPosition - parentNotSameOverlaps.length)))
|
left = left + (5 * parentNotSameOverlaps.length - ((10 * parentNotSameOverlaps.length / sameOverlapsLength) * (this.eventPosition - parentNotSameOverlaps.length)))
|
||||||
}
|
}
|
||||||
zIdnex = 10
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.vuecal.minEventWidth && width < this.vuecal.minEventWidth) {
|
if (this.vuecal.minEventWidth && width < this.vuecal.minEventWidth) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</all-day-bar>
|
</all-day-bar>
|
||||||
<div class="vuecal__bg" :class="{ vuecal__flex: !hasTimeColumn }" column="column">
|
<div class="vuecal__bg" :class="{ vuecal__flex: !hasTimeColumn }" column="column" ref="vuecal_scroll">
|
||||||
<div class="vuecal__flex" row="row" grow="grow">
|
<div class="vuecal__flex" row="row" grow="grow">
|
||||||
<div class="vuecal__time-column" v-if="hasTimeColumn">
|
<div class="vuecal__time-column" v-if="hasTimeColumn">
|
||||||
<div class="vuecal__all-day-text" v-if="showAllDayEvents && cellOrSplitMinWidth && !(isDayView && !minSplitWidth)" :style="{ height: allDayBar.height }">
|
<div class="vuecal__all-day-text" v-if="showAllDayEvents && cellOrSplitMinWidth && !(isDayView && !minSplitWidth)" :style="{ height: allDayBar.height }">
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="vuecal__flex vuecal__cells vuecal__scrollable-body" :class="`${view.id}-view`" grow="grow" :wrap="!cellOrSplitMinWidth || !isWeekView" :column="!!cellOrSplitMinWidth">
|
<div class="vuecal__flex vuecal__cells vuecal__scrollable-body" :class="`${view.id}-view`" grow="grow" :wrap="!cellOrSplitMinWidth || !isWeekView" :column="!!cellOrSplitMinWidth">
|
||||||
<weekdays-headings v-if="cellOrSplitMinWidth && isWeekView" :transition-direction="transitionDirection" :week-days="weekDays" :switch-to-narrower-view="switchToNarrowerView" :style="cellOrSplitMinWidth ? `min-width: ${cellOrSplitMinWidth}px` : ''" :unscheduledTime="unscheduledTime">
|
<weekdays-headings v-if="cellOrSplitMinWidth && isWeekView" :transition-direction="transitionDirection" :week-days="weekDays" :switch-to-narrower-view="switchToNarrowerView" :style="cellOrSplitMinWidth ? `min-width: ${cellOrSplitMinWidth}px` : ''" :unscheduledTime="unscheduledTime" ref="vuecal_weekday_heading">
|
||||||
<template #weekday-heading="{ heading, view }" v-if="$slots['weekday-heading']">
|
<template #weekday-heading="{ heading, view }" v-if="$slots['weekday-heading']">
|
||||||
<slot name="weekday-heading" :heading="heading" :view="view"></slot>
|
<slot name="weekday-heading" :heading="heading" :view="view"></slot>
|
||||||
</template>
|
</template>
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</all-day-bar>
|
</all-day-bar>
|
||||||
|
|
||||||
<div class="vuecal__flex" :ref="el => cellsEl = el" grow="grow" :wrap="!cellOrSplitMinWidth || !isWeekView" :style="cellOrSplitMinWidth ? `min-width: ${cellOrSplitMinWidth}px` : ''">
|
<div class="vuecal__flex vuecal__cells-body" :ref="el => cellsEl = el" grow="grow" :wrap="!cellOrSplitMinWidth || !isWeekView" :style="cellOrSplitMinWidth ? `min-width: ${cellOrSplitMinWidth}px` : ''">
|
||||||
<!-- TU -->
|
<!-- TU -->
|
||||||
<vuecal-cell v-for="(cell, i) in viewCells" :key="i" :options="$props" :edit-events="editEvents" :data="cell" :cell-width="hideWeekdays.length && (isWeekView || isMonthView) && cellWidth" :min-timestamp="minTimestamp" :max-timestamp="maxTimestamp" :cell-splits="hasSplits && daySplits || []">
|
<vuecal-cell v-for="(cell, i) in viewCells" :key="i" :options="$props" :edit-events="editEvents" :data="cell" :cell-width="hideWeekdays.length && (isWeekView || isMonthView) && cellWidth" :min-timestamp="minTimestamp" :max-timestamp="maxTimestamp" :cell-splits="hasSplits && daySplits || []">
|
||||||
<template #cell-content="{ events, split, selectCell }">
|
<template #cell-content="{ events, split, selectCell }">
|
||||||
@@ -186,6 +186,7 @@ export default {
|
|||||||
|
|
||||||
props: {
|
props: {
|
||||||
activeView: { type: String, default: 'week' },
|
activeView: { type: String, default: 'week' },
|
||||||
|
scrollToHour: { type: Number, default: 0 }, // In minutes.
|
||||||
// Only used if there are daySplits with minSplitWidth, to add the same height top spacer on time column.
|
// Only used if there are daySplits with minSplitWidth, to add the same height top spacer on time column.
|
||||||
allDayBarHeight: { type: [String, Number], default: '25px' },
|
allDayBarHeight: { type: [String, Number], default: '25px' },
|
||||||
cellClickHold: { type: Boolean, default: true },
|
cellClickHold: { type: Boolean, default: true },
|
||||||
@@ -554,6 +555,9 @@ export default {
|
|||||||
}
|
}
|
||||||
: {})
|
: {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$refs['vuecal_scroll'].scrollTop = this.scrollToHour * this.timeCellHeight
|
||||||
|
|
||||||
this.$emit('view-change', params)
|
this.$emit('view-change', params)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1302,6 +1306,13 @@ export default {
|
|||||||
: {})
|
: {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.$refs['vuecal_scroll'].addEventListener('scroll', () => {
|
||||||
|
this.$refs['vuecal_weekday_heading'].onTimelineScroll(this.$refs['vuecal_scroll'].scrollTop)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.viewportTimelineOffset = this.$refs['vuecal_scroll'].getBoundingClientRect().top
|
||||||
|
this.$refs['vuecal_scroll'].scrollTop = this.scrollToHour * this.timeCellHeight
|
||||||
|
|
||||||
this.$emit('ready', params)
|
this.$emit('ready', params)
|
||||||
this.ready = true
|
this.ready = true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template lang="pug">
|
<template lang="pug">
|
||||||
//- weekdays-headings are on week view only.
|
//- weekdays-headings are on week view only.
|
||||||
.vuecal__flex.vuecal__weekdays-headings
|
.vuecal__flex.vuecal__weekdays-headings(
|
||||||
|
ref="vuecal_weekday_heading")
|
||||||
template(v-for="(heading, i) in headings" :key="i")
|
template(v-for="(heading, i) in headings" :key="i")
|
||||||
.vuecal__flex.vuecal__heading(
|
.vuecal__flex.vuecal__heading(
|
||||||
v-if="!heading.hide"
|
v-if="!heading.hide"
|
||||||
@@ -31,7 +32,8 @@ export default {
|
|||||||
transitionDirection: { type: String, default: 'right' },
|
transitionDirection: { type: String, default: 'right' },
|
||||||
weekDays: { type: Array, default: () => [] },
|
weekDays: { type: Array, default: () => [] },
|
||||||
switchToNarrowerView: { type: Function, default: () => {} },
|
switchToNarrowerView: { type: Function, default: () => {} },
|
||||||
unscheduledTime: { type: Array, default: [] }
|
unscheduledTime: { type: Array, default: [] },
|
||||||
|
// viewPortOffset: { type: Number, default: 0 },
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -48,7 +50,10 @@ export default {
|
|||||||
name: heading.name,
|
name: heading.name,
|
||||||
initials: heading.initials,
|
initials: heading.initials,
|
||||||
...(heading.today ? { today: heading.today } : {})
|
...(heading.today ? { today: heading.today } : {})
|
||||||
})
|
}),
|
||||||
|
onTimelineScroll(viewPortOffset) {
|
||||||
|
this.$refs['vuecal_weekday_heading'].style.top = `${viewPortOffset}px`
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -74,11 +74,7 @@ export default {
|
|||||||
border-bottom: 1px solid rgba(33, 33, 33, 0.08)
|
border-bottom: 1px solid rgba(33, 33, 33, 0.08)
|
||||||
gap: 25px
|
gap: 25px
|
||||||
flex-wrap: wrap
|
flex-wrap: wrap
|
||||||
position: sticky
|
flex: 0 0 auto
|
||||||
top: 0
|
|
||||||
z-index: 9999
|
|
||||||
background: white
|
|
||||||
|
|
||||||
|
|
||||||
.subheader-icon-button
|
.subheader-icon-button
|
||||||
border: 1px solid #ABABAB
|
border: 1px solid #ABABAB
|
||||||
@@ -100,6 +96,7 @@ export default {
|
|||||||
.subheader-input
|
.subheader-input
|
||||||
max-width: 250px !important
|
max-width: 250px !important
|
||||||
min-width: 250px
|
min-width: 250px
|
||||||
|
height: 56px
|
||||||
|
|
||||||
&:deep(.v-input__details)
|
&:deep(.v-input__details)
|
||||||
display: none
|
display: none
|
||||||
@@ -107,11 +104,7 @@ export default {
|
|||||||
&.disabled
|
&.disabled
|
||||||
pointer-events: none !important
|
pointer-events: none !important
|
||||||
|
|
||||||
|
@media (max-width: 1312px)
|
||||||
.date-wrapper
|
|
||||||
flex: 0 1 385px
|
|
||||||
|
|
||||||
@media (max-width: 1316px)
|
|
||||||
.date-wrapper
|
.date-wrapper
|
||||||
order: 3
|
order: 3
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,9 @@
|
|||||||
:unscheduledTime="calData.unscheduled_times"
|
:unscheduledTime="calData.unscheduled_times"
|
||||||
:overlaps-per-time-step="false"
|
:overlaps-per-time-step="false"
|
||||||
:showTimeInCells="false"
|
:showTimeInCells="false"
|
||||||
:time-cell-height="100"
|
:time-cell-height="timeCellHeight"
|
||||||
:snap-to-time="15"
|
:snap-to-time="8 * 60"
|
||||||
|
:scroll-to-hour="calConfig.scrollHour"
|
||||||
:min-cell-width="300"
|
:min-cell-width="300"
|
||||||
@ready="onReady()"
|
@ready="onReady()"
|
||||||
@view-change="weekChanged"
|
@view-change="weekChanged"
|
||||||
@@ -94,7 +95,7 @@ export default {
|
|||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
default() {
|
default() {
|
||||||
return {startHour: 8, endHour: 16, date: new Date()}
|
return {date: new Date(), scrollHour: 7}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -112,12 +113,13 @@ export default {
|
|||||||
},
|
},
|
||||||
focusedEventId: null,
|
focusedEventId: null,
|
||||||
showCompleteModal: null,
|
showCompleteModal: null,
|
||||||
showDeleteModal: null
|
showDeleteModal: null,
|
||||||
|
timeCellHeight: 100,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this._scrollToDefaultTime()
|
this._scrollToDefaultTime()
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@@ -137,7 +139,7 @@ export default {
|
|||||||
|
|
||||||
onReady() {
|
onReady() {
|
||||||
this.scrollToYesterday()
|
this.scrollToYesterday()
|
||||||
this.correctTimecolumnMargin()
|
this.correctMargins()
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToYesterday() {
|
scrollToYesterday() {
|
||||||
@@ -148,9 +150,10 @@ export default {
|
|||||||
scrollContainer.scrollLeft = yesterdayCell.offsetLeft - scrollContainer.offsetLeft - 20
|
scrollContainer.scrollLeft = yesterdayCell.offsetLeft - scrollContainer.offsetLeft - 20
|
||||||
},
|
},
|
||||||
|
|
||||||
correctTimecolumnMargin() {
|
correctMargins() {
|
||||||
const heightOfDayHeader = document.getElementsByClassName('vuecal__heading')[0].clientHeight
|
const heightOfDayHeader = document.getElementsByClassName('vuecal__heading')[0].clientHeight
|
||||||
document.getElementsByClassName('vuecal__time-column')[0].style.marginTop = `${heightOfDayHeader}px`
|
document.getElementsByClassName('vuecal__time-column')[0].style.marginTop = `${heightOfDayHeader}px`
|
||||||
|
document.getElementsByClassName('vuecal__cells-body')[0].style.marginTop = `${heightOfDayHeader}px`
|
||||||
},
|
},
|
||||||
|
|
||||||
getHeadingDate(value) {
|
getHeadingDate(value) {
|
||||||
@@ -211,7 +214,8 @@ export default {
|
|||||||
|
|
||||||
.calendar-wrapper
|
.calendar-wrapper
|
||||||
width: 100%
|
width: 100%
|
||||||
padding-top: 50px
|
height: 100%
|
||||||
|
// padding-top: 50px
|
||||||
|
|
||||||
&:deep()
|
&:deep()
|
||||||
.vuecal__cells
|
.vuecal__cells
|
||||||
@@ -252,6 +256,16 @@ export default {
|
|||||||
.vuecal__cell:before
|
.vuecal__cell:before
|
||||||
border: none
|
border: none
|
||||||
|
|
||||||
|
.vuecal__scrollable-body
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
.vuecal__weekdays-headings
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
left: 20px
|
||||||
|
z-index: 999
|
||||||
|
background: white
|
||||||
|
|
||||||
.vuecal__heading
|
.vuecal__heading
|
||||||
height: fit-content
|
height: fit-content
|
||||||
min-height: 100%
|
min-height: 100%
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ export default {
|
|||||||
dataLoaded: false,
|
dataLoaded: false,
|
||||||
config: {
|
config: {
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
startHour: 8,
|
scrollHour: 7,
|
||||||
endHour: 16,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -70,9 +69,7 @@ export default {
|
|||||||
time.surname = this.timelineData.surname
|
time.surname = this.timelineData.surname
|
||||||
})
|
})
|
||||||
|
|
||||||
// format working hours
|
this.config.scrollHour = Number(this.timelineData.work_hours_from.split(':')[0]) - 1
|
||||||
this.config.startHour = Number(this.timelineData.work_hours_from.split(':')[0]) - 1
|
|
||||||
this.config.endHour = Number(this.timelineData.work_hours_to.split(':')[0]) + 1
|
|
||||||
},
|
},
|
||||||
|
|
||||||
triggerToast(message) {
|
triggerToast(message) {
|
||||||
@@ -102,5 +99,10 @@ export default {
|
|||||||
.w-loadable
|
.w-loadable
|
||||||
text-align: center
|
text-align: center
|
||||||
padding-top: 20px
|
padding-top: 20px
|
||||||
height: 100%
|
height: calc( 100% - 121px )
|
||||||
|
|
||||||
|
@media (max-width: 1312px)
|
||||||
|
.w-loadable
|
||||||
|
height: calc( 100% - 202px )
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -80,6 +80,7 @@ export default {
|
|||||||
border-bottom: 1px solid rgba(33, 33, 33, 0.08)
|
border-bottom: 1px solid rgba(33, 33, 33, 0.08)
|
||||||
gap: 25px
|
gap: 25px
|
||||||
flex-wrap: wrap
|
flex-wrap: wrap
|
||||||
|
flex: 0 0 auto
|
||||||
|
|
||||||
.subheader-icon-button
|
.subheader-icon-button
|
||||||
border: 1px solid #ABABAB
|
border: 1px solid #ABABAB
|
||||||
@@ -109,10 +110,7 @@ export default {
|
|||||||
pointer-events: none !important
|
pointer-events: none !important
|
||||||
|
|
||||||
|
|
||||||
.date-wrapper
|
@media (max-width: 1312px)
|
||||||
flex: 0 1 385px
|
|
||||||
|
|
||||||
@media (max-width: 1316px)
|
|
||||||
.date-wrapper
|
.date-wrapper
|
||||||
order: 3
|
order: 3
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<A-team-filter @dayChanged="getDayData" />
|
<A-team-filter @dayChanged="getDayData" />
|
||||||
|
|
||||||
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
<W-loadable :content="timelineData" class="w-loadable" empty-message="Nepodarilo sa nacitat data!">
|
||||||
<Z-timeline />
|
<Z-timeline />
|
||||||
</W-loadable>
|
</W-loadable>
|
||||||
@@ -38,5 +39,9 @@ export default {
|
|||||||
.w-loadable
|
.w-loadable
|
||||||
text-align: center
|
text-align: center
|
||||||
padding-top: 20px
|
padding-top: 20px
|
||||||
height: 100%
|
height: calc( 100% - 121px )
|
||||||
|
|
||||||
|
@media (max-width: 1312px)
|
||||||
|
.w-loadable
|
||||||
|
height: calc( 100% - 202px )
|
||||||
</style>
|
</style>
|
||||||
Reference in new issue
Block a user