Работа над интерактивным обучением для дежурного и мед. сестры

This commit is contained in:
brusnitsyn
2026-07-15 16:53:38 +09:00
parent e48d38f3a2
commit d9cb1aca28
12 changed files with 377 additions and 209 deletions

22
package-lock.json generated
View File

@@ -1122,7 +1122,8 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@tailwindcss/language-server": {
"version": "0.14.29",
@@ -1937,8 +1938,7 @@
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-5.13.0.tgz",
"integrity": "sha512-PJuXT6zdiCbv0IkX5cqkKFVIIh+9v3kqP9zsOHEGpIWi7DfTgzvfOKc8icw6G3/ulR3V1alDDUtOVH0zWCWGEQ==",
"license": "SEE LICENSE IN LICENSE",
"peer": true
"license": "SEE LICENSE IN LICENSE"
},
"node_modules/async-validator": {
"version": "4.2.5",
@@ -2169,7 +2169,6 @@
"integrity": "sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@emotion/hash": "~0.8.0",
"csstype": "~3.0.5"
@@ -2245,7 +2244,6 @@
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"license": "ISC",
"peer": true,
"engines": {
"node": ">=12"
}
@@ -2299,7 +2297,6 @@
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
"license": "MIT",
"peer": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
@@ -2320,6 +2317,7 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"peer": true,
"dependencies": {
"ms": "^2.1.3"
},
@@ -2394,6 +2392,7 @@
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.5.tgz",
"integrity": "sha512-QCwxUDULPlXv8F6tqMMKx5dNkTe6OaBYRMPYeXKBlyOoKvAmE0ac6pW7fFhSscJ/5SI7666/U/B+MElbsrJlIg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.4.1",
@@ -2407,6 +2406,7 @@
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.0.0"
}
@@ -3183,7 +3183,8 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/muggle-string": {
"version": "0.4.1",
@@ -3301,7 +3302,6 @@
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz",
"integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/devtools-api": "^7.7.7"
},
@@ -3387,7 +3387,6 @@
"resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-8.5.0.tgz",
"integrity": "sha512-V7uzGi9bqOOOyM/6IkJdpFyjGZj7llz1v0oWnYkZKcYLvbz6VcHVLmzKqkvegjuMumpfIEKGLmWHwFb39XFCpw==",
"license": "MIT",
"peer": true,
"dependencies": {
"tweetnacl": "^1.0.3"
}
@@ -3628,6 +3627,7 @@
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz",
"integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.4.1"
@@ -3840,7 +3840,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -4198,7 +4197,6 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz",
"integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-sfc": "3.5.26",
@@ -4311,6 +4309,7 @@
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
"integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.0.0"
},
@@ -4331,6 +4330,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
"peer": true,
"engines": {
"node": ">=0.4.0"
}

View File

