392 lines
11 KiB
Vue
392 lines
11 KiB
Vue
<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"
|
||
)
|
||
img(:src="status.icon")
|
||
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"
|
||
)
|
||
img(:src="medical.icon")
|
||
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",
|
||
:iconLeft="!foundPerson",
|
||
iconRight
|
||
)
|
||
template(v-slot:iconLeft)
|
||
q-icon(name="app:icon-search", size="16px", style="color: var(--font-grey-color)")
|
||
template(v-slot:iconRight)
|
||
q-icon.cursor-pointer(
|
||
@click="copyValue(foundPerson)"
|
||
name="app:icon-copy",
|
||
size="16px",
|
||
style="color: var(--font-grey-color)"
|
||
)
|
||
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
|
||
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 {{person.birthday}}
|
||
img.h-6.w-6(v-if="person.check", :src="icon_ok")
|
||
.gradient.flex.absolute(v-if="isGradient")
|
||
</template>
|
||
|
||
<script>
|
||
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;
|
||
});
|
||
},
|
||
copyValue(text) {
|
||
navigator.clipboard.writeText(text);
|
||
},
|
||
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()
|
||
);
|
||
},
|
||
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
|
||
|
||
.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)
|
||
.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>
|