Files
astra-frontend/src/pages/schedule/components/ScheduleBody.vue
2022-12-28 19:03:55 +03:00

370 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template lang="pug">
.schedule.flex-col(:style="themeCell")
.table-header.flex.w-full.pr-2
.flex.items-center.justify-center.pl-11(
:style="{width: 'calc(25% + 40px)'}"
)
.text.font-bold Сотрудник
.column-wrapper.flex
.schedule-column.flex.flex-col.items-center.justify-center.w-11(
v-for="day in result",
:class="{'column-color': changelColumnColor(day)}",
)
.text.flex.font-bold(
:style="{opacity: changeOpacity(day)}"
) {{day.format("D")}}
.text.flex.font-bold(
:style="{opacity: changeOpacity(day)}"
) {{day.format("ddd")}}
.schedule-wrapper.flex.w-full.flex-col
.schedule-body.flex.w-full(v-for="schedule in serialized", :key="schedule.id")
.edit.flex.items-center.justify-center.h-11.w-11
.flex.icon-edit
.name-employee.flex.justify-center.items-center.cursor-pointer
span {{trimOwnerName(schedule.last_name, schedule.first_name, schedule.patronymic)}}
.cell.flex.flex-col.items-center.justify-center.w-11.h-11.cursor-pointer(
v-for="day in result",
:key="day",
:id="schedule.id + day",
@click="choiceCell(day, schedule.id, schedule)",
:class="choiceState(day, schedule.id)",
:style="{backgroundColor: choiceDay(day, schedule.id) ? choiceColor(day, schedule) : ''}"
)
.flex(
:class="{'cell-work': choiceState(day, schedule.id).status}"
) {{choiceDay(day, schedule.id) ? choiceWorks(day, schedule) : ''}}
.schedule-select.flex.w-full.pr-2(v-if="clearEmployee")
.edit.flex.items-center.justify-center.h-11.w-11(v-if="currentEmployee.label")
.flex.icon-edit(v-if="currentEmployee.label")
//- base-button(
//- confirm,
//- rounded,
//- outlined,
//- :size="20",
//- @click="saveEmployee",
//- v-if="currentEmployee.label"
//- )
//- .icon-ok.text-xsm(class="pt-[3px]")
.name.flex.justify-center.items-center.cursor-pointer(:class="{'select-name': currentEmployee.label}")
base-custom-select(
v-if="!currentEmployee.label",
:items="ownersList",
v-model="currentEmployee",
placeholder="Добавить сотрудника",
:style="{border: 'none', justifyContent: 'center'}"
)
.flex.justify-center(v-else) {{currentEmployee.label}}
.cell.flex.flex-col.items-center.justify-center.w-11.h-11.cursor-pointer(
v-if="currentEmployee.label",
v-for="day in result",
:key="day",
:id="currentEmployee.id + day",
@click="choiceCell(day, currentEmployee.id)",
:class="choiceState(day, currentEmployee.id)"
)
</template>
<script>
import * as moment from "moment";
import BaseModal from "@/components/base/BaseModal.vue";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseCustomSelect from "@/components/base/BaseCustomSelect.vue";
export default {
name: "ScheduleBody",
components: { BaseModal, BaseButton, BaseCustomSelect },
props: {
employeeList: {
type: Array,
default() {
return [];
},
},
scheduleList: Array,
serialized: Array,
dataSchedule: Object,
buttons: Array,
startMonth: Object,
clearEmployee: Array,
},
data() {
return {
days: "",
result: [],
showSelect: false,
employee: [],
currentEmployee: {
label: "",
id: null,
},
curWork: "",
dateInterval: {
id: "",
start: "",
end: "",
text: "",
},
activeButton: null,
};
},
computed: {
ownersList() {
if (this.clearEmployee) {
let filteredArray = [];
this.clearEmployee.forEach((elem) => {
filteredArray.push({
id: elem.id,
label: this.trimOwnerName(
elem.last_name,
elem.first_name,
elem.patronymic
),
});
});
return filteredArray;
}
return [];
},
themeCell() {
this.setActiveButton();
return {
"--bg-color-status": this.activeButton?.color,
"--text-status": this.activeButton?.text,
};
},
},
methods: {
changelColumnColor(day) {
return day.format("ddd") === "сб" || day.format("ddd") === "вс"
? true
: false;
},
setActiveButton() {
this.activeButton = this.buttons.find((e) => e.active);
},
choiceCell(time, id, schedule) {
let formatTime = time.format("YYYY-MM-DD");
let insideSchedules = schedule?.schedules.filter(
(el) =>
(el.date > this.dateInterval.start &&
el.date < this.dateInterval.end) ||
el.date === this.dateInterval.start ||
el.date === this.dateInterval.end
);
if (
this.dateInterval.start &&
this.dateInterval.end &&
this.dateInterval.id !== id
) {
this.dateInterval.start = "";
this.dateInterval.end = "";
this.dateInterval.id = "";
}
if (!this.dateInterval.start) {
this.dateInterval.start = formatTime;
this.dateInterval.id = id;
} else if (time.isAfter(this.dateInterval.start)) {
this.dateInterval.end = formatTime;
if (this.currentEmployee.label) {
this.$emit("new-schedule-employee", this.dateInterval);
} else this.$emit("schedule-employee", this.dateInterval);
} else this.dateInterval.start = formatTime;
if (
!this.currentEmployee.label &&
this.dateInterval.start &&
this.dateInterval.end &&
insideSchedules
)
this.rangeSchdedules(schedule, insideSchedules, id);
},
rangeSchdedules(schedule, insideSchedules, id) {
insideSchedules = schedule.schedules.filter(
(el) =>
(el.date > this.dateInterval.start &&
el.date < this.dateInterval.end) ||
el.date === this.dateInterval.start ||
el.date === this.dateInterval.end
);
if (insideSchedules.length > 0) insideSchedules[0].employeeId = id;
let keys = Object.keys(insideSchedules);
let outsideSchedules = [];
let firstDate = insideSchedules[keys[0]]?.date;
let lastDate = insideSchedules[keys.length - 1]?.date;
if (this.dateInterval.start < firstDate) {
outsideSchedules.push({
start_date: this.dateInterval.start,
end_date: moment(firstDate).subtract(1, "d").format("YYYY-MM-DD"),
});
}
if (this.dateInterval.end > lastDate)
outsideSchedules.push({
start_date: moment(lastDate).add(1, "d").format("YYYY-MM-DD"),
end_date: this.dateInterval.end,
});
this.$emit("schedules", insideSchedules, outsideSchedules);
},
choiceState(day, id) {
let formatDay = day.format("YYYY-MM-DD");
let resStart =
this.dateInterval.start &&
formatDay === this.dateInterval.start &&
this.dateInterval.id === id;
let resEnd =
this.dateInterval.end &&
formatDay === this.dateInterval.end &&
this.dateInterval.id === id;
let resMiddle =
day.isBefore(this.dateInterval.end) &&
this.dateInterval.id === id &&
day.isAfter(this.dateInterval.start);
return {
status: (resStart || resMiddle || resEnd) && !!this.activeButton,
"from-date": !!resStart && !this.activeButton,
"to-date": !!resEnd && !this.activeButton,
"middle-dates": !!resMiddle && !this.activeButton,
};
},
saveEmployee() {
this.currentEmployee.label = "";
this.currentEmployee.id = null;
},
choiceWorks(day, employee) {
let currentDay = day.format("YYYY-MM-DD");
let res = employee.schedules.find((e) => e.date === currentDay)?.status;
return this.buttons.find((e) => e.work === res)?.text[1];
},
choiceColor(day, employee) {
let currentDay = day.format("YYYY-MM-DD");
let res = employee.schedules.find((e) => e.date === currentDay)?.status;
return this.buttons.find((e) => e.work === res)?.color;
},
changeDays() {
this.days = moment().daysInMonth();
},
pushMonth() {
this.result.push(this.startMonth);
for (let i = 2; i <= this.days; i++) {
this.result.push(this.startMonth.clone().add(i - 1, "d"));
}
},
trimOwnerName(lastName, firstName, patronymic) {
let checkedFirstName = firstName !== null ? firstName[0] + "." : "";
let checkedPatronymic = patronymic !== null ? patronymic[0] + "." : "";
return `${lastName} ${checkedFirstName}${checkedPatronymic}`;
},
choiceDay(day, employee) {
let current = day.format("YYYY-MM-DD");
return this.scheduleList.find(
(e) => current === e.date && e.employee.id === employee
)?.date;
},
changeOpacity(day) {
return day.format("ddd") === "сб" || day.format("ddd") === "вс"
? "0.6"
: "1";
},
},
mounted() {
this.changeDays();
this.pushMonth();
},
};
</script>
<style lang="sass" scoped>
.schedule
border: 1.5px solid var(--border-light-grey-color-1)
border-radius: 4px
border-right: none
border-bottom: none
min-height: 87px
width: calc(100vw - 136px)
.schedule-wrapper
overflow-y: scroll
max-height: 351px
.schedule-body
&:hover
background-color: var(--border-light-grey-color-1)
.table-header
height: 50px
background-color: #D7D9FF
border-bottom: 1.5px solid var(--border-light-grey-color-1)
border-top-left-radius: 2px
border-top-right-radius: 2px
.schedule-select
border-top: 1.5px solid var(--border-light-grey-color-1)
&:hover
background-color: var(--border-light-grey-color-1)
.column-wrapper
overflow: auto
overflow-x: hidden
.column-color
background-color: var(--bg-white-color-1)
.text
color: var(--btn-blue-color)
.edit
border-right: 1.5px solid var(--border-light-grey-color-1)
border-bottom: 1.5px solid var(--border-light-grey-color-1)
.name
color: var(--btn-blue-color)
border-bottom: 1.5px solid var(--border-light-grey-color-1)
border-right: 1.5px solid var(--border-light-grey-color-1)
.select-name
width: 25%
border-right: 1.5px solid var(--border-light-grey-color-1)
.name-employee
width: 25%
border-right: 1.5px solid var(--border-light-grey-color-1)
border-bottom: 1.5px solid var(--border-light-grey-color-1)
color: var(--btn-blue-color)
.cell
border-right: 1.5px solid var(--border-light-grey-color-1)
border-bottom: 1.5px solid var(--border-light-grey-color-1)
.modal-wrapper
border: 1.5px solid var(--border-light-grey-color-1)
border-radius: 4px
width: 400px
height: 500px
.status
background-color: var(--bg-color-status) !important
.cell-work
display: none
.status::after
content: var(--text-status)
.from-date
background-color: limegreen !important
.to-date
background-color: red !important
.middle-dates
background-color: yellow !important
</style>