260 lines
7.2 KiB
Vue
260 lines
7.2 KiB
Vue
<template lang="pug">
|
|
.calendar-column-wrapper.flex.flex-col
|
|
.header.flex.items-center.justify-between.py-2.px-6.top-0
|
|
.flex.items-center
|
|
base-avatar.mr-2(:size="32", :color="ownerData.color")
|
|
img.h-full.object-cover(
|
|
:src="url + ownerData.photo",
|
|
alt="Team member",
|
|
v-if="ownerData.photo"
|
|
)
|
|
span(v-if="!ownerData.photo") {{ defaultAvatar }}
|
|
span.owner-name.font-medium.text-base.mr-6 {{ ownerName }}
|
|
img.icon-wrapper.cursor-pointer(src="@/assets/icons/lock.svg")
|
|
column-header-checkbox
|
|
.body(@dblclick="clickOnBackground")
|
|
//.nonworking-time(:style="nonworkingStartTime")
|
|
transition-group(name="card")
|
|
calendar-event-card(
|
|
v-for="event, index in dayEvents",
|
|
:key="event.id + index",
|
|
:id="event.id",
|
|
:ownerEvent="event",
|
|
:event-statuses="eventStatuses",
|
|
:style="eventCardPosition(event.start, event.end)",
|
|
@selected-event="transmitEventData",
|
|
@delete-event="transmitDeleteEvent",
|
|
:schedule-body-ref="scheduleBodyRef",
|
|
)
|
|
//.nonworking-time.absolute(:style="nonworkingEndTime")
|
|
</template>
|
|
|
|
<script>
|
|
import ColumnHeaderCheckbox from "./CalendarColumnHeaderCheckbox.vue";
|
|
import BaseAvatar from "@/components/base/BaseAvatar";
|
|
import CalendarEventCard from "./CalendarEventCard.vue";
|
|
//import * as moment from "moment/moment";
|
|
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
|
|
import { addNotification } from "@/components/Notifications/notificationContext";
|
|
export default {
|
|
name: "CalendarColumn",
|
|
components: {
|
|
CalendarEventCard,
|
|
BaseAvatar,
|
|
ColumnHeaderCheckbox,
|
|
TheNotificationProvider,
|
|
},
|
|
props: {
|
|
ownerData: Object,
|
|
dayEvents: Array,
|
|
dayEndTime: Number,
|
|
dayStartTime: Number,
|
|
eventStatuses: Array,
|
|
//changeFormWasClosed: Boolean,
|
|
scheduleBodyRef: Node,
|
|
url: String,
|
|
openFormCreateEvent: Function,
|
|
currentDate: {
|
|
type: Object,
|
|
default() {
|
|
return {};
|
|
},
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
pixelsPerHour: 62,
|
|
};
|
|
},
|
|
computed: {
|
|
/*workingShift() {
|
|
if (!this.ownerData.id) return null;
|
|
let start = this.ownerData.start_time;
|
|
let end = this.ownerData.end_time;
|
|
return {
|
|
start: start?.split(":"),
|
|
end: end?.split(":"),
|
|
fulltime: `${start} - ${end}`,
|
|
};
|
|
},
|
|
nonworkingStartTime() {
|
|
if (!this.ownerData.id || !this.workingShift) return {};
|
|
let height =
|
|
(this.workingShift.start[0] - this.dayStartTime) * this.pixelsPerHour +
|
|
this.workingShift.start[1] * this.pixelsPerMinute;
|
|
if (height <= 0)
|
|
return {
|
|
height: 0,
|
|
display: "none",
|
|
};
|
|
return {
|
|
height: `${height}px`,
|
|
};
|
|
},
|
|
nonworkingEndTime() {
|
|
if (!this.ownerData.id || !this.workingShift) return {};
|
|
let time = moment()
|
|
.hour(this.dayEndTime)
|
|
.minute(0)
|
|
.subtract(parseInt(this.workingShift.end[0]), "hours")
|
|
.subtract(parseInt(this.workingShift.end[1]), "minutes")
|
|
.format("HH:mm")
|
|
.split(":");
|
|
let position =
|
|
time[0] * this.pixelsPerHour + time[1] * this.pixelsPerMinute;
|
|
if (position <= 0)
|
|
return {
|
|
bottom: 0,
|
|
display: "none",
|
|
};
|
|
return {
|
|
bottom: 0,
|
|
height: `${position}px`,
|
|
};
|
|
},*/
|
|
ownerName() {
|
|
if (this.ownerData.id) {
|
|
let checkedFirstName =
|
|
this.ownerData.first_name !== null
|
|
? this.ownerData.first_name[0] + "."
|
|
: "";
|
|
let checkedPatronymic =
|
|
this.ownerData.patronymic !== null
|
|
? this.ownerData.patronymic[0] + "."
|
|
: "";
|
|
return `${this.ownerData.last_name} ${checkedFirstName}${checkedPatronymic}`;
|
|
}
|
|
return null;
|
|
},
|
|
defaultAvatar() {
|
|
let checkedFirstName =
|
|
this.ownerData.first_name !== null
|
|
? this.ownerData.first_name[0]
|
|
: this.ownerData.last_name[1];
|
|
return `${this.ownerData.last_name[0]}${checkedFirstName}`;
|
|
},
|
|
pixelsPerMinute() {
|
|
return this.pixelsPerHour / 60;
|
|
},
|
|
},
|
|
methods: {
|
|
eventCardPosition(startTime, endTime) {
|
|
let start = startTime
|
|
.slice(11, -4)
|
|
.split(":")
|
|
.map((elem) => parseInt(elem, 10));
|
|
let end = endTime.slice(11, -6);
|
|
let position =
|
|
(start[0] - this.dayStartTime) * this.pixelsPerHour +
|
|
start[1] * this.pixelsPerMinute;
|
|
if (
|
|
parseInt(start[0], 10) < this.dayStartTime ||
|
|
parseInt(end, 10) > this.dayEndTime
|
|
) {
|
|
return {
|
|
top: "0px",
|
|
visibility: "hidden",
|
|
};
|
|
}
|
|
return {
|
|
top: `${position}px`,
|
|
};
|
|
},
|
|
transmitEventData(eventData) {
|
|
this.$emit("selected-event", eventData);
|
|
},
|
|
/*transmitResetChangeForm() {
|
|
this.$emit("reset-change-form");
|
|
},*/
|
|
transmitDeleteEvent(eventData) {
|
|
this.$emit("delete-event", eventData);
|
|
},
|
|
addErrorNotification(title, message) {
|
|
addNotification(title, title, message, "error", 5000);
|
|
},
|
|
/*clickOnBackground(e) {
|
|
let res = String((e.offsetY / this.pixelsPerHour).toFixed(2)).split(".");
|
|
let hours = parseInt(res[0]) + this.dayStartTime;
|
|
let minuts = Math.round(res[1] * 0.6);
|
|
if (minuts < 10) minuts = "0" + minuts;
|
|
if (hours < 10) hours = "0" + hours;
|
|
if (e.target.className !== "body")
|
|
this.addErrorNotification(
|
|
`Для сотрудника ${this.ownerName} рабочие часы: ${this.workingShift.fulltime}`,
|
|
"Вы пытаетесь добавить запись вне рабочего времени"
|
|
);
|
|
else
|
|
this.$emit("selected-event", {
|
|
employees: [
|
|
{
|
|
employee: {
|
|
id: this.ownerData.id,
|
|
last_name: this.ownerData.last_name,
|
|
first_name: this.ownerData.first_name,
|
|
patronymic: this.ownerData.patronymic,
|
|
color: this.ownerData.color,
|
|
photo: this.ownerData.photo,
|
|
},
|
|
role: "owner",
|
|
},
|
|
],
|
|
start: `${this.currentDate.format(
|
|
"YYYY-MM-DD"
|
|
)}T${hours}:${minuts}:00`,
|
|
end: `${this.currentDate.format("YYYY-MM-DD")}T${hours}:${minuts}:00`,
|
|
});
|
|
},*/
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="sass" scoped>
|
|
.calendar-column-wrapper
|
|
border-right: 1px solid var(--border-light-grey-color)
|
|
&:last-child
|
|
border-right: none
|
|
|
|
.header
|
|
position: sticky
|
|
z-index: 5
|
|
background-color: var(--default-white)
|
|
|
|
.body
|
|
position: relative
|
|
z-index: 3
|
|
height: 100%
|
|
|
|
.btn
|
|
opacity: 0.5
|
|
padding: 7px 13px !important
|
|
|
|
.icon-wrapper
|
|
width: 24px
|
|
height: 24px
|
|
|
|
.owner-name
|
|
color: var(--font-dark-blue-color)
|
|
|
|
.card-enter-from
|
|
opacity: 0
|
|
pointer-events: none
|
|
|
|
.card-enter-active
|
|
transition: 0.3s ease
|
|
|
|
.card-leave-to
|
|
opacity: 0
|
|
pointer-events: none
|
|
|
|
.card-leave-active
|
|
transition: 0.3s ease
|
|
|
|
.card-move
|
|
transition: 0.3s ease
|
|
|
|
.nonworking-time
|
|
width: 100%
|
|
background-color: var(--btn-blue-sec-color)
|
|
opacity: 0.3
|
|
</style>
|