Files
astra-frontend/src/pages/newCalendar/components/CalendarSidebar.vue

413 lines
12 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">
.sidebar.flex.flex-col.gap-y-px
.button.flex.rounded-t
q-btn.button-open(
@click="openSidebar",
dense,
padding="8px"
)
img(:src="arrow")
.button.flex
base-button(width="40px", @click="createForm")
q-icon.plus(name="app:plus", size="24px")
.button.flex.relative.btn-sidebar.button-svg.cursor-pointer(
@click="()=>showActive(svg.name)",
v-for="svg in patientData.arrSvg"
v-click-outside="hideActive"
)
q-btn(
:class="{'active-btn': findActiveBtn(svg.name)}",
dense,
style="borderRadius: 50%",
:padding="svg.name === 'group' ? '10.5px 7.5px' : '4px'"
)
calendar-sidebar-svg.svg(:name-svg="svg.name", :active="svg.active")
.separator.flex.absolute(v-show="allLeave")
.sidebar.flex-col.flex
.mark-top.flex.w-2.h-2
.mark-bottom.flex.w-2.h-2
.mark-text.flex.font-medium.text-sm {{svg.text}}
q-menu(
v-if="svg.name === 'round'",
anchor="center start",
self="top right",
:style="{'margin-left': '8px !important'}"
)
.modal-wrapper.flex.flex-col.gap-y-2
.font-bold.text-xm.px-2 {{svg.text}}
.flex.flex-col
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7.px-2(
v-for="status in patientData.statuses"
)
.priority.rounded-full.flex.mr-1.5px(:class="choiceClass(status.id)")
span {{status.name}}
q-menu(
v-if="svg.name === 'medcard'",
anchor="center start",
self="top right",
:style="{'margin-left': '8px !important'}"
)
.modal-wrapper.flex.flex-col.gap-y-2
.font-bold.text-xm.px-2 {{svg.text}}
.flex.flex-col
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7.px-2(
v-for="medical in medicalData"
)
q-icon(:name="medical.icon", size="20px")
span {{medical.name}}
q-menu.overflow-hidden(
v-if="svg.name === 'group'",
anchor="center start",
self="top right",
:style="{'margin-left': '8px !important'}"
)
.patient-wrapper.flex.flex-col.gap-y-4.px-4.pt-4
.font-bold.text-xm {{svg.text}}
.flex.flex-col.relative(:style="{maxHeight: '391px'}")
.flex.flex-col.gap-y-2
.flex.h-8.w-full.items-center.justify-between
base-input.input(
v-model="foundPerson",
@keyup.enter="searchPerson",
@input="searchPerson",
id="input",
placeholder="Найти пациента...",
:width="160"
size="S",
icon-left
)
template(v-slot:iconLeft)
q-icon.input-icon(name="app:search", size="16px")
q-btn.ml-2(
@click="sortPerson(patientsData)",
:style="{width: '32px', height: '32px', border: '1px solid var(--gray-secondary)'}",
padding="0",
:class="sortingClass"
)
calendar-sidebar-svg(name-svg="sort", :active="sort")
.flex.items-center.justify-between.font-medium.text-smm.h-55.py-2.cursor-pointer(
@click="checkAll(patientsData)",
v-if="!foundPerson"
)
.flex.items-center.gap-x-2
.all-icon.flex.items-center.justify-center
//- q-icon(name="app:patients")
calendar-sidebar-svg.p-6px(name-svg="group", active)
.flex.flex-col.font-medium
.text-smm Все
.grey-color.text.text-xsx {{ patientsData?.length + " пациентов" }}
img(v-if="selectAll(patientsData)", :src="icon_ok")
.person-wrapper.flex.flex-col(@scroll="scrollTo", id="persons")
.person.items-center.flex.justify-between.py-2.cursor-pointer.h-55(
v-for="(person, index) in choiceData(patientsData)",
@click="checkPerson(index, patientsData)"
)
.flex.items-center.gap-x-2
img.h-10.w-10.object-cover.rounded-full(:src="person.avatar")
.flex.flex-col.font-medium
.text-smm {{trimOwnerName(person.last_name, person.first_name, person.patronymic)}}
.grey-color.text.text-xsx {{trimBirthday(person.birthday)}}
img.h-6.w-6(v-if="person.check", :src="icon_ok")
.gradient.flex.absolute(v-if="isGradient")
</template>
<script>
import * as moment from "moment";
import arrow from "@/assets/icons/double_left_arrow.svg";
import icon_ok from "@/assets/icons/icon_ok.svg";
import sort_word from "@/assets/icons/sort_word.svg";
import { patientData } from "@/pages/newCalendar/utils/calendarConfig.js";
import { patientList } from "@/pages/newCalendar/utils/calendarConfig.js";
import CalendarSidebarSvg from "@/pages/newCalendar/components/CalendarSidebarSvg.vue";
import { trimName } from "@/pages/newCalendar/utils/calendarFunctions.js";
import icon_patients from "@/assets/icons/person_group.svg";
import BaseButton from "@/components/base/BaseButton.vue";
import BaseInput from "@/components/base/BaseInput.vue";
export default {
name: "CalendarSidebar",
props: { openSidebar: Function, createForm: Function },
components: { BaseInput, CalendarSidebarSvg, BaseButton },
data() {
return {
icon_patients,
arrow,
icon_ok,
sort_word,
patientData: patientData,
medicalData: patientList.find((e) => e.label === "Первичная медкарта")
.data,
patientsData: patientList.find((e) => e.label === "Пациенты").data,
foundPerson: "",
sortData: [],
sort: false,
trimOwnerName: trimName,
isGradient: true,
};
},
computed: {
allLeave() {
return this.patientData.arrSvg.find(({ active }) => active)?.active
? false
: true;
},
sortingClass() {
return this.sort
? {
"sort-icon-active": true,
}
: {
"sort-icon-default": true,
};
},
},
methods: {
findActiveBtn(value) {
return this.patientData.arrSvg.find(({ name }) => name === value)?.active
? true
: false;
},
hideActive() {
this.patientData.arrSvg.forEach((e) => {
if (e.active) e.active = false;
});
this.sortData = [];
this.foundPerson = "";
this.patientsData.forEach((e) => (e.check = false));
},
showActive(name) {
this.patientData.arrSvg.forEach((e) => {
if (e.name === name) e.active = !e.active;
});
},
choiceClass(priority) {
return {
"none-priority": !priority,
"red-color": priority === 1,
"blue-color": priority === 2,
"green-color": priority === 3,
};
},
checkPerson(index, arr) {
arr.map((e) => {
if (e.id === index) e.check = !e.check;
});
},
selectAll(arr) {
return arr.find((e) => e.check) ? false : true;
},
checkAll(arr) {
arr.map((e) => (e.check = false));
},
searchPerson() {
this.sortData = this.patientsData.filter(
(e) =>
e.last_name.toLowerCase().substr(0, this.foundPerson.length) ===
this.foundPerson.toLowerCase()
);
},
trimBirthday(birthday) {
return moment(birthday, "DD MM YYYY").format("DD MMMM YYYY");
},
choiceData(arr) {
return this.foundPerson ? this.sortData : arr;
},
sortPerson(arr) {
if (!this.sort) {
this.sort = true;
arr.sort((a, b) => (a.last_name > b.last_name ? 1 : -1));
} else {
this.sort = false;
arr.sort((a, b) => (b.last_name > a.last_name ? 1 : -1));
}
},
scrollTo(event) {
if (
Math.abs(
event.currentTarget.scrollHeight -
event.currentTarget.clientHeight -
event.currentTarget.scrollTop
) < 1
)
return (this.isGradient = false);
this.isGradient = true;
},
},
watch: {
foundPerson: {
immediate: true,
handler(val) {
if (val && document.getElementById("persons").offsetHeight < 296) {
this.isGradient = false;
}
},
},
},
};
</script>
<style lang="sass" scoped>
.sidebar
color: var(--font-dark-blue-color)
.button
width: 72px
height: 72px
background: var(--default-white)
align-items: center
justify-content: center
&:last-child
border-bottom-left-radius: 0.25rem
border-bottom-right-radius: 0.25rem
.btn-sidebar
&:hover
& .separator
transition: 0.1s
opacity: 1
.modal-wrapper
width: 232px
padding: 16px 8px 6px
.patient-wrapper
width: 232px
max-height: 445px
min-height: 102px
color: var(--font-dark-blue-color)
.h-55
height: 55px
.status
height: 40px
width: 100%
&:hover
height: 40px
background: var(--gray-thirdly)
cursor: pointer
.person-wrapper
overflow-y: auto
margin-right: -10px
max-height: 296px
&::-webkit-scrollbar
width: 4px
&::-webkit-scrollbar-track:vertical
margin-top: -40px
margin-bottom: 18px
.person
width: calc(100% - 10px)
border-bottom: 1px solid var(--bg-light-grey)
&:first-child
border-top: 1px solid var(--bg-light-grey)
.all-icon
height: 40px
width: 40px
border-radius: 50%
background: var(--surface-blue-big)
#input :deep(.q-field__control)
height: 32px
.q-field__prepend
height: 32px
.input :deep(.q-field__prepend)
padding-right: 4px
.input :deep(.q-field__append)
padding-left: 6px
.input-icon :deep(path)
fill: var(--font-grey-color)
.separator
transition: 0.1s
opacity: 0
z-index: 6
align-items: center
left: 72px
width: max-content
height: 32px
.mark-top
border-bottom-right-radius: 10px
background: var(--bg-body-color)
.mark-bottom
border-top-right-radius: 10px
background: var(--bg-body-color)
.mark-text
padding: 8px 12px
background: var(--font-dark-blue-color)
border-radius: 4px
color: var(--default-white)
.gradient
width: 232px
height: 44px
right: 0px
bottom: 0px
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, var(--default-white) 100%)
.button-open
border: 1px solid var(--gray-secondary)
color: var(--font-grey-color)
background: var(--bg-light-grey)
.sort-icon-default
background-color: var(--bg-light-grey)
color: var(--font-grey-color)
border: 1px solid var(--gray-secondary)
.sort-icon-active
background-color: var(--btn-blue-color)
color: var(--default-white)
.active-btn
transition: background 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.4s cubic-bezier(0.25, 0.8, 0.5, 1)
background: var(--bg-light-blue-color)
.grey-color
color: var(--font-grey-color)
.q-btn :deep(.q-focus-helper)
display: none
.q-btn :deep(.q-ripple)
display: none
.plus :deep(path)
fill: var(--default-white)
.priority
height: 15px
width: 15px
.none-priority
border: 1.5px solid var(--font-grey-color)
.red-color
background: var(--system-color-red)
.blue-color
background: var(--btn-blue-color)
.green-color
background: var(--system-color-green)
.button-svg
&:hover
.svg :deep(.hover)
opacity: 1
transition: opacity 0.3s cubic-bezier(0.25, 0.8, 0.5, 1), opacity 0.4s cubic-bezier(0.25, 0.8, 0.5, 1)
</style>
<style lang="sass">
.q-menu
box-shadow: -4px -4px 8px 0px rgba(9, 10, 21, 0.10), 4px 4px 8px 0px rgba(9, 10, 21, 0.10)
</style>