refactor: AppointmentView: Переименован hook и убран console.log

This commit is contained in:
Андрей Дувакин 2025-06-04 19:24:09 +05:00
parent 4dca2314cc
commit a416b6cc95
3 changed files with 40 additions and 32 deletions

View File

@ -1,5 +1,5 @@
import { createApi } from "@reduxjs/toolkit/query/react";
import { baseQueryWithAuth } from "./baseQuery.js";
import {createApi} from "@reduxjs/toolkit/query/react";
import {baseQueryWithAuth} from "./baseQuery.js";
export const appointmentFilesApi = createApi({
reducerPath: 'appointmentFilesApi',
@ -8,7 +8,6 @@ export const appointmentFilesApi = createApi({
endpoints: (builder) => ({
getAppointmentFiles: builder.query({
query: (appointmentId) => {
console.log(`Fetching files for appointment ID: ${appointmentId}`);
return `/appointment_files/${appointmentId}/`;
},
providesTags: ['AppointmentFile'],
@ -22,7 +21,7 @@ export const appointmentFilesApi = createApi({
invalidatesTags: ['AppointmentFile'],
}),
uploadAppointmentFile: builder.mutation({
query: ({ appointmentId, file }) => {
query: ({appointmentId, file}) => {
if (!(file instanceof File)) {
throw new Error('Invalid file object');
}

View File

@ -1,5 +1,5 @@
import { Button, Modal, Row, Typography, Spin } from "antd";
import useAppointmentViewUI from "./useAppointmentViewUI.js";
import {Button, Modal, Row, Typography, Spin, Splitter, Divider} from "antd";
import useAppointmentView from "./useAppointmentView.js";
const AppointmentViewModal = () => {
const {
@ -20,7 +20,7 @@ const AppointmentViewModal = () => {
isFilesLoading,
downloadingFiles,
downloadFile,
} = useAppointmentViewUI();
} = useAppointmentView();
if (!selectedAppointment) {
return null;
@ -67,26 +67,27 @@ const AppointmentViewModal = () => {
<b>{labels.results}</b>
</p>
<div
dangerouslySetInnerHTML={{ __html: getResults(selectedAppointment.results) }}
dangerouslySetInnerHTML={{__html: getResults(selectedAppointment.results)}}
/>
<p>
<b>{labels.files}</b>
</p>
{isFilesLoading ? (
<Spin />
<Spin/>
) : files.length > 0 ? (
files.map((file) => (
<div key={file.id} style={{ marginBottom: 8 }}>
<Row key={file.id} align="middle" justify="space-between">
<span>{file.file_title || labels.notSpecified}</span>
<Button
style={{ marginLeft: 8 }}
onClick={() => downloadFile(file.id, file.file_title)}
loading={downloadingFiles[file.id] || false}
disabled={downloadingFiles[file.id] || false}
type={"dashed"}
>
{downloadingFiles[file.id] ? labels.downloading : labels.download}
</Button>
</div>
<Divider/>
</Row>
))
) : (
<p>{labels.noFiles}</p>

View File

@ -1,25 +1,26 @@
import { useDispatch, useSelector } from "react-redux";
import { setSelectedAppointment } from "../../../Redux/Slices/appointmentsSlice.js";
import {useDispatch, useSelector} from "react-redux";
import {setSelectedAppointment} from "../../../Redux/Slices/appointmentsSlice.js";
import dayjs from "dayjs";
import { useState } from "react";
import {useState} from "react";
import {useGetAppointmentFilesQuery} from "../../../Api/appointmentFilesApi.js";
import {baseQueryWithAuth} from "../../../Api/baseQuery.js";
import {notification} from "antd";
const useAppointmentViewUI = () => {
const useAppointmentView = () => {
const dispatch = useDispatch();
const { selectedAppointment } = useSelector((state) => state.appointmentsUI);
const {selectedAppointment} = useSelector((state) => state.appointmentsUI);
const { data: files = [], isLoading: isFilesLoading } = useGetAppointmentFilesQuery(
const {data: files = [], isLoading: isFilesLoading} = useGetAppointmentFilesQuery(
selectedAppointment?.id,
{ skip: !selectedAppointment?.id }
{skip: !selectedAppointment?.id}
);
const [downloadingFiles, setDownloadingFiles] = useState({});
const modalWidth = 700;
const blockStyle = { marginBottom: 16 };
const footerRowStyle = { marginTop: 16 };
const footerButtonStyle = { marginRight: 8 };
const blockStyle = {marginBottom: 16};
const footerRowStyle = {marginTop: 16};
const footerButtonStyle = {marginRight: 8};
const labels = {
title: "Просмотр приема",
@ -72,19 +73,17 @@ const useAppointmentViewUI = () => {
const downloadFile = async (fileId, fileName) => {
try {
setDownloadingFiles((prev) => ({ ...prev, [fileId]: true }));
// Выполняем запрос с использованием fetch, применяя baseQueryWithAuth для аутентификации
const { url, ...options } = await baseQueryWithAuth(
setDownloadingFiles((prev) => ({...prev, [fileId]: true}));
const {url, ...options} = await baseQueryWithAuth(
{
url: `/appointment_files/${fileId}/file/`,
method: 'GET',
credentials: 'include',
},
{ getState: () => ({}) },
{},
{}
);
// Поскольку baseQueryWithAuth может вернуть объект с полной URL, используем его
const response = await fetch(url, {
...options,
method: 'GET',
@ -92,7 +91,11 @@ const useAppointmentViewUI = () => {
});
if (!response.ok) {
throw new Error(`Ошибка HTTP: ${response.status} ${response.statusText}`);
notification.error({
message: "Ошибка при скачивании файла",
description: "Не удалось загрузить файл.",
placement: "topRight",
});
}
const blob = await response.blob();
@ -104,11 +107,16 @@ const useAppointmentViewUI = () => {
link.click();
link.remove();
window.URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error("Ошибка при скачивании файла:", error);
// Можно добавить уведомление, например, с antd message
console.error("Error downloading file:", error);
notification.error({
message: "Ошибка при скачивании файлов",
description: "Не удалось загрузить файл.",
placement: "topRight",
});
} finally {
setDownloadingFiles((prev) => ({ ...prev, [fileId]: false }));
setDownloadingFiles((prev) => ({...prev, [fileId]: false}));
}
};
@ -133,4 +141,4 @@ const useAppointmentViewUI = () => {
};
};
export default useAppointmentViewUI;
export default useAppointmentView;