Merge branch 'add-admin-calendar' into 'master'

Добавлен календарь администратора

See merge request astra/astra-frontend!509
This commit is contained in:
Kirill Andrusyak
2023-09-21 20:19:22 +00:00
24 changed files with 1007 additions and 500 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -233,4 +233,10 @@ export default {
.input :deep(.q-field__marginal) .input :deep(.q-field__marginal)
height: auto !important height: auto !important
.input :deep(.q-field__shadow)
opacity: 0.5
top: 3px
color: var(--font-grey-color)
margin-left: 8px
</style> </style>

View File

@@ -2,7 +2,10 @@
.w-full.flex .w-full.flex
calendar-sidebar(v-if="!isOpen", :open-sidebar="openSidebar", :create-form="createForm") calendar-sidebar(v-if="!isOpen", :open-sidebar="openSidebar", :create-form="createForm")
calendar-open-sidebar(v-else, :open-sidebar="openSidebar", :create-form="createForm") calendar-open-sidebar(v-else, :open-sidebar="openSidebar", :create-form="createForm")
calendar-wrapper.ml-2(:open-sidebar="isOpen") component.ml-2(
v-bind:is="calendarComponent",
:open-sidebar="isOpen",
)
base-modal(v-model="isShowForm", title="Создание записи", modal-padding) base-modal(v-model="isShowForm", title="Создание записи", modal-padding)
create-event-form(:close-form="closeForm") create-event-form(:close-form="closeForm")
base-modal(v-model="previewVisibility", :hideHeader="true", :modalPadding="true") base-modal(v-model="previewVisibility", :hideHeader="true", :modalPadding="true")
@@ -12,7 +15,8 @@
<script> <script>
import CalendarSidebar from "@/pages/newCalendar/components/CalendarSidebar"; import CalendarSidebar from "@/pages/newCalendar/components/CalendarSidebar";
import CalendarOpenSidebar from "@/pages/newCalendar/components/CalendarOpenSidebar"; import CalendarOpenSidebar from "@/pages/newCalendar/components/CalendarOpenSidebar";
import CalendarWrapper from "@/pages/newCalendar/components/CalendarWrapper"; import DoctorCalendarWrapper from "@/pages/newCalendar/components/doctorCalendar/CalendarWrapper";
import ManagerCalendarWrapper from "@/pages/newCalendar/components/managerCalendar/CalendarWrapper";
import CreateEventForm from "@/pages/newCalendar/components/CreateEventForm"; import CreateEventForm from "@/pages/newCalendar/components/CreateEventForm";
import * as moment from "moment/moment"; import * as moment from "moment/moment";
import BaseModal from "@/components/base/BaseModal.vue"; import BaseModal from "@/components/base/BaseModal.vue";
@@ -23,7 +27,8 @@ export default {
components: { components: {
CalendarSidebar, CalendarSidebar,
CalendarOpenSidebar, CalendarOpenSidebar,
CalendarWrapper, DoctorCalendarWrapper,
ManagerCalendarWrapper,
CreateEventForm, CreateEventForm,
BaseModal, BaseModal,
CalendarRecordPreview, CalendarRecordPreview,
@@ -40,7 +45,13 @@ export default {
...mapState({ ...mapState({
selectedRecordId: (state) => state.calendar.selectedRecordId, selectedRecordId: (state) => state.calendar.selectedRecordId,
selectedDates: (state) => state.calendar.selectedDates, selectedDates: (state) => state.calendar.selectedDates,
calendarShape: (state) => state.calendarShape,
}), }),
calendarComponent() {
return this.calendarShape === "doctor"
? "doctor-calendar-wrapper"
: "manager-calendar-wrapper";
},
}, },
methods: { methods: {
openSidebar() { openSidebar() {
@@ -73,10 +84,11 @@ export default {
deep: true, deep: true,
handler(value) { handler(value) {
if (this.$route.path === "/calendar") { if (this.$route.path === "/calendar") {
let dateType = this.calendarShape === "doctor" ? "week" : "day";
if (!value?.start || !value?.end) { if (!value?.start || !value?.end) {
this.changeSelectedDates({ this.changeSelectedDates({
from: moment().clone().startOf("week"), from: moment().clone().startOf(dateType),
to: moment().clone().endOf("week"), to: moment().clone().endOf(dateType),
}); });
this.$router.replace({ this.$router.replace({
query: { query: {
@@ -87,12 +99,13 @@ export default {
} else if ( } else if (
value?.start !== this.selectedDates?.from?.format("DD.MM.YYYY") || value?.start !== this.selectedDates?.from?.format("DD.MM.YYYY") ||
value?.end !== this.selectedDates?.to?.format("DD.MM.YYYY") value?.end !== this.selectedDates?.to?.format("DD.MM.YYYY")
) ) {
this.changeSelectedDates({ this.changeSelectedDates({
from: this.convertDate(value?.start), from: this.convertDate(value?.start).clone().startOf("day"),
to: this.convertDate(value?.end), to: this.convertDate(value?.end).clone().endOf("day"),
}); });
} }
}
}, },
}, },
selectedDates: { selectedDates: {

View File

@@ -15,7 +15,7 @@ export default {
timeCoil: Array, timeCoil: Array,
currentTime: String, currentTime: String,
dayEndTime: Number, dayEndTime: Number,
isCurrentWeek: Boolean, isCurrent: Boolean,
}, },
computed: { computed: {
currentHour() { currentHour() {
@@ -33,7 +33,7 @@ export default {
if ( if (
convertTime(elem, 0, 3) === this.currentHour && convertTime(elem, 0, 3) === this.currentHour &&
!this.isEndDay && !this.isEndDay &&
this.isCurrentWeek this.isCurrent
) { ) {
return { return {
"current-time": true, "current-time": true,

View File

@@ -1,112 +0,0 @@
<template lang="pug">
.calendar-column-wrapper.flex.flex-col
.header.flex.flex-col.items-center.justify-center.top-0.pt-3.pb-10px
span.font-bold.text-base.color-black {{ date?.format("D MMMM")}}
span.text-smm.color-grey {{ transformDayName(date?.format("dddd"))}}
.body.h-full.px-1.py-1
calendar-record-card(
v-for="record in filteredRecords",
:key="record?.id",
:record="record",
:expanded-type="expandedDisplayType",
:style="eventCardPosition(record.start, record.end)",
@click="changeSelectedRecordId(record?.id)",
)
.footer.flex.items-center.justify-center.bg-white.h-9(v-if="!expandedDisplayType")
span.text-smm.color-grey 0 записей
</template>
<script>
import * as moment from "moment/moment";
import CalendarRecordCard from "@/pages/newCalendar/components/CalendarRecordCard.vue";
import { verifyTime } from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapActions, mapState } from "vuex";
export default {
name: "CalendarColumn",
components: { CalendarRecordCard },
props: {
date: Object,
expandedDisplayType: Boolean,
dayEndTime: Number,
dayStartTime: Number,
},
data() {
return {
pixelsPerHour: 76,
};
},
computed: {
...mapState({
events: (state) => state.calendar.events || [],
}),
filteredRecords() {
return this.events.filter(
(elem) =>
moment.parseZone(elem.start).format("YYYY-MM-DD") ===
this.date.format("YYYY-MM-DD")
);
},
pixelsPerMinute() {
return this.pixelsPerHour / 60;
},
},
methods: {
...mapActions({
changeSelectedRecordId: "changeSelectedRecordId",
}),
transformDayName(name) {
return name[0]?.toUpperCase() + name?.slice(1);
},
eventCardPosition(startTime, endTime) {
let start = startTime
.slice(11, -4)
.split(":")
.map((elem) => parseInt(elem, 10));
let end = endTime.slice(11, -4);
let position =
(start[0] - this.dayStartTime) * this.pixelsPerHour +
start[1] * this.pixelsPerMinute +
4;
if (
parseInt(start[0], 10) < this.dayStartTime ||
verifyTime(end) > this.dayEndTime
) {
return {
top: "0px",
visibility: "hidden",
};
}
return {
top: `${position}px`,
};
},
},
};
</script>
<style lang="sass" scoped>
.calendar-column-wrapper
border-right: 1px solid var(--border-light-grey-color)
&:last-child
border-right: none
.header
position: sticky
z-index: 5
background-color: var(--default-white)
.body
position: relative
z-index: 3
.color-black
color: var(--font-dark-blue-color)
.color-grey
color: var(--font-grey-color)
.footer
border-top: 1px solid var(--border-light-grey-color)
@media(min-height: 1090px)
border-bottom: 1px solid var(--border-light-grey-color)
</style>

View File

@@ -33,12 +33,12 @@
.flex.gap-x-14(:class="bodyClass") .flex.gap-x-14(:class="bodyClass")
.flex.gap-x-2.items-center( .flex.gap-x-2.items-center(
v-for="contact in contacts", v-for="contact in contacts",
:key="contact.value", :key="contact?.value",
) )
q-icon.network-icon(:name="contact.icon", size="16px") q-icon.network-icon(:name="contact?.icon", size="16px")
.text-xxs.cursor-default {{ contact.value }} .text-xxs.cursor-default {{ contact?.value }}
.h-6.w-6.color-black.background-dark-grey.text-xxs.rounded.flex.items-center.justify-center.cursor-default( .h-6.w-6.color-black.background-dark-grey.text-xxs.rounded.flex.items-center.justify-center.cursor-default(
v-if="collapsedDisplayCondition" v-if="collapsedDisplayCondition && contact"
) +1 ) +1
</template> </template>

View File

@@ -1,294 +0,0 @@
<template lang="pug">
.schedule.flex-1.flex.flex-col.relative(
:style="{width: openSidebar ? 'calc(100vw - 320px)' : 'calc(100vw - 160px)'}"
)
calendar-header.w-full.mb-1(v-model="displayType")
.schedule-body.h-full.bg-white.w-full(:class="{rounded: !expandedDisplayType}")
.column-wrapper.flex.ml-20(:style="columnWrapperWidth")
calendar-column(
v-for="date in dateRange",
:key="date",
:date="date",
:style="columnHeight",
:expanded-display-type="expandedDisplayType",
:day-start-time="validateStartTime"
:day-end-time="validateEndTime"
)
.flex.relative(
:style="expandedDisplayType ? backgroundWrapperWidth : {}",
:class="{'border-bottom': expandedDisplayType}"
)
.time-coil-wrapper.left-0.-mt-12
calendar-clock-column(
:time-coil="timeCoil",
:current-time="currentTime",
:is-current-week="isCurrentWeek",
:day-end-time="validateEndTime"
)
.time-circle-indicator.left-74px.h-3.w-3.rounded-full.absolute(
v-if="isShownIndicator",
:style="circleIndicatorLocation"
)
span.time-line-indicator.block.left-20.absolute(
v-if="isShownIndicator",
:style="lineIndicatorLocation"
)
calendar-background.flex-1
.w-full.h-3.bg-white.footer(v-if="expandedDisplayType")
</template>
<script>
import CalendarHeader from "@/pages/newCalendar/components/CalendarHeader";
import CalendarBackground from "@/pages/newCalendar/components/CalendarBackground.vue";
import CalendarClockColumn from "@/pages/newCalendar/components/CalendarClockColumn.vue";
import CalendarColumn from "@/pages/newCalendar/components/CalendarColumn.vue";
import {
convertTime,
verifyTime,
} from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapState, mapActions } from "vuex";
import * as moment from "moment/moment";
export default {
name: "CalendarWrapper",
components: {
CalendarHeader,
CalendarBackground,
CalendarClockColumn,
CalendarColumn,
},
props: {
openSidebar: Boolean,
},
data() {
return {
displayType: "expanded",
currentTime: "",
isCurrentWeek: true,
isShownIndicator: true,
timeCoil: [],
timer: null,
pixelsPerHour: 76,
};
},
computed: {
...mapState({
workingHours: (state) => state.calendar.workingHours,
selectedDates: (state) => state.calendar.selectedDates,
}),
hours() {
return convertTime(this.currentTime, 0, -6);
},
minutes() {
return convertTime(this.currentTime, 3, -3);
},
hoursMinutes() {
return this.currentTime.slice(0, -3);
},
pixelsPerMinute() {
return this.pixelsPerHour / 60;
},
backgroundHeight() {
return (
(this.validateEndTime - this.validateStartTime) * this.pixelsPerHour
);
},
expandedDisplayType() {
return this.displayType === "expanded";
},
dateRange() {
let diff = this.selectedDates?.to.diff(this.selectedDates?.from, "days");
let range = [];
for (let i = 0; i <= diff; i++) {
range.push(this.selectedDates?.from.clone().add(i, "day"));
}
return range;
},
validateStartTime() {
return verifyTime(this.workingHours.start);
},
validateEndTime() {
return verifyTime(this.workingHours.end);
},
columnHeight() {
return this.expandedDisplayType
? {
height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
width: "380px",
}
: {
height: `${this.timeCoil.length * this.pixelsPerHour + 96}px`,
width: this.openSidebar
? `calc((100vw - 320px - 80px) / ${this.dateRange.length})`
: `calc((100vw - 160px - 80px) / ${this.dateRange.length})`,
};
},
columnWrapperWidth() {
return this.expandedDisplayType
? {
width: `${380 * this.dateRange.length}px`,
}
: {
width: this.openSidebar
? "calc(100vw - 320px - 80px)"
: "calc(100vw - 160px - 80px)",
};
},
backgroundWrapperWidth() {
return {
width: `${380 * this.dateRange.length + 80}px`,
};
},
lineIndicatorLocation() {
return {
top: `${this.calculateIndicatorLocation()}px`,
};
},
circleIndicatorLocation() {
return {
top: `${this.calculateIndicatorLocation() + 42}px`,
};
},
},
methods: {
...mapActions({
getEvents: "getEvents",
}),
changeCurrentTime() {
this.currentTime = moment().format("HH:mm:ss");
},
timeCoilInitialization() {
this.timeCoil = [];
for (let i = this.validateStartTime; i < this.validateEndTime; i++) {
if (
i === this.hours &&
this.hours !== this.validateEndTime &&
this.isCurrentWeek
) {
this.timeCoil.push(this.hoursMinutes);
} else this.timeCoil.push(`${i}:00`);
}
},
changeTimeCoil() {
this.timeCoil = this.timeCoil.map((elem) => {
if (convertTime(elem, 0, -3) === this.hours) {
return this.hoursMinutes;
}
return elem.slice(0, -3) + ":00";
});
},
startTimer() {
if (
this.hours >= this.validateStartTime &&
this.hours < this.validateEndTime
) {
this.timer = setInterval(() => {
this.changeCurrentTime();
this.changeTimeCoil();
}, 5000);
}
},
stopTimer() {
clearInterval(this.timer);
this.timer = null;
},
calculateIndicatorLocation() {
let newTime = this.currentTime
.split(":")
.map((elem) => parseInt(elem, 10));
let result =
(newTime[0] - this.validateStartTime) * this.pixelsPerHour +
newTime[1] * this.pixelsPerMinute;
if (result > this.backgroundHeight || result < 0) {
this.isShownIndicator = false;
return 0;
}
return result;
},
},
watch: {
currentTime() {
if (
this.hours === this.validateEndTime &&
this.minutes > 0 &&
this.timer
) {
this.stopTimer();
this.timeCoilInitialization();
}
},
selectedDates: {
deep: true,
handler(newValue) {
this.isCurrentWeek =
newValue?.from.isSame(moment().clone().startOf("week")) &&
newValue?.to.isSame(moment().clone().endOf("week"));
this.isShownIndicator = this.isCurrentWeek;
if (this.timer) {
this.stopTimer();
this.timeCoilInitialization();
}
if (this.isCurrentWeek) {
this.changeCurrentTime();
this.timeCoilInitialization();
this.startTimer();
}
},
},
},
mounted() {
this.changeCurrentTime();
this.timeCoilInitialization();
this.startTimer();
},
beforeUnmount() {
this.stopTimer();
},
};
</script>
<style lang="sass" scoped>
.schedule-body
overflow-x: auto
border-top-left-radius: 4px
border-top-right-radius: 4px
&::-webkit-scrollbar-track:horizontal
margin: 0 24px 0 24px
.background
background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)
.time-coil-wrapper
position: sticky
z-index: 5
background-color: var(--default-white)
padding-top: 38px
.column-wrapper
height: 60px
position: relative
background-color: var(--default-white)
.footer
border-bottom-left-radius: 4px
border-bottom-right-radius: 4px
.border-bottom
border-bottom: 4px solid var(--bg-ligth-blue-color)
.records-count
border-right: 1px solid var(--border-light-grey-color)
&:last-child
border-right: none
.border-top
border-top: 1px solid var(--border-light-grey-color)
.time-circle-indicator
background-color: var(--bg-event-red-color)
z-index: 5
.time-line-indicator
border-top: 1px solid var(--bg-event-red-color)
z-index: 4
width: calc(100% - 80px)
</style>

View File

@@ -0,0 +1,49 @@
<template lang="pug">
.calendar-column-wrapper.flex.flex-col
.header.flex.flex-col.items-center.justify-center.top-0.pt-3.pb-10px
span.font-bold.text-base.color-black {{ date?.format("D MMMM")}}
span.text-smm.color-grey {{ capitalizeFirstChar(date?.format("dddd"))}}
.body.h-full.px-1.py-1
calendar-record-card(
v-for="record in filteredRecords",
:key="record?.id",
:record="record",
:expanded-type="expandedDisplayType",
:style="eventCardPosition(record.start, record.end)",
@click="changeSelectedRecordId(record?.id)",
)
.footer.flex.items-center.justify-center.bg-white.h-9(v-if="!expandedDisplayType")
span.text-smm.color-grey 0 записей
</template>
<script>
import * as moment from "moment/moment";
import { columnMixin } from "@/pages/newCalendar/mixins/columnMixin.js";
import { capitalizeFirstChar } from "@/pages/newCalendar/utils/calendarFunctions.js";
export default {
name: "CalendarColumn",
mixins: [columnMixin],
props: {
date: Object,
expandedDisplayType: Boolean,
},
data() {
return {
capitalizeFirstChar: capitalizeFirstChar,
};
},
computed: {
filteredRecords() {
return this.events.filter(
(elem) =>
moment.parseZone(elem.start).format("YYYY-MM-DD") ===
this.date.format("YYYY-MM-DD")
);
},
},
};
</script>
<style lang="sass" scoped>
@import "@/pages/newCalendar/sass/columnStyle.sass"
</style>

View File

@@ -74,15 +74,13 @@
</template> </template>
<script> <script>
import BaseCalendar from "@/components/base/Calendar/BaseCalendar.vue";
import { mapState, mapActions } from "vuex";
import { v_model } from "@/shared/mixins/v-model"; import { v_model } from "@/shared/mixins/v-model";
import DateSwitcherSvg from "@/pages/newCalendar/components/CalendarDateSwitcherSvg.vue"; import DateSwitcherSvg from "@/pages/newCalendar/components/CalendarDateSwitcherSvg.vue";
import BaseInput from "@/components/base/BaseInput.vue"; import { headerMixin } from "@/pages/newCalendar/mixins/headerMixin.js";
export default { export default {
name: "CalendarHeader", name: "CalendarHeader",
mixins: [v_model], mixins: [v_model, headerMixin],
components: { BaseInput, BaseCalendar, DateSwitcherSvg }, components: { DateSwitcherSvg },
data() { data() {
return { return {
displayTypesList: [ displayTypesList: [
@@ -99,7 +97,6 @@ export default {
from: null, from: null,
to: null, to: null,
}, },
calendarVisibility: false,
}; };
}, },
computed: { computed: {
@@ -108,9 +105,6 @@ export default {
"D MMMM YYYY" "D MMMM YYYY"
)} ${this.dates?.to?.format("D MMMM YYYY")}`; )} ${this.dates?.to?.format("D MMMM YYYY")}`;
}, },
...mapState({
selectedDates: (state) => state.calendar.selectedDates,
}),
}, },
methods: { methods: {
previousWeek() { previousWeek() {
@@ -123,13 +117,6 @@ export default {
this.dates.from = this.dates.from.clone().add(diff, "day"); this.dates.from = this.dates.from.clone().add(diff, "day");
this.dates.to = this.dates.to.clone().add(diff, "day"); this.dates.to = this.dates.to.clone().add(diff, "day");
}, },
...mapActions({
changeSelectedDates: "changeSelectedDates",
getEvents: "getEvents",
}),
saveDatesChange() {
this.calendarVisibility = false;
},
initializeDates() { initializeDates() {
this.dates = { this.dates = {
from: this.selectedDates.from.clone(), from: this.selectedDates.from.clone(),
@@ -164,50 +151,7 @@ export default {
</script> </script>
<style lang="sass" scoped> <style lang="sass" scoped>
.calendar-header-wrapper @import "@/pages/newCalendar/sass/headerStyle.sass"
background-color: var(--default-white)
height: 72px
border-radius: 4px
z-index: 10
.text
color: var(--font-dark-blue-color)
.text-grey-color
color: var(--font-grey-color)
.text-primary
color: var(--font-dark-blue-color-0) !important
.bg-secondary
background: var(--bg-light-grey) !important
.q-btn--round
width: 32px !important
height: 32px !important
min-width: 32px !important
min-height: 32px !important
.q-btn-group :deep(.q-btn-item)
border-radius: 4px !important
.search :deep(.q-field__marginal)
height: auto !important
.search :deep(.q-field__prepend)
padding-right: 6px !important
.search-icon :deep(path)
fill: var(--font-grey-color)
.calendar-icon :deep(path)
fill: var(--font-dark-blue-color)
.active-toggle
background: var(--btn-blue-color)
.border-toggle
border: 1px solid var(--gray-secondary)
</style> </style>
<style lang="sass"> <style lang="sass">
.q-field--outlined.q-field--readonly .q-field__control:before .q-field--outlined.q-field--readonly .q-field__control:before

View File

@@ -0,0 +1,135 @@
<template lang="pug">
.schedule.flex-1.flex.flex-col.relative(
:style="{width: openSidebar ? 'calc(100vw - 320px)' : 'calc(100vw - 160px)'}"
)
calendar-header.w-full.mb-1(v-model="displayType")
.schedule-body.h-full.bg-white.w-full(:class="{rounded: !expandedDisplayType}")
.column-wrapper.flex.ml-20(:style="columnWrapperWidth")
calendar-column(
v-for="date in dateRange",
:key="date",
:date="date",
:style="columnHeight",
:expanded-display-type="expandedDisplayType",
:day-start-time="validateStartTime"
:day-end-time="validateEndTime"
)
.flex.relative(
:style="expandedDisplayType ? backgroundWrapperWidth : {}",
:class="{'border-bottom': expandedDisplayType}"
)
.time-coil-wrapper.left-0.-mt-16
calendar-clock-column(
:time-coil="timeCoil",
:current-time="currentTime",
:is-current="isCurrent",
:day-end-time="validateEndTime"
)
.time-circle-indicator.left-74px.h-3.w-3.rounded-full.absolute(
v-if="isShownIndicator",
:style="circleIndicatorLocation"
)
span.time-line-indicator.block.left-20.absolute(
v-if="isShownIndicator",
:style="lineIndicatorLocation"
)
calendar-background.flex-1
.w-full.h-3.bg-white.footer(v-if="expandedDisplayType")
</template>
<script>
import CalendarHeader from "@/pages/newCalendar/components/doctorCalendar/CalendarHeader";
import CalendarColumn from "@/pages/newCalendar/components/doctorCalendar/CalendarColumn.vue";
import { mapState } from "vuex";
import * as moment from "moment/moment";
import { wrapperMixin } from "@/pages/newCalendar/mixins/wrapperMixin.js";
export default {
name: "CalendarWrapper",
components: {
CalendarHeader,
CalendarColumn,
},
props: {
openSidebar: Boolean,
},
mixins: [wrapperMixin],
data() {
return {
displayType: "expanded",
};
},
computed: {
...mapState({
selectedDates: (state) => state.calendar.selectedDates,
}),
expandedDisplayType() {
return this.displayType === "expanded";
},
backgroundWrapperWidth() {
return {
width: `${380 * this.dateRange.length + 80}px`,
};
},
dateRange() {
let diff = this.selectedDates?.to.diff(this.selectedDates?.from, "days");
let range = [];
for (let i = 0; i <= diff; i++) {
range.push(this.selectedDates?.from.clone().add(i, "day"));
}
return range;
},
columnHeight() {
return this.expandedDisplayType
? {
height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
width: "380px",
}
: {
height: `${this.timeCoil.length * this.pixelsPerHour + 96}px`,
width: this.openSidebar
? `calc((100vw - 320px - 80px) / ${this.dateRange.length})`
: `calc((100vw - 160px - 80px) / ${this.dateRange.length})`,
};
},
columnWrapperWidth() {
return this.expandedDisplayType
? {
width: `${380 * this.dateRange.length}px`,
}
: {
width: this.openSidebar
? "calc(100vw - 320px - 80px)"
: "calc(100vw - 160px - 80px)",
};
},
},
watch: {
selectedDates: {
deep: true,
handler(newValue) {
this.isCurrent =
newValue?.from.isSame(moment().clone().startOf("week"), "day") &&
newValue?.to.isSame(moment().clone().endOf("week"), "day");
this.isShownIndicator = this.isCurrent;
if (this.timer) {
this.stopTimer();
this.timeCoilInitialization();
}
if (this.isCurrent) {
this.changeCurrentTime();
this.timeCoilInitialization();
this.startTimer();
}
},
},
},
mounted() {
this.changeCurrentTime();
this.timeCoilInitialization();
},
};
</script>
<style lang="sass" scoped>
@import "@/pages/newCalendar/sass/wrapperStyle.sass"
</style>

View File

@@ -0,0 +1,62 @@
<template lang="pug">
.calendar-column-wrapper.flex.flex-col
.header.flex.items-center.justify-between.top-0.py-2.px-6
.flex.h-full.items-center.h-11
q-avatar.mr-2(
size="40px",
round
)
img(:src="medic?.photo || defaultPhoto", alt="doctor")
.flex.flex-col.justify-between
span.text-dark {{trimName(medic?.last_name, medic?.first_name, medic?.patronymic)}}
span.text-xsx.color-grey {{medic?.job || "Терапевт"}}
button(@click="locked = !locked")
q-icon.lock-icon(
:name="locked ? 'app:lock' : 'app:lock-open'",
size="24px"
)
.body.h-full.px-1.py-1
calendar-record-card(
v-for="record in filteredRecords",
:key="record?.id",
:record="record",
:expanded-type="true",
:style="eventCardPosition(record.start, record.end)",
@click="changeSelectedRecordId(record?.id)",
)
</template>
<script>
import { columnMixin } from "@/pages/newCalendar/mixins/columnMixin.js";
import { trimName } from "@/pages/newCalendar/utils/calendarFunctions.js";
import doctorAvatar from "@/assets/images/doctor.png";
import { mapState } from "vuex";
export default {
name: "CalendarColumn",
mixins: [columnMixin],
props: {
medic: Object,
},
data() {
return {
trimName: trimName,
defaultPhoto: doctorAvatar,
locked: false,
};
},
computed: {
...mapState({
events: (state) => state.calendar.events,
}),
filteredRecords() {
return this.events.filter((elem) => elem?.medic?.id === this.medic?.id);
},
},
};
</script>
<style lang="sass" scoped>
@import "@/pages/newCalendar/sass/columnStyle.sass"
.lock-icon :deep(path)
fill: var(--font-grey-color)
</style>

View File

@@ -0,0 +1,141 @@
<template lang="pug">
.calendar-header-wrapper.w-full.flex.items-center.p-4.justify-between
base-input.search(
iconLeft,
:width="280",
size="M",
placeholder="Найти ...",
icon-left
)
template(v-slot:iconLeft)
q-icon.search-icon(name="app:search", size="20px")
.flex.gap-x-4.items-center.justify-center
q-btn(
color="secondary",
round,
size="14px",
dense,
icon="arrow_back_ios_new",
text-color="primary",
padding="2px 11px 2px 8px",
@click="previousDate",
)
base-input.search(
size="M"
:width="332",
v-model="currentDate",
:shadow-text="inputShadowText"
)
.h-5.w-5.flex.items-center.justify-center.ml-3
q-icon.calendar-icon.text.cursor-pointer(
:name="calendarVisibility ? 'app:cancel-mini' : 'app:calendar'",
size="20px",
)
q-menu(
:style="{'margin-top': '8px !important'}"
v-model="calendarVisibility",
transition-show="scale",
transition-hide="scale"
self="top middle",
:offset="[130, 8]"
)
base-calendar(
v-model="date",
:save="saveDatesChange",
:start-year="2000"
)
q-btn(
color="secondary",
icon="arrow_forward_ios",
round,
size="14px",
text-color="primary",
dense,
@click="nextDate"
)
.h-10.p-1.flex.items-center.justify-between.bg-secondary.rounded.text-grey-color.ml-52.border
q-btn-toggle(
v-model="value",
:options="displayTypesList",
no-caps,
padding="0px 12px"
)
</template>
<script>
import { v_model } from "@/shared/mixins/v-model";
import { headerMixin } from "@/pages/newCalendar/mixins/headerMixin.js";
import { capitalizeFirstChar } from "@/pages/newCalendar/utils/calendarFunctions.js";
export default {
name: "CalendarHeader",
mixins: [v_model, headerMixin],
data() {
return {
displayTypesList: [
{
value: "day",
label: "День",
},
{
value: "week",
label: "Неделя",
},
],
date: null,
};
},
computed: {
currentDate() {
return this.date?.format("D MMMM YYYY");
},
inputShadowText() {
console.log(this.date, capitalizeFirstChar(this.date?.format("dddd")));
return this.date?.isValid()
? capitalizeFirstChar(this.date?.format("dddd"))
: "";
},
},
methods: {
previousDate() {
this.date = this.date?.clone()?.subtract(1, "day");
},
nextDate() {
this.date = this.date?.clone()?.add(1, "day");
},
initializeDates() {
this.date = this.selectedDates.from.clone();
},
},
watch: {
date: {
deep: true,
handler(val) {
if (!val?.isSame(this.selectedDates?.from, "day"))
this.changeSelectedDates({
from: val,
to: val?.clone()?.endOf("day"),
});
},
},
selectedDates: {
deep: true,
immediate: true,
handler(val) {
if (!val?.from.isSame(this.date, "day")) this.initializeDates();
},
},
},
};
</script>
<style lang="sass" scoped>
@import "@/pages/newCalendar/sass/headerStyle.sass"
.q-btn-toggle :deep(span)
font-weight: 500
.q-btn-toggle :deep(.q-btn-item)
height: 32px
</style>
<style lang="sass">
.q-field--outlined.q-field--readonly .q-field__control:before
border-style: solid !important
</style>

View File

@@ -0,0 +1,132 @@
<template lang="pug">
.schedule.flex-1.flex.flex-col.relative(
:style="{width: openSidebar ? 'calc(100vw - 320px)' : 'calc(100vw - 160px)'}"
)
calendar-header.w-full.mb-1(v-model="displayType")
.schedule-body.h-full.bg-white.w-full
.column-wrapper.flex.ml-20(:style="columnWrapperWidth")
calendar-column(
v-for="medic in filteringMedics",
:key="medic?.id",
:medic="medic",
:style="columnStyle",
:expanded-display-type="true",
:day-start-time="validateStartTime"
:day-end-time="validateEndTime"
)
.flex.relative.border-bottom(
:style="backgroundWrapperWidth",
)
.time-coil-wrapper.left-0.-mt-16
calendar-clock-column(
:time-coil="timeCoil",
:current-time="currentTime",
:is-current="isCurrent",
:day-end-time="validateEndTime"
)
.time-circle-indicator.left-74px.h-3.w-3.rounded-full.absolute(
v-if="isShownIndicator",
:style="circleIndicatorLocation"
)
span.time-line-indicator.block.left-20.absolute(
v-if="isShownIndicator",
:style="lineIndicatorLocation"
)
calendar-background.flex-1
.w-full.h-3.bg-white.footer
</template>
<script>
import CalendarHeader from "@/pages/newCalendar/components/managerCalendar/CalendarHeader";
import CalendarColumn from "@/pages/newCalendar/components/managerCalendar/CalendarColumn.vue";
import { mapState } from "vuex";
import * as moment from "moment/moment";
import { wrapperMixin } from "@/pages/newCalendar/mixins/wrapperMixin.js";
export default {
name: "CalendarWrapper",
components: {
CalendarHeader,
CalendarColumn,
},
props: {
openSidebar: Boolean,
},
mixins: [wrapperMixin],
data() {
return {
displayType: "day",
};
},
computed: {
...mapState({
selectedDates: (state) => state.calendar.selectedDates,
events: (state) => state.calendar.events,
}),
filteringMedics() {
let medicsList = [];
this.events?.forEach(({ medic }) => {
if (!medicsList.includes(JSON.stringify(medic)))
medicsList.push(JSON.stringify(medic));
});
return medicsList?.map((elem) => JSON.parse(elem));
},
medicsListLength() {
return this.filteringMedics?.length;
},
columnStyle() {
return this.medicsListLength > 4
? {
height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
width: "380px",
}
: {
height: `${this.timeCoil.length * this.pixelsPerHour + 60}px`,
width: `calc(100%/ ${this.medicsListLength})`,
};
},
backgroundWrapperWidth() {
return this.medicsListLength > 4
? {
width: `${380 * this.medicsListLength + 80}px`,
}
: {};
},
columnWrapperWidth() {
return this.medicsListLength > 4
? {
width: `${380 * this.medicsListLength}px`,
}
: {
width: "calc(100% - 80px)",
};
},
},
watch: {
selectedDates: {
immediate: true,
deep: true,
handler(newValue) {
this.isCurrent = newValue?.from.isSame(moment(), "day");
this.isShownIndicator = this.isCurrent;
if (this.timer) {
this.stopTimer();
this.timeCoilInitialization();
}
if (this.isCurrent) {
this.changeCurrentTime();
this.timeCoilInitialization();
this.startTimer();
}
},
},
},
mounted() {
this.changeCurrentTime();
this.timeCoilInitialization();
},
};
</script>
<style lang="sass" scoped>
@import "@/pages/newCalendar/sass/wrapperStyle.sass"
</style>

View File

@@ -0,0 +1,53 @@
import CalendarRecordCard from "@/pages/newCalendar/components/CalendarRecordCard.vue";
import { verifyTime } from "@/pages/newCalendar/utils/calendarFunctions.js";
import { mapActions, mapState } from "vuex";
export const columnMixin = {
props: {
dayEndTime: Number,
dayStartTime: Number,
},
emits: [],
components: { CalendarRecordCard },
data() {
return {
pixelsPerHour: 76,
};
},
computed: {
...mapState({
events: (state) => state.calendar.events || [],
}),
pixelsPerMinute() {
return this.pixelsPerHour / 60;
},
},
methods: {
...mapActions({
changeSelectedRecordId: "changeSelectedRecordId",
}),
eventCardPosition(startTime, endTime) {
let start = startTime
.slice(11, -4)
.split(":")
.map((elem) => parseInt(elem, 10));
let end = endTime.slice(11, -4);
let position =
(start[0] - this.dayStartTime) * this.pixelsPerHour +
start[1] * this.pixelsPerMinute +
4;
if (
parseInt(start[0], 10) < this.dayStartTime ||
verifyTime(end) > this.dayEndTime
) {
return {
top: "0px",
visibility: "hidden",
};
}
return {
top: `${position}px`,
};
},
},
};

View File

@@ -0,0 +1,26 @@
import BaseCalendar from "@/components/base/Calendar/BaseCalendar.vue";
import { mapState, mapActions } from "vuex";
import BaseInput from "@/components/base/BaseInput.vue";
export const headerMixin = {
components: { BaseInput, BaseCalendar },
data() {
return {
calendarVisibility: false,
};
},
computed: {
...mapState({
selectedDates: (state) => state.calendar.selectedDates,
}),
},
methods: {
...mapActions({
getEvents: "getEvents",
changeSelectedDates: "changeSelectedDates",
}),
saveDatesChange() {
this.calendarVisibility = false;
},
},
};

View File

@@ -0,0 +1,135 @@
import { mapState } from "vuex";
import * as moment from "moment/moment";
import CalendarBackground from "@/pages/newCalendar/components/CalendarBackground.vue";
import CalendarClockColumn from "@/pages/newCalendar/components/CalendarClockColumn.vue";
import {
convertTime,
verifyTime,
} from "@/pages/newCalendar/utils/calendarFunctions.js";
export const wrapperMixin = {
props: {
openSidebar: Boolean,
},
emits: [],
components: {
CalendarBackground,
CalendarClockColumn,
},
data() {
return {
currentTime: "",
isShownIndicator: true,
timeCoil: [],
timer: null,
pixelsPerHour: 76,
isCurrent: true,
};
},
computed: {
...mapState({
workingHours: (state) => state.calendar.workingHours,
}),
hours() {
return convertTime(this.currentTime, 0, -6);
},
minutes() {
return convertTime(this.currentTime, 3, -3);
},
hoursMinutes() {
return this.currentTime.slice(0, -3);
},
pixelsPerMinute() {
return this.pixelsPerHour / 60;
},
validateStartTime() {
return verifyTime(this.workingHours.start);
},
validateEndTime() {
return verifyTime(this.workingHours.end);
},
backgroundHeight() {
return (
(this.validateEndTime - this.validateStartTime) * this.pixelsPerHour
);
},
lineIndicatorLocation() {
return {
top: `${this.calculateIndicatorLocation()}px`,
};
},
circleIndicatorLocation() {
return {
top: `${this.calculateIndicatorLocation() + 58}px`,
};
},
},
methods: {
changeCurrentTime() {
this.currentTime = moment().format("HH:mm:ss");
},
changeTimeCoil() {
this.timeCoil = this.timeCoil.map((elem) => {
if (convertTime(elem, 0, -3) === this.hours) {
return this.hoursMinutes;
}
return elem.slice(0, -3) + ":00";
});
},
startTimer() {
if (
this.hours >= this.validateStartTime &&
this.hours < this.validateEndTime
) {
this.timer = setInterval(() => {
this.changeCurrentTime();
this.changeTimeCoil();
}, 5000);
}
},
stopTimer() {
clearInterval(this.timer);
this.timer = null;
},
calculateIndicatorLocation() {
let newTime = this.currentTime
.split(":")
.map((elem) => parseInt(elem, 10));
let result =
(newTime[0] - this.validateStartTime) * this.pixelsPerHour +
newTime[1] * this.pixelsPerMinute;
if (result > this.backgroundHeight || result < 0) {
this.isShownIndicator = false;
return 0;
}
return result;
},
timeCoilInitialization() {
this.timeCoil = [];
for (let i = this.validateStartTime; i < this.validateEndTime; i++) {
if (
i === this.hours &&
this.hours !== this.validateEndTime &&
this.isCurrent
) {
this.timeCoil.push(this.hoursMinutes);
} else this.timeCoil.push(`${i}:00`);
}
},
},
watch: {
currentTime() {
if (
this.hours === this.validateEndTime &&
this.minutes > 0 &&
this.timer
) {
this.stopTimer();
this.timeCoilInitialization();
}
},
},
beforeUnmount() {
this.stopTimer();
},
};

View File

@@ -0,0 +1,24 @@
.calendar-column-wrapper
border-right: 1px solid var(--border-light-grey-color)
&:last-child
border-right: none
.header
position: sticky
z-index: 5
background-color: var(--default-white)
.body
position: relative
z-index: 3
.color-black
color: var(--font-dark-blue-color)
.color-grey
color: var(--font-grey-color)
.footer
border-top: 1px solid var(--border-light-grey-color)
@media(min-height: 1090px)
border-bottom: 1px solid var(--border-light-grey-color)

View File

@@ -0,0 +1,41 @@
.calendar-header-wrapper
background-color: var(--default-white)
height: 72px
border-radius: 4px
z-index: 10
.text
color: var(--font-dark-blue-color)
.text-grey-color
color: var(--font-grey-color)
.text-primary
color: var(--font-dark-blue-color-0) !important
.bg-secondary
background: var(--bg-light-grey) !important
.q-btn--round
width: 32px !important
height: 32px !important
min-width: 32px !important
min-height: 32px !important
.q-btn-group :deep(.q-btn-item)
border-radius: 4px !important
.search :deep(.q-field__marginal)
height: auto !important
.search :deep(.q-field__prepend)
padding-right: 6px !important
.search-icon :deep(path)
fill: var(--font-grey-color)
.calendar-icon :deep(path)
fill: var(--font-dark-blue-color)
.border-toggle
border: 1px solid var(--gray-secondary)

View File

@@ -0,0 +1,44 @@
.schedule-body
overflow-x: auto
border-top-left-radius: 4px
border-top-right-radius: 4px
&::-webkit-scrollbar-track:horizontal
margin: 0 24px 0 24px
.background
background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%)
.time-coil-wrapper
position: sticky
z-index: 5
background-color: var(--default-white)
padding-top: 52px
.column-wrapper
height: 60px
position: relative
background-color: var(--default-white)
.footer
border-bottom-left-radius: 4px
border-bottom-right-radius: 4px
.border-bottom
border-bottom: 4px solid var(--bg-ligth-blue-color)
.records-count
border-right: 1px solid var(--border-light-grey-color)
&:last-child
border-right: none
.border-top
border-top: 1px solid var(--border-light-grey-color)
.time-circle-indicator
background-color: var(--bg-event-red-color)
z-index: 5
.time-line-indicator
border-top: 1px solid var(--bg-event-red-color)
z-index: 4
width: calc(100% - 80px)

View File

@@ -778,16 +778,16 @@ export const services = [
export const recordList = [ export const recordList = [
{ {
id: "c3df0a95-8093-41f1-9584-5b70ee05e71c", id: "asdf0a95-8093-41f1-9584-5b70ee05e71c",
start: "2023-07-05T10:00:00Z", start: "2023-09-18T10:00:00Z",
end: "2023-07-05T11:00:00Z", end: "2023-09-18T11:00:00Z",
employee: { employee: {
id: "464101e6-b4e6-46a4-8ef6-08ecb2921493", id: "464101e6-b4e6-46a4-8ef6-08ecb2921493",
last_name: "Каневский", last_name: "Каневский",
first_name: "Леонид", first_name: "Леонид",
patronymic: "Семенович", patronymic: "Семенович",
}, },
member: { person: {
id: "3e6e54e4-2706-47d3-8b54-b841ee8f0943", id: "3e6e54e4-2706-47d3-8b54-b841ee8f0943",
last_name: "Харитонова", last_name: "Харитонова",
first_name: "Ольга", first_name: "Ольга",
@@ -823,16 +823,16 @@ export const recordList = [
], ],
}, },
{ {
id: "ba931000-7140-4977-bd09-1ac212b8b8e5", id: "ss931000-7140-4977-bd09-1ac212b8b8e5",
start: "2023-07-06T15:00:00Z", start: "2023-09-18T15:00:00Z",
end: "2023-07-06T15:30:00Z", end: "2023-09-18T15:30:00Z",
employee: { employee: {
id: "464101e6-b4e6-46a4-8ef6-08ecb2921493", id: "464101e6-b4e6-46a4-8ef6-08ecb2921493",
last_name: "Каневский", last_name: "Каневский",
first_name: "Леонид", first_name: "Леонид",
patronymic: "Семенович", patronymic: "Семенович",
}, },
member: { person: {
id: "d340d344-4fc7-4fbe-9db8-b7562b70438d", id: "d340d344-4fc7-4fbe-9db8-b7562b70438d",
last_name: "Гаранова", last_name: "Гаранова",
first_name: "Наталья", first_name: "Наталья",
@@ -877,16 +877,16 @@ export const recordList = [
], ],
}, },
{ {
id: "4cd94bec-a0df-4a18-879d-f64cd6d7098e", id: "ccd94bec-a0df-4a18-879d-f64cd6d5698e",
start: "2023-07-03T13:00:00Z", start: "2023-09-18T13:00:00Z",
end: "2023-07-03T14:30:00Z", end: "2023-09-18T14:30:00Z",
employee: { employee: {
id: "464101e6-b4e6-46a4-8ef6-08ecb2921493", id: "111101e6-b4e6-46a4-8ef6-08ecb2921493",
last_name: "Каневский", last_name: "Гурцев",
first_name: "Леонид", first_name: "Семен",
patronymic: "Семенович", patronymic: "Семенович",
}, },
member: { person: {
id: "0b2d1db1-6aab-4e29-b857-fc7c9777280f", id: "0b2d1db1-6aab-4e29-b857-fc7c9777280f",
last_name: "Харитонова", last_name: "Харитонова",
first_name: "Ольга", first_name: "Ольга",
@@ -930,6 +930,105 @@ export const recordList = [
}, },
], ],
}, },
{
id: "vv931000-7140-4977-bd09-1ac233b8b8e5",
start: "2023-09-18T15:00:00Z",
end: "2023-09-18T15:30:00Z",
employee: {
id: "333101e6-b4e6-46a4-8ef6-08ecb2921493",
last_name: "Лебедев",
first_name: "Леонид",
patronymic: "Семенович",
},
person: {
id: "d340d344-4fc7-4fbe-9db8-b7562b70438d",
last_name: "Гаранова",
first_name: "Наталья",
patronymic: "Романовна",
birth_date: "1990-04-12",
photo: personImage,
contacts: [
{
value: "+7 (910) 4241313",
kind: "PHONE",
},
{
value: "Haritonich@mail.ru",
kind: "EMAIL",
},
],
},
status: "accepted",
medicalCard: {
status: "not_filled",
},
},
{
id: "rr931000-7140-4977-bd09-1ac233b8b8e5",
start: "2023-09-18T15:00:00Z",
end: "2023-09-18T15:30:00Z",
employee: {
id: "666101e6-b4e6-46a4-8ef6-08ecb7721493",
last_name: "Петров",
first_name: "Леонид",
patronymic: "Семенович",
},
person: {
id: "d340d344-4fc7-4fbe-9db8-b7562b70438d",
last_name: "Гаранова",
first_name: "Наталья",
patronymic: "Романовна",
birth_date: "1990-04-12",
photo: personImage,
contacts: [
{
value: "+7 (910) 4241313",
kind: "PHONE",
},
{
value: "Haritonich@mail.ru",
kind: "EMAIL",
},
],
},
status: "accepted",
medicalCard: {
status: "not_filled",
},
},
{
id: "ma931000-7140-4977-bd09-1ac233b8b8e5",
start: "2023-09-18T15:00:00Z",
end: "2023-09-18T15:30:00Z",
employee: {
id: "999101e6-b4e6-46a4-8ef6-22ecb2921493",
last_name: "Ленин",
first_name: "Леонид",
patronymic: "Семенович",
},
person: {
id: "d340d344-4fc7-4fbe-9db8-b7562b70438d",
last_name: "Гаранова",
first_name: "Наталья",
patronymic: "Романовна",
birth_date: "1990-04-12",
photo: personImage,
contacts: [
{
value: "+7 (910) 4241313",
kind: "PHONE",
},
{
value: "Haritonich@mail.ru",
kind: "EMAIL",
},
],
},
status: "accepted",
medicalCard: {
status: "not_filled",
},
},
]; ];
export const recordPreviewConfig = [ export const recordPreviewConfig = [

View File

@@ -3,8 +3,8 @@ export function convertTime(str, startIndex, endIndex) {
} }
export function trimName(lastName, firstName, patronymic) { export function trimName(lastName, firstName, patronymic) {
let checkedFirstName = firstName !== null ? firstName?.[0] + ". " : ""; let checkedFirstName = firstName ? firstName?.[0] + ". " : "";
let checkedPatronymic = patronymic !== null ? patronymic?.[0] + "." : ""; let checkedPatronymic = patronymic ? patronymic?.[0] + "." : "";
return `${lastName} ${checkedFirstName}${checkedPatronymic}`; return `${lastName} ${checkedFirstName}${checkedPatronymic}`;
} }
@@ -13,3 +13,7 @@ export function verifyTime(dayTime) {
let newTime = timeArray[1] >= 30 ? timeArray[0] + 1 : timeArray[0]; let newTime = timeArray[1] >= 30 ? timeArray[0] + 1 : timeArray[0];
return newTime; return newTime;
} }
export function capitalizeFirstChar(str) {
return str[0]?.toUpperCase() + str?.slice(1);
}

View File

@@ -148,7 +148,12 @@ export default {
return this.$store.state.medical.documents; return this.$store.state.medical.documents;
}, },
passportFields() { passportFields() {
let excludedFields = ["attachments", "id", "category"]; let excludedFields = [
"attachments",
"id",
"category",
"issued_by_org_code",
];
return Object.keys(this.docData.passport).filter( return Object.keys(this.docData.passport).filter(
(key) => !excludedFields.includes(key) (key) => !excludedFields.includes(key)
); );

View File

@@ -8,6 +8,7 @@ export default createStore({
imgUrl: "https://astra-dev.dopcore.com/api/store/", imgUrl: "https://astra-dev.dopcore.com/api/store/",
routingHistory: window.history, routingHistory: window.history,
userData: {}, userData: {},
calendarShape: "manager",
}, },
modules: { modules: {
medical, medical,

View File

@@ -194,8 +194,7 @@ const getters = {
series: document?.series || (isPolicy || isPassport ? "" : "000"), series: document?.series || (isPolicy || isPassport ? "" : "000"),
number: document?.number || "", number: document?.number || "",
issued_by: document?.issued_by || (isPassport ? "" : "000"), issued_by: document?.issued_by || (isPassport ? "" : "000"),
issued_by_org_code: issued_by_org_code: document?.issued_by_org_code || "",
document?.issued_by_org_code || (isPassport ? "000-000" : ""),
issued_at: document?.issued_at || "", issued_at: document?.issued_at || "",
attachments: document?.attachments?.length attachments: document?.attachments?.length
? { ? {