Merge branch 'UC-203' into 'master'

WIP EmployeesList подтягивается из Schedules

See merge request andrusyakka/urban-couscous!214
This commit is contained in:
Daria Golova
2022-12-22 14:36:07 +00:00
6 changed files with 220 additions and 61 deletions

View File

@@ -2,14 +2,14 @@
.calendar-container.flex
calendar-sidebar(
:url="url",
:team-data="employeesData",
:schedules-data="schedulesData",
:open-form-create="openFormCreateEvent",
:event-statuses="eventStatuses",
@width="changeWidth",
)
calendar-schedule(
:url="url",
:owners-data="employeesData",
:schedules-data="schedulesData",
:current-date="currentDate",
:time-information="timeInformation",
:events-data="eventsData",
@@ -28,10 +28,10 @@
calendar-form-add-event(
v-if="isOpenForm",
:close-form="closeFormCreateEvent",
:owners-data="employeesData",
:selected-event-data="selectedEvent",
:event-statuses="eventStatuses",
:time-information="timeInformation",
:current-date="currentDate",
@clear-selected-event-data="clearSelectedEvent",
@close-change-form="setChangeFormState"
)
@@ -76,11 +76,12 @@ export default {
showModal: false,
timeInformation: {
dayStartTime: "08:00",
dayEndTime: "20:00",
dayEndTime: "22:00",
},
eventsData: [],
employeesData: [],
schedulesData: [],
isOpenForm: false,
WORKING_STATUS: "WORKS",
changeFormWasClosed: false,
eventStatuses: [
{
@@ -141,13 +142,28 @@ export default {
saveEventsData(res) {
this.eventsData = res.results;
},
saveEmployeesData(res) {
this.employeesData = res.results;
saveSchedulesData(res) {
if (res.results.length === 0) {
this.schedulesData = [];
return;
}
let filteredEmployees = res.results.filter(
(elem) => elem.status === this.WORKING_STATUS
);
if (filteredEmployees.length === 0) {
this.schedulesData = [];
return;
}
this.schedulesData = filteredEmployees;
},
fetchEmployeesData() {
fetchSchedulesData() {
fetchWrapper
.get("general/employee/")
.then((res) => this.saveEmployeesData(res));
.get(
`accounts/schedules/?date_after=${this.currentDate.format(
"YYYY-MM-DD"
)}&date_before=${this.currentDate.format("YYYY-MM-DD")}`
)
.then((res) => this.saveSchedulesData(res));
},
fetchEventsData() {
fetchWrapper
@@ -192,9 +208,12 @@ export default {
this.clearSelectedEvent();
}
},
currentDate() {
this.fetchSchedulesData();
},
},
mounted() {
this.fetchEmployeesData();
this.fetchSchedulesData();
this.fetchEventsData();
},
};

View File

@@ -12,7 +12,8 @@
span.owner-name.font-medium.text-base.mr-6 {{ ownerName }}
img.icon-wrapper.cursor-pointer(src="@/assets/icons/lock.svg")
column-header-checkbox
.body.pl-1.h-full(@dblclick="clickOnBackground")
.body(@dblclick="clickOnBackground")
.nonworking-time(:style="nonworkingStartTime")
transition-group(name="card")
calendar-event-card(
v-for="event, index in dayEvents",
@@ -27,18 +28,23 @@
@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,
@@ -63,6 +69,51 @@ export default {
};
},
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 =
@@ -120,23 +171,41 @@ export default {
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: this.ownerData,
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}:00Z`,
end: `${this.currentDate.format("YYYY-MM-DD")}T${hours}:${minuts}:00Z`,
end: `${this.currentDate.format(
"YYYY-MM-DD"
)}T${hours}:${minuts}:00Z`,
});
},
},
@@ -157,6 +226,7 @@ export default {
.body
position: relative
z-index: 3
height: 100%
.btn
opacity: 0.5
@@ -185,4 +255,9 @@ export default {
.card-move
transition: 0.3s ease
.nonworking-time
width: 100%
background-color: var(--btn-blue-sec-color)
opacity: 0.3
</style>

View File

@@ -1,5 +1,5 @@
<template lang="pug">
.wrapper.cursor-pointer.my-1(
.wrapper.cursor-pointer.my-1.mx-1(
:style="themeColors",
:class="cardTheme",
ref="eventCard"

View File

@@ -95,12 +95,6 @@ export default {
emits: ["clear-selected-event-data", "close-change-form"],
props: {
closeForm: Function,
ownersData: {
type: Array,
default() {
return [];
},
},
selectedEventData: {
type: Object,
default() {
@@ -119,6 +113,12 @@ export default {
return {};
},
},
currentDate: {
type: Object,
default() {
return {};
},
},
},
data() {
return {
@@ -135,6 +135,8 @@ export default {
id: null,
ifClearedForm: true,
membersData: [],
ownersData: [],
WORKING_STATUS: "WORKS",
};
},
computed: {
@@ -303,10 +305,27 @@ export default {
},
checkTime() {
let counter = 0;
let foundedSchedule = {};
let foundedEmployee = this.ownersData.find(
(elem) => elem.id === this.employees.employee.id
);
if (foundedEmployee)
foundedSchedule = foundedEmployee.schedules.find(
(elem) =>
elem.date === this.eventDate && elem.status === this.WORKING_STATUS
);
if (!foundedSchedule) {
this.addErrorNotification(
"Некорректная дата события",
`В данный день ${this.employees.employee.label} не работает`
);
counter += 1;
return false;
}
if (
this.checkTimeLimits(
this.startTime,
this.timeInformation.dayStartTime,
foundedSchedule.start_time,
"start"
)
) {
@@ -316,13 +335,7 @@ export default {
);
counter += 1;
}
if (
this.checkTimeLimits(
this.endTime,
this.timeInformation.dayEndTime,
"end"
)
) {
if (this.checkTimeLimits(this.endTime, foundedSchedule.end_time, "end")) {
this.addErrorNotification(
"Некорректное время окончания события",
"Время окончания события позже окончания рабочего дня"
@@ -330,11 +343,7 @@ export default {
counter += 1;
}
if (
this.checkTimeLimits(
this.endTime,
this.timeInformation.dayStartTime,
"start"
)
this.checkTimeLimits(this.endTime, foundedSchedule.start_time, "start")
) {
this.addErrorNotification(
"Некорректное время окончания события",
@@ -343,11 +352,7 @@ export default {
counter += 1;
}
if (
this.checkTimeLimits(
this.startTime,
this.timeInformation.dayEndTime,
"end"
)
this.checkTimeLimits(this.startTime, foundedSchedule.end_time, "end")
) {
this.addErrorNotification(
"Некорректное время начала события",
@@ -488,6 +493,61 @@ export default {
.get("general/person/?limit=100")
.then((res) => this.saveMembersData(res));
},
fetchOwnersData() {
fetchWrapper
.get(
`accounts/schedules/?date_after=${this.currentDate
.clone()
.subtract(1, "month")
.format("YYYY-MM-DD")}&date_before=${this.currentDate
.clone()
.add(1, "month")
.format("YYYY-MM-DD")}`
)
.then((res) => this.saveOwnersData(res));
},
saveOwnersData(res) {
let serializedList = [];
if (res.results.length === 0) {
this.ownersData = [];
return;
}
res.results.forEach((elem) => {
let foundedElem = serializedList.find(
(item) => item.id === elem.employee.id
);
if (!foundedElem) {
serializedList.push({
id: elem.employee.id,
last_name: elem.employee.last_name,
first_name: elem.employee.first_name,
patronymic: elem.employee.patronymic,
color: elem.employee.color,
schedules: [
{
date: elem.date,
end_time: elem.end_time.slice(0, elem.end_time.length - 3),
start_time: elem.start_time.slice(
0,
elem.start_time.length - 3
),
status: elem.status,
id: elem.id,
},
],
});
} else {
foundedElem.schedules.push({
date: elem.date,
end_time: elem.end_time.slice(0, elem.end_time.length - 3),
start_time: elem.start_time.slice(0, elem.start_time.length - 3),
status: elem.status,
id: elem.id,
});
}
});
this.ownersData = serializedList;
},
saveMembersData(res) {
this.membersData = res.results;
},
@@ -523,6 +583,7 @@ export default {
},
},
mounted() {
this.fetchOwnersData();
this.fetchMembersData();
},
};

View File

@@ -94,7 +94,7 @@ export default {
},
},
sidebarWidth: String,
ownersData: {
schedulesData: {
type: Array,
default() {
return [];
@@ -168,14 +168,16 @@ export default {
},
filteredOwners() {
let filteredArray = [];
this.ownersData.forEach((elem) => {
this.schedulesData.forEach((elem) => {
filteredArray.push({
id: elem.id,
last_name: elem.last_name,
first_name: elem.first_name,
patronymic: elem.patronymic,
color: elem.color,
photo: elem.photo,
id: elem.employee.id,
last_name: elem.employee.last_name,
first_name: elem.employee.first_name,
patronymic: elem.employee.patronymic,
color: elem.employee.color,
photo: elem.employee.photo,
end_time: elem.end_time.slice(0, elem.end_time.length - 3),
start_time: elem.start_time.slice(0, elem.start_time.length - 3),
});
});
return filteredArray;
@@ -301,9 +303,7 @@ export default {
let filteredArray = [];
this.filteredEventsByDate.forEach((item) => {
let foundEvent = item.employees.find(
(elem) =>
JSON.stringify(elem.employee) === JSON.stringify(owner) &&
elem.role === "owner"
(elem) => elem.employee.id === owner.id && elem.role === "owner"
);
if (foundEvent) filteredArray.push(item);
});

View File

@@ -45,7 +45,7 @@ export default {
CalendarSidebarTeammate,
},
props: {
teamData: Array,
schedulesData: Array,
openFormCreate: Function,
eventStatuses: Array,
url: String,
@@ -74,6 +74,10 @@ export default {
width: this.widthSidebarClose,
};
},
teamData() {
if (this.schedulesData.length === 0) return [];
return this.schedulesData.map((elem) => elem.employee);
},
},
methods: {
changeSize() {