292 lines
7.9 KiB
Vue
292 lines
7.9 KiB
Vue
<template lang="pug">
|
|
.schedule.flex-1.flex.flex-col.relative(
|
|
:style="{width: openSidebar ? 'calc(100vw - 320px)' : 'calc(100vw - 160px)'}"
|
|
)
|
|
calendar-header.w-full.mb-1(v-model="displayType")
|
|
.schedule-body.h-full.bg-white.w-full(:class="{rounded: !expandedDisplayType}")
|
|
.column-wrapper.flex.ml-20(:style="columnWrapperWidth")
|
|
calendar-column(
|
|
v-for="date in dateRange",
|
|
:key="date",
|
|
:date="date",
|
|
:style="columnHeight",
|
|
:expanded-display-type="expandedDisplayType",
|
|
:day-start-time="validateStartTime"
|
|
:day-end-time="validateEndTime"
|
|
)
|
|
.flex.relative(
|
|
:style="expandedDisplayType ? backgroundWrapperWidth : {}",
|
|
:class="{'border-bottom': expandedDisplayType}"
|
|
)
|
|
.time-coil-wrapper.left-0.-mt-12
|
|
calendar-clock-column(
|
|
:time-coil="timeCoil",
|
|
:current-time="currentTime",
|
|
:is-current-week="isCurrentWeek",
|
|
:day-end-time="validateEndTime"
|
|
)
|
|
.time-circle-indicator.left-74px.h-3.w-3.rounded-full.absolute(
|
|
v-if="isShownIndicator",
|
|
:style="circleIndicatorLocation"
|
|
)
|
|
span.time-line-indicator.block.left-20.absolute(
|
|
v-if="isShownIndicator",
|
|
:style="lineIndicatorLocation"
|
|
)
|
|
calendar-background.flex-1
|
|
.w-full.h-3.bg-white.footer(v-if="expandedDisplayType")
|
|
</template>
|
|
|
|
<script>
|
|
import CalendarHeader from "@/pages/newCalendar/components/CalendarHeader";
|
|
import CalendarBackground from "@/pages/newCalendar/components/CalendarBackground.vue";
|
|
import CalendarClockColumn from "@/pages/newCalendar/components/CalendarClockColumn.vue";
|
|
import CalendarColumn from "@/pages/newCalendar/components/CalendarColumn.vue";
|
|
import {
|
|
convertTime,
|
|
verifyTime,
|
|
} from "@/pages/newCalendar/utils/calendarFunctions.js";
|
|
import { mapState } from "vuex";
|
|
import * as moment from "moment/moment";
|
|
export default {
|
|
name: "CalendarWrapper",
|
|
components: {
|
|
CalendarHeader,
|
|
CalendarBackground,
|
|
CalendarClockColumn,
|
|
CalendarColumn,
|
|
},
|
|
props: {
|
|
openSidebar: Boolean,
|
|
},
|
|
data() {
|
|
return {
|
|
displayType: "expanded",
|
|
currentTime: "",
|
|
isCurrentWeek: true,
|
|
isShownIndicator: true,
|
|
timeCoil: [],
|
|
timer: null,
|
|
pixelsPerHour: 76,
|
|
};
|
|
},
|
|
computed: {
|
|
...mapState({
|
|
workingHours: (state) => state.calendar.workingHours,
|
|
selectedDates: (state) => state.calendar.selectedDates,
|
|
}),
|
|
hours() {
|
|
return convertTime(this.currentTime, 0, -6);
|
|
},
|
|
minutes() {
|
|
return convertTime(this.currentTime, 3, -3);
|
|
},
|
|
hoursMinutes() {
|
|
return this.currentTime.slice(0, -3);
|
|
},
|
|
pixelsPerMinute() {
|
|
return this.pixelsPerHour / 60;
|
|
},
|
|
backgroundHeight() {
|
|
return (
|
|
(this.validateEndTime - this.validateStartTime) * this.pixelsPerHour
|
|
);
|
|
},
|
|
expandedDisplayType() {
|
|
return this.displayType === "expanded";
|
|
},
|
|
dateRange() {
|
|
let diff = this.selectedDates?.to.diff(this.selectedDates?.from, "days");
|
|
let range = [];
|
|
for (let i = 0; i <= diff; i++) {
|
|
range.push(this.selectedDates?.from.clone().add(i, "day"));
|
|
}
|
|
return range;
|
|
},
|
|
validateStartTime() {
|
|
return verifyTime(this.workingHours.start);
|
|
},
|
|
validateEndTime() {
|
|
return verifyTime(this.workingHours.end);
|
|
},
|
|
columnHeight() {
|
|
return this.expandedDisplayType
|
|
? {
|
|
height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
|
|
width: "380px",
|
|
}
|
|
: {
|
|
height: `${this.timeCoil.length * this.pixelsPerHour + 96}px`,
|
|
width: this.openSidebar
|
|
? `calc((100vw - 320px - 80px) / ${this.dateRange.length})`
|
|
: `calc((100vw - 160px - 80px) / ${this.dateRange.length})`,
|
|
};
|
|
},
|
|
columnWrapperWidth() {
|
|
return this.expandedDisplayType
|
|
? {
|
|
width: `${380 * this.dateRange.length}px`,
|
|
}
|
|
: {
|
|
width: this.openSidebar
|
|
? "calc(100vw - 320px - 80px)"
|
|
: "calc(100vw - 160px - 80px)",
|
|
};
|
|
},
|
|
backgroundWrapperWidth() {
|
|
return {
|
|
width: `${380 * this.dateRange.length + 80}px`,
|
|
};
|
|
},
|
|
lineIndicatorLocation() {
|
|
return {
|
|
top: `${this.calculateIndicatorLocation()}px`,
|
|
};
|
|
},
|
|
circleIndicatorLocation() {
|
|
return {
|
|
top: `${this.calculateIndicatorLocation() + 42}px`,
|
|
};
|
|
},
|
|
},
|
|
methods: {
|
|
changeCurrentTime() {
|
|
this.currentTime = moment().format("HH:mm:ss");
|
|
},
|
|
timeCoilInitialization() {
|
|
this.timeCoil = [];
|
|
for (let i = this.validateStartTime; i < this.validateEndTime; i++) {
|
|
if (
|
|
i === this.hours &&
|
|
this.hours !== this.validateEndTime &&
|
|
this.isCurrentWeek
|
|
) {
|
|
this.timeCoil.push(this.hoursMinutes);
|
|
} else this.timeCoil.push(`${i}:00`);
|
|
}
|
|
},
|
|
changeTimeCoil() {
|
|
this.timeCoil = this.timeCoil.map((elem) => {
|
|
if (convertTime(elem, 0, -3) === this.hours) {
|
|
return this.hoursMinutes;
|
|
}
|
|
return elem.slice(0, -3) + ":00";
|
|
});
|
|
},
|
|
startTimer() {
|
|
if (
|
|
this.hours >= this.validateStartTime &&
|
|
this.hours < this.validateEndTime
|
|
) {
|
|
this.timer = setInterval(() => {
|
|
this.changeCurrentTime();
|
|
this.changeTimeCoil();
|
|
}, 5000);
|
|
}
|
|
},
|
|
stopTimer() {
|
|
clearInterval(this.timer);
|
|
this.timer = null;
|
|
},
|
|
calculateIndicatorLocation() {
|
|
let newTime = this.currentTime
|
|
.split(":")
|
|
.map((elem) => parseInt(elem, 10));
|
|
let result =
|
|
(newTime[0] - this.validateStartTime) * this.pixelsPerHour +
|
|
newTime[1] * this.pixelsPerMinute;
|
|
if (result > this.backgroundHeight || result < 0) {
|
|
this.isShownIndicator = false;
|
|
return 0;
|
|
}
|
|
return result;
|
|
},
|
|
},
|
|
watch: {
|
|
currentTime() {
|
|
if (
|
|
this.hours === this.validateEndTime &&
|
|
this.minutes > 0 &&
|
|
this.timer
|
|
) {
|
|
this.stopTimer();
|
|
this.timeCoilInitialization();
|
|
}
|
|
},
|
|
selectedDates: {
|
|
deep: true,
|
|
handler(newValue) {
|
|
this.isCurrentWeek =
|
|
newValue?.from.isSame(moment().clone().startOf("week")) &&
|
|
newValue?.to.isSame(moment().clone().endOf("week"));
|
|
this.isShownIndicator = this.isCurrentWeek;
|
|
if (this.timer) {
|
|
this.stopTimer();
|
|
this.timeCoilInitialization();
|
|
}
|
|
if (this.isCurrentWeek) {
|
|
this.changeCurrentTime();
|
|
this.timeCoilInitialization();
|
|
this.startTimer();
|
|
}
|
|
},
|
|
},
|
|
},
|
|
mounted() {
|
|
this.changeCurrentTime();
|
|
this.timeCoilInitialization();
|
|
this.startTimer();
|
|
},
|
|
beforeUnmount() {
|
|
this.stopTimer();
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="sass" scoped>
|
|
.schedule-body
|
|
overflow-x: auto
|
|
border-top-left-radius: 4px
|
|
border-top-right-radius: 4px
|
|
&::-webkit-scrollbar-track:horizontal
|
|
margin: 0 24px 0 24px
|
|
|
|
.background
|
|
background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)
|
|
|
|
.time-coil-wrapper
|
|
position: sticky
|
|
z-index: 5
|
|
background-color: var(--default-white)
|
|
padding-top: 38px
|
|
|
|
.column-wrapper
|
|
height: 60px
|
|
position: relative
|
|
background-color: var(--default-white)
|
|
|
|
.footer
|
|
border-bottom-left-radius: 4px
|
|
border-bottom-right-radius: 4px
|
|
|
|
.border-bottom
|
|
border-bottom: 4px solid var(--bg-ligth-blue-color)
|
|
|
|
.records-count
|
|
border-right: 1px solid var(--border-light-grey-color)
|
|
&:last-child
|
|
border-right: none
|
|
|
|
.border-top
|
|
border-top: 1px solid var(--border-light-grey-color)
|
|
|
|
.time-circle-indicator
|
|
background-color: var(--bg-event-red-color)
|
|
z-index: 5
|
|
|
|
.time-line-indicator
|
|
border-top: 1px solid var(--bg-event-red-color)
|
|
z-index: 4
|
|
width: calc(100% - 80px)
|
|
</style>
|