Files
astra-frontend/src/pages/newCalendar/components/CalendarSidebar.vue
2023-07-18 17:40:12 +03:00

368 lines
10 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-1
.button.flex.rounded-t
q-btn(
@click="openSidebar",
dense,
padding="8px",
style="color: var(--font-grey-color); background: var(--bg-light-grey)"
)
img(:src="arrow")
.button.flex
base-button(width="40px", @click="createForm")
q-icon(name="app:plus", size="12px")
.button.flex.relative.btn-sidebar.button-svg.cursor-pointer(
@click="()=>showActive(svg.name)",
v-for="svg in patientData.arrSvg"
)
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'}",
@before-hide="hideActive"
)
.status-wrapper.flex.flex-col.gap-y-4.p-4
.font-bold.text-xm {{svg.text}}
.flex.flex-col.gap-2px
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7(
v-for="status in patientData.statuses",
v-close-popup
)
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'}",
@before-hide="hideActive"
)
.fill-wrapper.flex.flex-col.gap-y-4.p-4
.font-bold.text-xm {{svg.text}}
.flex.flex-col.gap-2px
.status.flex.items-center.gap-x-1.font-medium.text-smm.rounded.h-7(
v-for="medical in medicalData",
v-close-popup
)
img(:src="medical.icon")
span {{medical.name}}
q-menu(
v-if="svg.name === 'group'",
anchor="center start",
self="top right",
:style="{'margin-left': '8px !important'}",
@before-hide="hideActive"
)
.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",
debounce="10",
@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(
icon="app:sort-number",
@click="sortPerson(patientsData)",
:style="{width: '32px', height: '32px'}",
padding="0",
:class="sortingClass"
)
.flex.items-center.justify-between.font-medium.text-smm.h-10.py-2.cursor-pointer(
@click="checkAll(patientsData)"
)
.flex.items-center Все
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(
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)}}
.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 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 {
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 = this.patientData.arrSvg.map((e) => {
if (e.name === name) return { ...e, active: true };
return { ...e, active: false };
});
},
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 (event.currentTarget.scrollTop === 305)
return (this.isGradient = false);
this.isGradient = true;
},
},
watch: {
foundPerson: {
immediate: true,
handler(val) {
if (val && document.getElementById("persons").offsetHeight < 311) {
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
.status-wrapper
width: 232px
height: 188px
.fill-wrapper
height: 158px
width: 232px
.patient-wrapper
width: 232px
max-height: 445px
color: var(--font-dark-blue-color)
.status
height: 28px
width: 100%
&:hover
height: 28px
background: var(--bg-light-grey)
cursor: pointer
.person-wrapper
overflow-y: auto
margin-right: -10px
max-height: 311px
&::-webkit-scrollbar
width: 4px
&::-webkit-scrollbar-track:vertical
margin-top: -28px
margin-bottom: 18px
.person
height: 56px
width: calc(100% - 10px)
border-bottom: 1px solid var(--bg-light-grey)
&:first-child
border-top: 1px solid var(--bg-light-grey)
#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%)
.sort-icon-default
background-color: var(--bg-light-grey)
color: var(--font-grey-color)
.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)
.q-btn :deep(.q-focus-helper)
display: none
.q-btn :deep(.q-ripple)
display: none
.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>