294 lines
15 KiB
Vue
294 lines
15 KiB
Vue
<script setup lang="ts">
|
||
import { Head, Link } from '@inertiajs/vue3';
|
||
import MedicalReportController from '@/actions/App/Http/Controllers/MedicalReportController';
|
||
import Heading from '@/components/Heading.vue';
|
||
import type {
|
||
MedicalReport,
|
||
MedicalReportEconomistAnalysis,
|
||
MedicalReportEconomistIssues,
|
||
MedicalReportEconomistSummary,
|
||
} from '@/types';
|
||
|
||
type Props = {
|
||
report: MedicalReport;
|
||
summarySheet?: MedicalReportEconomistSummary | null;
|
||
analysisSheet?: MedicalReportEconomistAnalysis | null;
|
||
analysisIssues?: MedicalReportEconomistIssues | null;
|
||
};
|
||
|
||
defineProps<Props>();
|
||
</script>
|
||
|
||
<template>
|
||
<Head :title="`${report.name} - Экономисты`" />
|
||
|
||
<div class="flex flex-col gap-6 p-4 md:p-6">
|
||
<section
|
||
class="rounded-3xl border border-slate-200 bg-linear-to-br from-white via-slate-50 to-amber-50 p-6 shadow-sm"
|
||
>
|
||
<div class="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
||
<div class="space-y-3">
|
||
<div class="inline-flex w-fit rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold tracking-[0.18em] text-amber-700 uppercase">
|
||
Страница экономистов
|
||
</div>
|
||
<Heading
|
||
title="Свод по первой таблице Excel"
|
||
description="Отделения вводят только свои показатели, а здесь собирается первая сводная таблица для экономистов."
|
||
/>
|
||
</div>
|
||
|
||
<div class="flex flex-wrap gap-2">
|
||
<Link
|
||
:href="MedicalReportController.show({ medicalReport: report.id })"
|
||
class="rounded-full border border-slate-200 bg-white px-4 py-2 text-sm text-slate-700 transition-colors hover:border-slate-300"
|
||
>
|
||
Ввод отделений
|
||
</Link>
|
||
<Link
|
||
:href="MedicalReportController.builder({ medicalReport: report.id })"
|
||
class="rounded-full border border-slate-200 bg-white px-4 py-2 text-sm text-slate-700 transition-colors hover:border-slate-300"
|
||
>
|
||
Конструктор форм
|
||
</Link>
|
||
<div class="rounded-full border border-slate-950 bg-slate-950 px-4 py-2 text-sm text-white">
|
||
Свод экономистов
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="rounded-3xl border border-slate-200 bg-white p-5 shadow-sm">
|
||
<div
|
||
v-if="analysisIssues && analysisIssues.total_count > 0"
|
||
class="mb-8 rounded-2xl border border-amber-200 bg-amber-50 p-5 text-sm text-amber-950"
|
||
>
|
||
<div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
|
||
<div>
|
||
<div class="text-xs uppercase tracking-[0.16em] text-amber-700">
|
||
Требует настройки
|
||
</div>
|
||
<div class="mt-2 text-lg font-semibold">
|
||
Есть неполные связи для свода экономистов
|
||
</div>
|
||
<div class="mt-1 text-amber-900/80">
|
||
Не все сокращения и экспортные показатели привязаны к строкам и колонкам анализа.
|
||
</div>
|
||
</div>
|
||
<div class="rounded-2xl border border-amber-300 bg-white px-4 py-3 text-center">
|
||
<div class="text-xs uppercase tracking-[0.16em] text-amber-700">
|
||
Всего проблем
|
||
</div>
|
||
<div class="mt-1 text-2xl font-semibold">
|
||
{{ analysisIssues.total_count }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
v-if="analysisIssues.unmapped_departments.length > 0"
|
||
class="mt-5 overflow-x-auto rounded-2xl border border-amber-200 bg-white"
|
||
>
|
||
<table class="min-w-full text-sm">
|
||
<thead class="bg-amber-100/60 text-left text-amber-900">
|
||
<tr>
|
||
<th class="px-4 py-3 font-semibold">Отчетчик</th>
|
||
<th class="px-4 py-3 font-semibold">Секция</th>
|
||
<th class="px-4 py-3 font-semibold">Источник</th>
|
||
<th class="px-4 py-3 font-semibold">Причина</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr
|
||
v-for="issue in analysisIssues.unmapped_departments"
|
||
:key="`${issue.department}-${issue.section}-${issue.source_department}`"
|
||
class="border-t border-amber-100"
|
||
>
|
||
<td class="px-4 py-3">{{ issue.department }}</td>
|
||
<td class="px-4 py-3">{{ issue.section }}</td>
|
||
<td class="px-4 py-3">{{ issue.source_department }}</td>
|
||
<td class="px-4 py-3">{{ issue.reason }}</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div
|
||
v-if="analysisIssues.unmapped_metrics.length > 0"
|
||
class="mt-5 overflow-x-auto rounded-2xl border border-amber-200 bg-white"
|
||
>
|
||
<table class="min-w-full text-sm">
|
||
<thead class="bg-amber-100/60 text-left text-amber-900">
|
||
<tr>
|
||
<th class="px-4 py-3 font-semibold">Отчетчик</th>
|
||
<th class="px-4 py-3 font-semibold">Секция</th>
|
||
<th class="px-4 py-3 font-semibold">Метрика</th>
|
||
<th class="px-4 py-3 font-semibold">Причина</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr
|
||
v-for="issue in analysisIssues.unmapped_metrics"
|
||
:key="`${issue.department}-${issue.section}-${issue.metric}`"
|
||
class="border-t border-amber-100"
|
||
>
|
||
<td class="px-4 py-3">{{ issue.department }}</td>
|
||
<td class="px-4 py-3">{{ issue.section }}</td>
|
||
<td class="px-4 py-3">{{ issue.metric }}</td>
|
||
<td class="px-4 py-3">{{ issue.reason }}</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="analysisSheet" class="mb-8 border-b border-slate-100 pb-8">
|
||
<div class="mb-6 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
||
<div>
|
||
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
|
||
Матрица
|
||
</div>
|
||
<h1 class="mt-2 text-2xl font-semibold text-slate-950">
|
||
{{ analysisSheet.name }}
|
||
</h1>
|
||
</div>
|
||
|
||
<div class="grid gap-3 sm:grid-cols-2">
|
||
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
|
||
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
|
||
Подразделений с данными
|
||
</div>
|
||
<div class="mt-2 text-xl font-semibold text-slate-900">
|
||
{{ analysisSheet.filled_units }}
|
||
</div>
|
||
</div>
|
||
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
|
||
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
|
||
Заполненных ячеек
|
||
</div>
|
||
<div class="mt-2 text-xl font-semibold text-slate-900">
|
||
{{ analysisSheet.filled_cells }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="overflow-x-auto">
|
||
<table class="min-w-full border-separate border-spacing-0 text-sm">
|
||
<thead>
|
||
<tr>
|
||
<th class="sticky left-0 z-10 border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900">
|
||
Подразделение
|
||
</th>
|
||
<th
|
||
v-for="column in analysisSheet.columns"
|
||
:key="column.key"
|
||
class="border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900"
|
||
>
|
||
<div>{{ column.coordinate }}</div>
|
||
<div class="text-xs font-normal text-slate-500">
|
||
{{ column.name }}
|
||
</div>
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr
|
||
v-for="row in analysisSheet.rows"
|
||
:key="row.unit_name"
|
||
class="odd:bg-slate-50/70"
|
||
>
|
||
<td class="sticky left-0 z-10 border-b border-slate-100 bg-inherit px-4 py-3 font-medium text-slate-900">
|
||
<div class="text-[11px] uppercase tracking-[0.16em] text-slate-400">
|
||
{{ row.profile_name ?? 'Без профиля' }}
|
||
</div>
|
||
<div>{{ row.unit_name }}</div>
|
||
</td>
|
||
<td
|
||
v-for="value in row.values"
|
||
:key="`${row.unit_name}-${value.key}`"
|
||
class="border-b border-slate-100 px-4 py-3 text-slate-700"
|
||
>
|
||
{{ value.value || '0' }}
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-if="!summarySheet" class="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">
|
||
В шаблоне не найдена первая таблица для формирования свода.
|
||
</div>
|
||
|
||
<template v-else>
|
||
<div class="mb-6 flex flex-col gap-4 border-b border-slate-100 pb-5 md:flex-row md:items-end md:justify-between">
|
||
<div>
|
||
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
|
||
Таблица
|
||
</div>
|
||
<h1 class="mt-2 text-2xl font-semibold text-slate-950">
|
||
{{ summarySheet.name }}
|
||
</h1>
|
||
</div>
|
||
|
||
<div class="grid gap-3 sm:grid-cols-2">
|
||
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
|
||
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
|
||
Отделений с данными
|
||
</div>
|
||
<div class="mt-2 text-xl font-semibold text-slate-900">
|
||
{{ summarySheet.filled_departments }}
|
||
</div>
|
||
</div>
|
||
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
|
||
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
|
||
Заполненных ячеек
|
||
</div>
|
||
<div class="mt-2 text-xl font-semibold text-slate-900">
|
||
{{ summarySheet.filled_cells }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="overflow-x-auto">
|
||
<table class="min-w-full border-separate border-spacing-0 text-sm">
|
||
<thead>
|
||
<tr>
|
||
<th class="sticky left-0 z-10 border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900">
|
||
Отделение
|
||
</th>
|
||
<th
|
||
v-for="column in summarySheet.columns"
|
||
:key="column.coordinate"
|
||
class="border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900"
|
||
>
|
||
{{ column.name }}
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr
|
||
v-for="row in summarySheet.rows"
|
||
:key="row.department"
|
||
class="odd:bg-slate-50/70"
|
||
>
|
||
<td class="sticky left-0 z-10 border-b border-slate-100 bg-inherit px-4 py-3 font-medium text-slate-900">
|
||
{{ row.department }}
|
||
</td>
|
||
<td
|
||
v-for="value in row.values"
|
||
:key="`${row.department}-${value.name}`"
|
||
class="border-b border-slate-100 px-4 py-3 text-slate-700"
|
||
>
|
||
{{ value.value || '0' }}
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</template>
|
||
</section>
|
||
</div>
|
||
</template>
|