@@ -135,7 +135,11 @@ function delay(ms) {
<template>
<Teleport to="body">
<TourOverlay
v-if="onboarding.active && target"
v-if="onboarding.active &&
target &&
onboarding.currentStep?.highlight !== false &&
rect"
:allow-interaction="onboarding.currentStep?.allowInteraction ?? true"
:rect="rect"
:padding="onboarding.currentStep.padding"
/>
@@ -148,7 +152,7 @@ function delay(ms) {
:visible="onboarding.active"
:is-first="onboarding.stepIndex === 0"
:is-last="onboarding.stepIndex === onboarding.tour.steps.length - 1"
:is-last="onboarding.stepIndex === onboarding.tour?.steps.length - 1"
@next="onboarding.next"
@previous="onboarding.previous"

View File

@@ -5,16 +5,50 @@ const props = defineProps({
rect: {
type: Object,
required: true
},
allowInteraction: {
type: Boolean,
default: true
}
})
const style = computed(() => {
const r = props.rect
const overlayStyle = computed(() => {
if (!props.rect) return null;
const { top, left, width, height } = props.rect
return {
"--top": `${r.top}px`,
"--left": `${r.left}px`,
"--width": `${r.width}px`,
"--height": `${r.height}px`
top: {
top: 0,
left: 0,
width: '100vw',
height: `${top}px`
},
left: {
top: `${top}px`,
left: 0,
width: `${left}px`,
height: `${height}px`
},
right: {
top: `${top}px`,
left: `${left+width}px`,
width: `calc(100vw - ${left+width}px)`,
height: `${height}px`
},
bottom: {
top: `${top+height}px`,
left: 0,
width: "100vw",
height: `calc(100vh - ${top+height}px)`
},
highlight: {
top: `${top}px`,
left: `${left}px`,
width: `${width}px`,
height: `${height}px`
},
}
})
</script>
@@ -24,10 +58,32 @@ const style = computed(() => {
<Teleport to="body">
<Transition name="tour-fade">
<div v-if="rect && overlayStyle">
<div
class="tour-overlay"
:style="style"
class="tour-mask"
:style="overlayStyle.top"
/>
<div
class="tour-mask"
:style="overlayStyle.left"
/>
<div
class="tour-mask"
:style="overlayStyle.right"
/>
<div
class="tour-mask"
:style="overlayStyle.bottom"
/>
<div
class="tour-highlight"
:style="overlayStyle.highlight"
/>
<div
v-if="!allowInteraction"
class="tour-blocker"
/>
</div>
</Transition>
</Teleport>
@@ -35,28 +91,27 @@ const style = computed(() => {
<style scoped>
.tour-mask {
position: fixed;
z-index: 9998;
background: rgba(0,0,0,.55);
pointer-events: auto;
}
.tour-overlay {
.tour-blocker {
position: fixed;
inset: 0;
z-index: 9998;
pointer-events: none;
background: rgba(0,0,0,.55);
background: transparent;
pointer-events: auto;
}
/*
вырезаем окно
*/
mask:
linear-gradient(#000 0 0),
linear-gradient(#000 0 0);
mask-size:
100% 100%,
var(--width) var(--height);
mask-position:
0 0,
var(--left) var(--top);
mask-repeat:no-repeat;
mask-composite: exclude;
.tour-highlight {
position: fixed;
z-index: 9998;
border: 2px solid white;
border-radius: 8px;
pointer-events: none;
}
.tour-fade-enter-active,

View File

@@ -23,6 +23,10 @@ const props = defineProps({
type: [HTMLElement, String, Object],
default: null
},
disabledControllers: {
type: Boolean,
default: false
}
})
const emit = defineEmits([

View File

@@ -19,8 +19,8 @@ const onboarding = useOnboardingStore()
const userStore = useAuthStore()
const modalStore = useModalStore()
if (userStore.user.role.slug === 'dej')
onboarding.start("welcomeDuty")
// if (userStore.user.role.slug === 'nurse')
// onboarding.start("welcomeNurse")
const authStore = useAuthStore()
const themeVars = useThemeVars()
@@ -67,11 +67,12 @@ const isLockReportButton = computed(() => {
return getHours(serverTime.value) < 6 || getHours(serverTime.value) >= 7
})
const showSelectUserModal = ref(false)
const showSelectDutyUserModal = ref(false)
const showSelectNurseUserModal = ref(false)
const openReport = (path) => {
modalStore.showSelectDutyUserModal = true
showSelectDutyUserModal.value = true
onboarding.emit('selectUser:opened')
}
const openNurseReport = () => {
@@ -80,7 +81,8 @@ const openNurseReport = () => {
// } else {
// router.visit('/nurse/report')
// }
modalStore.showSelectNurseUserModal = true
showSelectNurseUserModal.value = true
onboarding.emit('selectUser:opened')
}
const cardColor = computed(() => themeVars.value.cardColor)
@@ -90,7 +92,7 @@ const dividerColor = computed(() => themeVars.value.dividerColor)
<template>
<AppLayout>
<div class="flex flex-col justify-center items-center" style="min-height: calc(100vh - 48px);">
<NFlex vertical :size="10" class="max-w-2xl w-full" style="padding: 0 16px 24px;">
<NFlex id="launcher" vertical :size="10" class="max-w-2xl w-full" style="padding: 0 16px 0 16px;">
<!-- Профиль -->
<NEl id="user-panel" class="profile-card rounded-2xl" style="padding: 18px 22px;">
@@ -192,9 +194,9 @@ const dividerColor = computed(() => themeVars.value.dividerColor)
</NFlex>
</div>
<SelectUserModal v-model:show="modalStore.showSelectDutyUserModal" :only-user-department="false" />
<SelectUserModal v-model:show="showSelectDutyUserModal" :only-user-department="false" />
<SelectUserModal
v-model:show="modalStore.showSelectNurseUserModal"
v-model:show="showSelectNurseUserModal"
target-path="/nurse/report"
submit-label="Перейти к журналу пациентов"
:with-exists-check="false"

View File

@@ -7,8 +7,11 @@ import {format} from "date-fns";
import {router, usePage} from "@inertiajs/vue3";
import AppPanel from "../../../Components/AppPanel.vue"
import AppSearchAddress from '../../../Components/AppSearchAddress.vue';
import {useOnboardingStore} from "../../../Stores/onboarding.js";
const show = defineModel('show', { default: false })
const onboarding = useOnboardingStore()
const currentStep = ref(1)
const currentStatus = ref('process')
const isFinallyStep = computed(() => currentStep.value === 2)
@@ -224,10 +227,16 @@ const onAfterLeave = () => {
currentStep.value = 1
searchOptions.value = []
}
const onUpdatePatientSource = (v) => {
if (v === 'mis') onboarding.emit('newPatientModal:patientTypeSelected')
if (v === 'special') onboarding.emit('newPatientModal:patientTypeSelected')
}
</script>
<template>
<NModal v-model:show="show"
id="create-new-patient-modal"
segmented
preset="card"
title="Добавление пациента"
@@ -243,7 +252,7 @@ const onAfterLeave = () => {
</NSteps>
<NTabs tab-class="hidden!" :value="currentStep">
<NTabPane :name="1" class="mt-4">
<NRadioGroup class="w-full space-y-2!" v-model:value="form.patient_source">
<NRadioGroup class="w-full space-y-2!" v-model:value="form.patient_source" @update:value="v => onUpdatePatientSource(v)">
<AppRadio title="МИС" value="mis" description="Выберите, если пациента можно найти в системе МИС" />
<AppRadio title="Спец. контингент" value="special" description="Выберите, если пациента нет в системе МИС" />
</NRadioGroup>

View File

@@ -17,6 +17,7 @@ import ActionsColumnDataTable from "../Components/ActionsColumnDataTable.vue";
import {useAppDialog} from "../../../Composables/useAppDialog.js";
import {format} from "date-fns";
import DatePickerQuery from "../../../Components/DatePickerQuery.vue";
import {useOnboardingStore} from "../../../Stores/onboarding.js";
const props = defineProps({
patients: {
@@ -53,6 +54,7 @@ const props = defineProps({
const canEdit = computed(() => props.canSaveReport || props.canEditPastReport)
const onboarding = useOnboardingStore()
const showAddMedicalHistoryModal = shallowRef(false)
const showEditMedicalHistoryModal = shallowRef(false)
const editHistoryId = ref(null)
@@ -210,18 +212,23 @@ const submit = () => {
const reportCreator = computed(() => {
if (props.latestReport === null) return ''
if (props.latestReport.doctor.LPUDoctorID === 0) return 'Отчет создан системой'
if (props.latestReport.doctor?.LPUDoctorID === 0) return 'Отчет создан системой'
else return `Отчет создан: ${props.latestReport.doctor.FAM_V} ${props.latestReport.doctor.IM_V} ${props.latestReport.doctor.OT_V}`
})
const reportCreatorType = computed(() => {
if (props.latestReport === null) return 'warning'
if (props.latestReport.doctor.LPUDoctorID === 0) return 'error'
if (props.latestReport.doctor?.LPUDoctorID === 0) return 'error'
else return 'warning'
})
const formattedLabel = (word, count) => {
return `${word} (${count})`
}
const onShowCreatePatientModal = () => {
showAddMedicalHistoryModal.value = true
onboarding.emit('createNewPatientModal:opened')
}
</script>
<template>
@@ -237,19 +244,19 @@ const formattedLabel = (word, count) => {
{{ reportCreator }}
</NTag>
</NSpace>
<DatePickerQuery :date="dates" :is-head-or-admin="true" class="text-lg!" hint />
<DatePickerQuery id="date-selector" :date="dates" :is-head-or-admin="true" class="text-lg!" hint />
</NFlex>
</AppPanel>
<AppPanel header="Журнал пациентов" header-include-body>
<template v-if="canEdit" #header-extra>
<NButton secondary :loading="loading" @click="showAddMedicalHistoryModal = true">
<NButton id="add-new-patient" secondary :loading="loading" @click="onShowCreatePatientModal">
<template #icon>
<TbCirclePlus />
</template>
Добавить пациента
</NButton>
</template>
<NTabs type="line">
<NTabs id="view-tabs" type="line">
<NTabPane name="all"
:tab="formattedLabel('В отделении', patientsByGroup.in_department.length)"
>

View File

@@ -27,6 +27,8 @@ const props = defineProps({
})
const reportStore = useReportStore()
const onboarding = useOnboardingStore()
const formRef = ref()
const rawUsers = ref([])
@@ -153,10 +155,15 @@ const onSubmit = (e) => {
formRef.value?.validate((errors) => {
if (!errors) {
if (reportExists.value) return
router.visit(props.targetPath, {
data: {
userId: reportStore.reportInfo.userId,
departmentId: reportStore.reportInfo.departmentId
},
onSuccess: () => {
onboarding.emit('navigate:report')
show.value = false
}
})
}
@@ -177,22 +184,11 @@ const onChangeDepartment = (departmentId) => {
usersLoaded.value = false
fetchUsers(departmentId)
}
const onboarding = useOnboardingStore()
const onAfterEnter = async () => {
// Если онбординг активен и текущий шаг имеет opensModal, переходим к следующему
if (!onboarding.isActive) return
await nextTick()
requestAnimationFrame(() => {
onboarding.setStep(onboarding.activeStepIndex + 1)
})
}
</script>
<template>
<NModal v-model:show="show"
id="modal-select-user"
preset="card"
class="max-w-[420px]"
:mask-closable="false"

View File

@@ -271,10 +271,10 @@ watch(() => props, (newProps) => {
{{ reportCreator }}
</NTag>
</NSpace>
<DatePickerQuery :date="dates" :is-head-or-admin="true" class="text-lg!" />
<DatePickerQuery id="date-selector" :date="dates" :is-head-or-admin="true" class="text-lg!" />
</NFlex>
<NDivider dashed class="my-4! mt-3!" />
<NRow class="grow space-x-2 h-[82.78px]">
<NRow id="statistic-widgets" class="grow space-x-2 h-[82.78px]">
<NCol :span="3">
<HeaderWidget label="Коек"
:counter="stats.duty.beds" />
@@ -305,7 +305,7 @@ watch(() => props, (newProps) => {
</NRow>
</AppPanel>
<div class="grid grid-cols-[1fr_auto] gap-x-2">
<AppPanel>
<AppPanel id="input-widgets">
<NFlex align="center" :wrap="false">
<NFormItem label="Поступило" :show-feedback="false">
<NInputNumber :disabled="!canSaveReport" :min="0" v-model:value="reportForm.recipient" />
@@ -335,7 +335,7 @@ watch(() => props, (newProps) => {
</NFlex>
</div>
<AppPanel>
<NTabs type="segment">
<NTabs id="view-tabs" type="segment">
<NTabPane name="mis" tab="МИС" display-directive="show">
<DutyPatientsPane :patients="patientCollection" :nurse-patients="nursePatientCollection" @create-observable="addObservablePatient" @remove-observable="removeObservablePatient" />
</NTabPane>

View File

@@ -1,5 +1,7 @@
import welcomeDuty from "./welcomeDuty"
import welcomeNurse from "./welcomeNurse"
export default {
welcomeDuty
welcomeDuty,
welcomeNurse,
}

View File

@@ -3,83 +3,78 @@ export default {
name: 'Знакомство с Метрикой',
steps: [
{
id: 'wellcome',
target: '#user-panel',
route: 'start', // главная страница
id: 'step-0',
target: '#launcher',
route: 'start',
title: '👋 Добро пожаловать!',
description: 'Это ваша панель управления. Сейчас мы покажем вам основные возможности.',
popper: { placement: 'bottom-start' }, // опционально: позиция тултипа
on: {
afterStep: () => {
const modalStore = useModalStore()
modalStore.showSelectDutyUserModal = false
},
beforeStep: () => {
const modalStore = useModalStore()
modalStore.showSelectDutyUserModal = false
},
}
description: 'Это ваша рабочая область. Сейчас мы покажем вам основные возможности.',
highlight: true,
scroll: false,
allowInteraction: false,
},
{
attachTo: { element: '#new-report-duty' },
route: 'start', // переходим на страницу отчётов
content: {
id: 'step-1',
target: '#new-report-duty',
route: 'start',
title: '✏️ Создать отчёт',
description: 'Нажмите эту кнопку, чтобы начать создание нового отчёта.'
},
on: {
afterStep: () => {
const modalStore = useModalStore()
const onboarding = useOnboardingStore()
if (onboarding.activeStepIndex === 2) modalStore.showSelectDutyUserModal = true
if (onboarding.activeStepIndex < 2) modalStore.showSelectDutyUserModal = false
},
beforeStep: () => {
const modalStore = useModalStore()
const onboarding = useOnboardingStore()
if (onboarding.activeStepIndex < 2) modalStore.showSelectDutyUserModal = false
},
},
description: 'Нажмите эту кнопку, чтобы начать создание нового отчёта.',
manual: true,
highlight: true,
scroll: false,
allowInteraction: true,
nextEvent: 'selectUser:opened'
},
{
attachTo: { element: '#modal-select-user-department' },
id: 'step-2',
target: '#modal-select-user',
route: 'start',
content: { title: 'Выберите отделение', description: 'Можете использовать список, либо ввести ФИО для поиска' },
insideModal: true, // флаг, что этот шаг внутри модалки
options: {
disableInteraction: false
}
title: 'Выберите отделение и ответственного',
description: 'Можете использовать список, либо ввести для поиска',
manual: true,
highlight: true,
scroll: true,
allowInteraction: true,
nextEvent: 'navigate:report'
},
{
attachTo: { element: '#modal-select-user-doctor' },
route: 'start',
content: { title: 'Введите ответственного', description: 'Можете использовать список, либо ввести ФИО для поиска' },
insideModal: true, // флаг, что этот шаг внутри модалки
id: 'step-3',
target: '#date-selector',
route: 'report',
title: 'Календарь',
description: 'Здесь Вы можете просмотреть предыдущие отчеты, путем выбора даты в календаре.',
highlight: true,
scroll: true,
allowInteraction: false,
},
{
attachTo: { element: '#modal-select-user-submit' },
route: 'start',
content: { title: 'Подтвердите ввод' },
insideModal: true, // флаг, что этот шаг внутри модалки
manual: true
id: 'step-4',
target: '#statistic-widgets',
route: 'report',
title: 'Основная статистика',
description: 'Здесь отображается информация из МИС и журнала пациентов',
highlight: true,
scroll: true,
allowInteraction: false,
},
{
attachTo: { element: '#report-name-input' },
route: 'report', // страница создания отчёта
content: {
title: '📝 Название отчёта',
description: 'Введите название, чтобы легко находить отчёт позже.'
}
id: 'step-5',
target: '#input-widgets',
route: 'report',
title: 'Поля ввода',
description: 'Поля заполняются данными из МИС автоматически. Но вы можете их изменить.',
highlight: true,
scroll: true,
allowInteraction: false,
},
{
attachTo: { element: '#save-report-btn' },
route: 'reports.create',
content: {
title: '💾 Сохранить',
description: 'После заполнения всех полей нажмите "Сохранить", чтобы завершить.'
}
}
id: 'step-6',
target: '#view-tabs',
route: 'report',
title: 'Представления',
description: 'Вы можете переключать представления. Вам доступны МИС и Журнал пациентов (заполняет старшая медицинская сестра отделения)',
highlight: true,
scroll: true,
allowInteraction: false,
},
]
}

View File

@@ -0,0 +1,94 @@
export default {
id: 'welcome-nurse',
name: 'Знакомство с Метрикой',
steps: [
{
id: 'step-0',
target: '#launcher',
route: 'start',
title: '👋 Добро пожаловать!',
description: 'Это ваша рабочая область. Сейчас мы покажем вам основные возможности.',
highlight: true,
scroll: false,
allowInteraction: false,
},
{
id: 'step-1',
target: '#new-report-nurse',
route: 'start',
title: '✏️ Создать отчёт',
description: 'Нажмите эту кнопку, чтобы начать создание нового отчёта.',
manual: true,
highlight: true,
scroll: false,
allowInteraction: true,
nextEvent: 'selectUser:opened'
},
{
id: 'step-2',
target: '#modal-select-user',
route: 'start',
title: 'Выберите отделение и ответственного',
description: 'Можете использовать список, либо ввести для поиска',
manual: true,
highlight: true,
scroll: true,
allowInteraction: true,
nextEvent: 'navigate:report'
},
{
id: 'step-3',
target: '#date-selector',
route: 'nurse.report',
title: 'Календарь',
description: 'Здесь Вы можете просмотреть предыдущие отчеты, путем выбора даты в календаре.',
highlight: true,
scroll: true,
allowInteraction: false,
},
{
id: 'step-4',
target: '#view-tabs',
route: 'nurse.report',
title: 'Представления',
description: 'Вы можете переключать представления. Для удобства пациенты разделены на категории.',
highlight: true,
scroll: true,
allowInteraction: false,
},
{
id: 'step-5',
target: '#add-new-patient',
route: 'nurse.report',
title: 'Добавление пациента',
description: 'Нажмите эту кнопку, чтобы добавить пациента.',
manual: true,
highlight: true,
scroll: true,
allowInteraction: true,
nextEvent: 'createNewPatientModal:opened'
},
{
id: 'step-6',
target: '#create-new-patient-modal',
route: 'nurse.report',
title: 'Форма создания',
description: 'Для начала вам нужно выбрать тип пациента. Если пациент есть в МИС, то выберите МИС. Иначе Спец. контингент',
manual: true,
highlight: true,
scroll: true,
allowInteraction: true,
nextEvent: 'newPatientModal:patientTypeSelected'
},
{
id: 'step-7',
target: '#create-new-patient-modal',
route: 'nurse.report',
title: 'Форма создания',
description: 'Заполните все необходимые поля, и нажмите кнопку Добавить',
highlight: true,
scroll: true,
allowInteraction: false,
},
]
}