Merge branch 'UC-201' into 'master'
Resolve UC-201 See merge request andrusyakka/urban-couscous!215
This commit is contained in:
@@ -21,14 +21,14 @@
|
|||||||
) Создать событие
|
) Создать событие
|
||||||
calendar-sidebar-event(:is-open="isOpen", :event-statuses="eventStatuses")
|
calendar-sidebar-event(:is-open="isOpen", :event-statuses="eventStatuses")
|
||||||
calendar-sidebar-teammate(:team-data="teamData", :is-open="isOpen", :url="url")
|
calendar-sidebar-teammate(:team-data="teamData", :is-open="isOpen", :url="url")
|
||||||
.button-wrapper.flex.justify-center.mb-23px
|
//- .button-wrapper.flex.justify-center.mb-23px
|
||||||
base-button(
|
//- base-button(
|
||||||
left-icon="icon-long-arrow",
|
//- left-icon="icon-long-arrow",
|
||||||
rounded, :size="40",
|
//- rounded, :size="40",
|
||||||
:icon-left-size="18",
|
//- :icon-left-size="18",
|
||||||
secondary,
|
//- secondary,
|
||||||
:style="{ transform: `rotate(${turnButton})`}",
|
//- :style="{ transform: `rotate(${turnButton})`}",
|
||||||
@click="changeSize"
|
//- @click="changeSize"
|
||||||
)
|
)
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { fetchWrapper } from "@/shared/fetchWrapper";
|
||||||
import BaseInput from "@/components/base/BaseInput";
|
import BaseInput from "@/components/base/BaseInput";
|
||||||
import BaseButton from "@/components/base/BaseButton";
|
import BaseButton from "@/components/base/BaseButton";
|
||||||
import viewPasswordIcon from "@/assets/icons/eye.svg";
|
import viewPasswordIcon from "@/assets/icons/eye.svg";
|
||||||
@@ -84,46 +85,28 @@ export default {
|
|||||||
localStorage.username = this.user.username;
|
localStorage.username = this.user.username;
|
||||||
localStorage.password = this.user.password;
|
localStorage.password = this.user.password;
|
||||||
},
|
},
|
||||||
async auth(token) {
|
async auth() {
|
||||||
let res = await fetch("https://astra-dev.dopcore.com/auth/users/me/", {
|
let res = await fetchWrapper.get("auth/users/me/");
|
||||||
headers: {
|
res = await res;
|
||||||
Authorization: `Bearer ${token}`,
|
let data = await fetchWrapper.get(`accounts/users/${res.id}/detail`);
|
||||||
},
|
data = await data;
|
||||||
});
|
|
||||||
res = await res.json();
|
|
||||||
let data = await fetch(
|
|
||||||
`https://astra-dev.dopcore.com/accounts/users/${res.id}/detail`,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
data = await data.json();
|
|
||||||
this.userData = data;
|
this.userData = data;
|
||||||
localStorage.setItem("userData", JSON.stringify(this.userData));
|
localStorage.setItem("userData", JSON.stringify(this.userData));
|
||||||
},
|
},
|
||||||
login() {
|
login() {
|
||||||
const requestOptions = {
|
fetchWrapper
|
||||||
method: "POST",
|
.post("auth/jwt/create/", {
|
||||||
headers: { "Content-Type": "application/json" },
|
username: this.user.username,
|
||||||
body: JSON.stringify(this.user),
|
password: this.user.password,
|
||||||
};
|
})
|
||||||
fetch("https://astra-dev.dopcore.com/auth/jwt/create/", requestOptions)
|
.then((token) => {
|
||||||
.then((result) => {
|
if (token.access) {
|
||||||
if (result.status === 200) {
|
localStorage.setItem("tokenAccess", token.access);
|
||||||
return result.json();
|
this.auth().then(() => this.$router.push("/"));
|
||||||
} else {
|
} else {
|
||||||
this.authorized = false;
|
this.authorized = false;
|
||||||
this.user.username = "";
|
this.user.username = "";
|
||||||
this.user.password = "";
|
this.user.password = "";
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((token) => {
|
|
||||||
if (token) {
|
|
||||||
localStorage.setItem("tokenAccess", token.access);
|
|
||||||
this.auth(token.access).then(() => this.$router.push("/"));
|
|
||||||
} else {
|
|
||||||
this.$router.push("/login");
|
this.$router.push("/login");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
schedule-body(
|
schedule-body(
|
||||||
:employee-list="employeeList",
|
:employee-list="employeeList",
|
||||||
:schedules-employee="fetchSchedulesEmployee",
|
:schedules-employee="fetchSchedulesEmployee",
|
||||||
:schedule-list="scheduleList"
|
:schedule-list="scheduleList",
|
||||||
|
:serialized="serialized"
|
||||||
)
|
)
|
||||||
schedule-bar
|
schedule-bar
|
||||||
</template>
|
</template>
|
||||||
@@ -22,20 +23,63 @@ export default {
|
|||||||
return {
|
return {
|
||||||
employeeList: [],
|
employeeList: [],
|
||||||
scheduleList: [],
|
scheduleList: [],
|
||||||
|
serialized: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchSchedules() {
|
fetchSchedules() {
|
||||||
fetchWrapper
|
fetchWrapper
|
||||||
.get("general/employee/")
|
.get("general/employee/")
|
||||||
.then((res) => (this.employeeList = res.results));
|
.then((res) => {
|
||||||
|
this.employeeList = res.results;
|
||||||
|
})
|
||||||
|
.then(() => this.fetchSchedulesEmployee());
|
||||||
},
|
},
|
||||||
fetchSchedulesEmployee(id) {
|
fetchSchedulesEmployee() {
|
||||||
fetchWrapper
|
this.employeeList.forEach((e) => {
|
||||||
.get(`accounts/schedules/?employee=${id}`, "api")
|
fetchWrapper
|
||||||
.then((data) => {
|
.get(`accounts/schedules/?employee=${e.id}`)
|
||||||
this.scheduleList = data.results;
|
.then((data) => {
|
||||||
});
|
this.scheduleList.push(...data.results);
|
||||||
|
})
|
||||||
|
.then(() => this.filterScheduleEmployee());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
filterScheduleEmployee() {
|
||||||
|
let serialized = [];
|
||||||
|
this.scheduleList.forEach((e) => {
|
||||||
|
let foundedElem = serialized.find((elem) => elem.id === e.employee.id);
|
||||||
|
if (!foundedElem) {
|
||||||
|
serialized.push({
|
||||||
|
first_name: e.employee.first_name,
|
||||||
|
id: e.employee.id,
|
||||||
|
last_name: e.employee.last_name,
|
||||||
|
patronymic: e.employee.patronymic,
|
||||||
|
schedules: [
|
||||||
|
{
|
||||||
|
date: e.date,
|
||||||
|
end_time: e.end_time,
|
||||||
|
start_time: e.start_time,
|
||||||
|
status: e.status,
|
||||||
|
id: e.id,
|
||||||
|
title: e.title,
|
||||||
|
name: e.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
foundedElem.schedules.push({
|
||||||
|
date: e.date,
|
||||||
|
end_time: e.end_time,
|
||||||
|
start_time: e.start_time,
|
||||||
|
status: e.status,
|
||||||
|
id: e.id,
|
||||||
|
title: e.title,
|
||||||
|
name: e.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.serialized = serialized;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -2,25 +2,22 @@
|
|||||||
.wrapper-bar.flex.flex-col.gap-y-4
|
.wrapper-bar.flex.flex-col.gap-y-4
|
||||||
.flex.px-5.py-5.w-full.justify-around
|
.flex.px-5.py-5.w-full.justify-around
|
||||||
.time-wrapper.flex.justify-between
|
.time-wrapper.flex.justify-between
|
||||||
.flex.flex-col.py-14px.px-4.gap-y-14px
|
.flex.flex-col.items-center.py-14px.px-4.gap-y-14px
|
||||||
.text.text-smm Начало рабочего дня
|
.text.text-smm Начало
|
||||||
base-input-time.item-input.text-base.select(:width-input="40")
|
base-input-date.select(v-model:value="dataSchedule.endTime")
|
||||||
.flex.flex-col.py-14px.px-4.gap-y-14px
|
.flex.flex-col.items-center.py-14px.px-4.gap-y-14px
|
||||||
.text.span.text-smm Конец рабочего дня
|
.text.span.text-smm Конец
|
||||||
base-input-time.item-input.text-base.select(:width-input="40")
|
base-input-date.select(v-model:value="dataSchedule.startTime")
|
||||||
.status-wrapper.flex.flex-col
|
.status-wrapper.flex.flex-col
|
||||||
.flex.justify-center.items-center.h-10
|
.flex.justify-center.items-center.h-10
|
||||||
span.font-semibold Статусы
|
span.font-semibold Статусы
|
||||||
.flex.justify-around(class="py-2.5")
|
.flex.justify-around(class="py-2.5")
|
||||||
base-button.button-work.font-semibold(
|
base-button.font-semibold(
|
||||||
:style="{minWidth: '190px', minHeight: '43px'}"
|
v-for="item in buttons",
|
||||||
) Работает
|
:class="item.work" ,
|
||||||
base-button.button-status.font-semibold(
|
:style="{minWidth: '190px', minHeight: '43px', border: item.active ? '1.5px solid #5E5E5E' : 'none'}",
|
||||||
:style="{minWidth: '190px', minHeight: '43px'}"
|
@click="choiceSchedule(item.work)"
|
||||||
) Отпуск/больничный
|
) {{item.name}}
|
||||||
base-button.button-free.font-semibold(
|
|
||||||
:style="{minWidth: '190px', minHeight: '43px'}"
|
|
||||||
) Выходной
|
|
||||||
.graph-template.flex
|
.graph-template.flex
|
||||||
base-custom-select(
|
base-custom-select(
|
||||||
:items="scheduleList",
|
:items="scheduleList",
|
||||||
@@ -36,9 +33,10 @@
|
|||||||
import BaseButton from "@/components/base/BaseButton.vue";
|
import BaseButton from "@/components/base/BaseButton.vue";
|
||||||
import BaseCustomSelect from "@/components/base/BaseCustomSelect.vue";
|
import BaseCustomSelect from "@/components/base/BaseCustomSelect.vue";
|
||||||
import BaseInputTime from "@/components/base/BaseInputTime.vue";
|
import BaseInputTime from "@/components/base/BaseInputTime.vue";
|
||||||
|
import BaseInputDate from "@/components/base/BaseInputDate.vue";
|
||||||
export default {
|
export default {
|
||||||
name: "ScheduleBar",
|
name: "ScheduleBar",
|
||||||
components: { BaseButton, BaseCustomSelect, BaseInputTime },
|
components: { BaseButton, BaseCustomSelect, BaseInputTime, BaseInputDate },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
scheduleList: [
|
scheduleList: [
|
||||||
@@ -48,8 +46,24 @@ export default {
|
|||||||
{ label: "5/2", id: 4 },
|
{ label: "5/2", id: 4 },
|
||||||
],
|
],
|
||||||
schedule: {},
|
schedule: {},
|
||||||
|
dataSchedule: {
|
||||||
|
startDate: null,
|
||||||
|
endDate: null,
|
||||||
|
status: "",
|
||||||
|
},
|
||||||
|
buttons: [
|
||||||
|
{ work: "button-work", name: "Работает", active: false },
|
||||||
|
{ work: "button-status", name: "Отпуск/больничный", active: false },
|
||||||
|
{ work: "button-free", name: "Статусы", active: false },
|
||||||
|
],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
choiceSchedule(item) {
|
||||||
|
this.buttons.forEach((e) => (e.active = false));
|
||||||
|
this.buttons.find((e) => e.work === item).active = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -60,7 +74,7 @@ export default {
|
|||||||
border-radius: 4px
|
border-radius: 4px
|
||||||
|
|
||||||
.time-wrapper
|
.time-wrapper
|
||||||
width: 350px
|
width: 420px
|
||||||
height: 102px
|
height: 102px
|
||||||
border: 1.5px solid var(--border-light-grey-color-1)
|
border: 1.5px solid var(--border-light-grey-color-1)
|
||||||
border-radius: 4px
|
border-radius: 4px
|
||||||
@@ -128,4 +142,9 @@ export default {
|
|||||||
.graph-template
|
.graph-template
|
||||||
width: 218px
|
width: 218px
|
||||||
height: 40px
|
height: 40px
|
||||||
|
|
||||||
|
.select
|
||||||
|
height: 40px
|
||||||
|
border: 1.5px solid var(--border-light-grey-color)
|
||||||
|
border-radius: 4px
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -14,40 +14,40 @@
|
|||||||
.text.flex.font-bold(
|
.text.flex.font-bold(
|
||||||
:style="{opacity: day.format('ddd') === 'сб' || day.format('ddd') === 'вс' ? '0.6' : '1'}"
|
:style="{opacity: day.format('ddd') === 'сб' || day.format('ddd') === 'вс' ? '0.6' : '1'}"
|
||||||
) {{day.format("ddd")}}
|
) {{day.format("ddd")}}
|
||||||
.schedule-body.flex.w-full(v-if="this.scheduleList[0]?.id")
|
.schedule-body.flex.w-full(v-for="schedule in serialized")
|
||||||
.edit.flex.items-center.justify-center.h-9.w-9
|
.edit.flex.items-center.justify-center.h-9.w-9
|
||||||
.flex.icon-edit
|
.flex.icon-edit
|
||||||
.name-employee.flex.justify-center.items-center.cursor-pointer(@click="openSelect")
|
.name-employee.flex.justify-center.items-center.cursor-pointer(@click="openSelect")
|
||||||
span {{trimOwnerName(this.scheduleList[0]?.employee.last_name, this.scheduleList[0]?.employee.first_name, this.scheduleList[0]?.employee.patronymic)}}
|
span {{trimOwnerName(schedule.last_name, schedule.first_name, schedule.patronymic)}}
|
||||||
.flex(v-for="day in result")
|
.flex
|
||||||
.cell.flex.flex-col.items-center.justify-center.w-11(
|
.cell.flex.flex-col.items-center.justify-center.w-11(
|
||||||
v-for="item in scheduleList",
|
v-for="day in result",
|
||||||
:style="{backgroundColor: day.format('YYYY-MM-DD') === item.date ? choiceColor(item.status) : ''}"
|
:style="{backgroundColor: day.format('YYYY-MM-DD') === choiceDay(day.format('YYYY-MM-DD'), schedule.id) ? choiceColor(day.format('YYYY-MM-DD')) : ''}"
|
||||||
)
|
)
|
||||||
.flex {{day.format("YYYY-MM-DD") === item.date ? choiceWorks(item.status) : ''}}
|
.flex {{day.format("YYYY-MM-DD") === choiceDay(day.format("YYYY-MM-DD"), schedule.id) ? choiceWorks(day.format('YYYY-MM-DD')) : ''}}
|
||||||
.schedule-body.flex.w-full
|
//- .schedule-body.flex.w-full
|
||||||
.edit.flex.items-center.justify-center.h-9.w-9
|
//- .edit.flex.items-center.justify-center.h-9.w-9
|
||||||
.flex.items-center.gap-x-8
|
//- .flex.items-center.gap-x-8
|
||||||
base-button(
|
//- base-button(
|
||||||
confirm,
|
//- confirm,
|
||||||
rounded,
|
//- rounded,
|
||||||
outlined,
|
//- outlined,
|
||||||
:size="20",
|
//- :size="20",
|
||||||
@click="saveEmployee",
|
//- @click="saveEmployee",
|
||||||
v-if="currentEmployee.label"
|
//- v-if="currentEmployee.label"
|
||||||
)
|
//- )
|
||||||
.icon-ok.text-xsm(class="pt-[3px]")
|
//- .icon-ok.text-xsm(class="pt-[3px]")
|
||||||
.name.flex.justify-center.items-center.cursor-pointer(
|
//- .name.flex.justify-center.items-center.cursor-pointer(
|
||||||
v-if="currentEmployee.label",
|
//- v-if="currentEmployee.label",
|
||||||
@click="openSelect"
|
//- @click="openSelect"
|
||||||
)
|
//- )
|
||||||
span {{currentEmployee.label}}
|
//- span {{currentEmployee.label}}
|
||||||
.name.flex(v-if="!currentEmployee.label")
|
//- .name.flex(v-if="!currentEmployee.label")
|
||||||
base-custom-select(
|
//- base-custom-select(
|
||||||
:items="ownersList",
|
//- :items="ownersList",
|
||||||
v-model="currentEmployee",
|
//- v-model="currentEmployee",
|
||||||
placeholder="Добавить сотрудника",
|
//- placeholder="Добавить сотрудника",
|
||||||
:style="{border: 'none'}"
|
//- :style="{border: 'none'}"
|
||||||
)
|
)
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ export default {
|
|||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
schedulesEmployee: Function,
|
|
||||||
scheduleList: Array,
|
scheduleList: Array,
|
||||||
|
serialized: Array,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -85,6 +85,7 @@ export default {
|
|||||||
{ work: "VACATION", color: "#D7D9FF", text: "О" },
|
{ work: "VACATION", color: "#D7D9FF", text: "О" },
|
||||||
{ work: "DAY_OFF", color: "#9294A7", text: "В" },
|
{ work: "DAY_OFF", color: "#9294A7", text: "В" },
|
||||||
],
|
],
|
||||||
|
curWork: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -108,15 +109,16 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveEmployee() {
|
saveEmployee() {
|
||||||
this.schedulesEmployee(this.currentEmployee.id);
|
|
||||||
this.currentEmployee.label = "";
|
this.currentEmployee.label = "";
|
||||||
this.currentEmployee.id = null;
|
this.currentEmployee.id = null;
|
||||||
},
|
},
|
||||||
choiceWorks(work) {
|
choiceWorks(day) {
|
||||||
return this.works.find((e) => e.work === work).text;
|
let a = this.scheduleList.find((e) => e.date === day).status;
|
||||||
|
return this.works.find((e) => e.work === a).text;
|
||||||
},
|
},
|
||||||
choiceColor(work) {
|
choiceColor(day) {
|
||||||
return this.works.find((e) => e.work === work).color;
|
let a = this.scheduleList.find((e) => e.date === day).status;
|
||||||
|
return this.works.find((e) => e.work === a).color;
|
||||||
},
|
},
|
||||||
changeDays() {
|
changeDays() {
|
||||||
this.days = moment().daysInMonth();
|
this.days = moment().daysInMonth();
|
||||||
@@ -138,6 +140,11 @@ export default {
|
|||||||
this.employee.push(this.employeeList[index]);
|
this.employee.push(this.employeeList[index]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
choiceDay(day, employee) {
|
||||||
|
return this.scheduleList.find(
|
||||||
|
(e) => day === e.date && e.employee.id === employee
|
||||||
|
)?.date;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -5,11 +5,6 @@ function prepareUrl(url) {
|
|||||||
return `https://astra-dev.dopcore.com/api/${url}`;
|
return `https://astra-dev.dopcore.com/api/${url}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepareUrlApi(url) {
|
|
||||||
if (url.startsWith("http")) return url;
|
|
||||||
return `https://astra-dev.dopcore.com/${url}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleRequest(method, url, headers, attempts, body, type) {
|
function handleRequest(method, url, headers, attempts, body, type) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
(function internalRequest() {
|
(function internalRequest() {
|
||||||
@@ -72,9 +67,7 @@ function request(method, url, headers = {}, body, type = "") {
|
|||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (type === "api") {
|
return fetch(prepareUrl(url), requestOptions);
|
||||||
return fetch(prepareUrlApi(url), requestOptions);
|
|
||||||
} else return fetch(prepareUrl(url), requestOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(url, type, headers, attempts = 3) {
|
function get(url, type, headers, attempts = 3) {
|
||||||
|
|||||||
Reference in New Issue
Block a user