переделал страницу с выдачами линз с использованием redux
This commit is contained in:
parent
0c0fbd89c0
commit
26484676da
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addLens = async (api, lens) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/lenses/`, lens);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default addLens;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const deleteLens = async (api, lens_id) => {
|
||||
const response = await api.delete(`${CONFIG.BASE_URL}/lenses/${lens_id}/`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default deleteLens;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllLenses = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/lenses/`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default getAllLenses;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const updateLens = async (api, lensId, lensData) => {
|
||||
const response = await api.put(`${CONFIG.BASE_URL}/lenses/${lensId}/`, lensData);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default updateLens;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addPatient = async (api, patient) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/patients/`, patient);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default addPatient;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const deletePatient = async (api, patient_id) => {
|
||||
const response = await api.delete(`${CONFIG.BASE_URL}/patients/${patient_id}/`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default deletePatient;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const updatePatient = async (api, patientId, patientData) => {
|
||||
const response = await api.put(`${CONFIG.BASE_URL}/patients/${patientId}/`, patientData);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default updatePatient;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addSetContent = async (api, set_content, set_id) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/set_content/${set_id}/`, set_content);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default addSetContent;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const updateSetContent = async (api, set_content, set_id) => {
|
||||
const response = await api.put(`${CONFIG.BASE_URL}/set_content/${set_id}/`, set_content);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default updateSetContent;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const addSet = async (api, set) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/sets/`, set);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default addSet;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const appendLensesFromSet = async (api, set_id) => {
|
||||
const response = await api.post(`${CONFIG.BASE_URL}/sets/append_lenses/${set_id}/`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default appendLensesFromSet;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const deleteSet = async (api, set_id) => {
|
||||
const response = await api.delete(`${CONFIG.BASE_URL}/sets/${set_id}/`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default deleteSet;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const getAllSets = async (api) => {
|
||||
const response = await api.get(`${CONFIG.BASE_URL}/sets/`);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default getAllSets;
|
||||
@ -1,8 +0,0 @@
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
const updateSet = async (api, set_id, set) => {
|
||||
const response = await api.put(`${CONFIG.BASE_URL}/sets/${set_id}/`, set);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default updateSet;
|
||||
@ -72,7 +72,7 @@ const LensIssueViewModal = ({visible, onCancel, lensIssue}) => {
|
||||
LensIssueViewModal.propTypes = {
|
||||
visible: PropTypes.bool.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
lensIssue: LensIssuePropType.isRequired,
|
||||
lensIssue: LensIssuePropType,
|
||||
};
|
||||
|
||||
export default LensIssueViewModal;
|
||||
47
web-app/src/hooks/data/useIssues.js
Normal file
47
web-app/src/hooks/data/useIssues.js
Normal file
@ -0,0 +1,47 @@
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {useAddLensIssuesMutation, useGetLensIssuesQuery} from "../../redux/services/lensIssuesApi.js";
|
||||
import {notification} from "antd";
|
||||
import {closeModal} from "../../redux/slices/lensIssuesSlice.js";
|
||||
|
||||
|
||||
const useIssues = () => {
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
selectedIssue,
|
||||
} = useSelector(state => state.lensIssuesUI);
|
||||
|
||||
const {data: issues = [], isLoading, isError, error} = useGetLensIssuesQuery(undefined, {
|
||||
pollingInterval: 20000,
|
||||
});
|
||||
const [addIssue] = useAddLensIssuesMutation();
|
||||
|
||||
const handleSubmitFormModal = async (issueDate, patientId, lensId) => {
|
||||
dispatch(closeModal());
|
||||
|
||||
try {
|
||||
await addIssue({issue_date: issueDate, patient_id: patientId, lens_id: lensId});
|
||||
notification.success({
|
||||
message: "Линза выдана",
|
||||
description: "Линза успешно выдана пациенту.",
|
||||
placement: "topRight",
|
||||
});
|
||||
} catch (error) {
|
||||
notification.error({
|
||||
message: "Ошибка выдачи линзы",
|
||||
description: error.data?.message || "Не удалось выдать линзу пациенту.",
|
||||
placement: "topRight",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
issues,
|
||||
isLoading,
|
||||
isError,
|
||||
error,
|
||||
selectedIssue,
|
||||
handleSubmitFormModal,
|
||||
};
|
||||
};
|
||||
|
||||
export default useIssues;
|
||||
131
web-app/src/hooks/ui/useIssuesUI.js
Normal file
131
web-app/src/hooks/ui/useIssuesUI.js
Normal file
@ -0,0 +1,131 @@
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {getCachedInfo} from "../../utils/cachedInfoUtils.js";
|
||||
import {
|
||||
closeModal,
|
||||
openModal,
|
||||
selectIssue,
|
||||
setCurrentPage,
|
||||
setEndFilterDate,
|
||||
setPageSize,
|
||||
setSearchText,
|
||||
setStartFilterDate,
|
||||
setViewMode
|
||||
} from "../../redux/slices/lensIssuesSlice.js";
|
||||
import {useEffect, useMemo} from "react";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
|
||||
const useIssuesUI = (issues) => {
|
||||
const dispatch = useDispatch();
|
||||
const {
|
||||
searchText,
|
||||
currentPage,
|
||||
pageSize,
|
||||
selectedIssue,
|
||||
isModalVisible,
|
||||
viewMode,
|
||||
startFilterDate,
|
||||
endFilterDate,
|
||||
} = useSelector(state => state.lensIssuesUI);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = "Выдача линз";
|
||||
const cachedViewMode = getCachedInfo("viewModeIssues");
|
||||
if (cachedViewMode) dispatch(setViewMode(cachedViewMode));
|
||||
}, [dispatch])
|
||||
|
||||
const startFilterDateConverted = startFilterDate ? dayjs(startFilterDate) : null;
|
||||
const endFilterDateConverted = endFilterDate ? dayjs(endFilterDate) : null;
|
||||
const filterDates = [startFilterDateConverted, endFilterDateConverted];
|
||||
const isFilterDates = startFilterDate && endFilterDate;
|
||||
|
||||
const handleSetSearchText = (value) => dispatch(setSearchText(value));
|
||||
const handleSetViewMode = (mode) => dispatch(setViewMode(mode));
|
||||
const handleSetCurrentPage = (page) => dispatch(setCurrentPage(page));
|
||||
const handleSetPageSize = (size) => dispatch(setPageSize(size));
|
||||
const handleCloseModal = () => dispatch(closeModal());
|
||||
const handleSelectIssue = (issue) => dispatch(selectIssue(issue));
|
||||
const resetSelectedIssue = () => dispatch(selectIssue(null));
|
||||
|
||||
const handleAddIssue = () => {
|
||||
dispatch(selectIssue(null));
|
||||
dispatch(openModal());
|
||||
};
|
||||
|
||||
const handlePaginationChange = (page, pageSize) => {
|
||||
handleSetCurrentPage(page);
|
||||
handleSetPageSize(pageSize);
|
||||
};
|
||||
|
||||
const handleFilterDateChange = (dates) => {
|
||||
if (dates) {
|
||||
const [start, end] = dates;
|
||||
dispatch(setStartFilterDate(start.toISOString()));
|
||||
dispatch(setEndFilterDate(end.toISOString()));
|
||||
}
|
||||
};
|
||||
|
||||
const handleResetFilterDate = () => {
|
||||
dispatch(setStartFilterDate(null));
|
||||
dispatch(setEndFilterDate(null));
|
||||
};
|
||||
|
||||
const filteredIssues = useMemo(() => {
|
||||
return issues.filter(issue => {
|
||||
let dateFilter = true;
|
||||
|
||||
if (startFilterDateConverted && endFilterDateConverted) {
|
||||
const issueDate = dayjs(issue.issue_date);
|
||||
|
||||
dateFilter = issueDate.isAfter(startFilterDateConverted) && issueDate.isBefore(endFilterDateConverted);
|
||||
}
|
||||
|
||||
return (
|
||||
(
|
||||
issue.patient.last_name.toLowerCase().includes(searchText) ||
|
||||
issue.patient.first_name.toLowerCase().includes(searchText) ||
|
||||
issue.doctor.last_name.toLowerCase().includes(searchText) ||
|
||||
issue.doctor.first_name.toLowerCase().includes(searchText)
|
||||
) &&
|
||||
dateFilter
|
||||
)
|
||||
});
|
||||
}, [issues, searchText, startFilterDateConverted, endFilterDateConverted]);
|
||||
|
||||
const pagination = {
|
||||
current: currentPage,
|
||||
pageSize: pageSize,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["5", "10", "20", "50"],
|
||||
onChange: (page, newPageSize) => {
|
||||
setCurrentPage(page);
|
||||
setPageSize(newPageSize);
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
filteredIssues,
|
||||
pagination,
|
||||
searchText,
|
||||
selectedIssue,
|
||||
isModalVisible,
|
||||
viewMode,
|
||||
currentPage,
|
||||
pageSize,
|
||||
filterDates,
|
||||
isFilterDates,
|
||||
handleAddIssue,
|
||||
handlePaginationChange,
|
||||
handleSetSearchText,
|
||||
handleSetViewMode,
|
||||
handleSetCurrentPage,
|
||||
handleSetPageSize,
|
||||
handleCloseModal,
|
||||
handleFilterDateChange,
|
||||
resetSelectedIssue,
|
||||
handleSelectIssue,
|
||||
handleResetFilterDate,
|
||||
};
|
||||
};
|
||||
|
||||
export default useIssuesUI;
|
||||
@ -1,5 +1,5 @@
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {useEffect} from "react";
|
||||
import {useEffect, useMemo} from "react";
|
||||
import {
|
||||
closeModal,
|
||||
openModal,
|
||||
@ -24,9 +24,9 @@ const useSetsUI = (sets) => {
|
||||
document.title = "Наборы линз";
|
||||
}, [dispatch]);
|
||||
|
||||
const containerStyle = { padding: 20 };
|
||||
const filterBarStyle = { marginBottom: 20 };
|
||||
const formItemStyle = { width: "100%" };
|
||||
const containerStyle = {padding: 20};
|
||||
const filterBarStyle = {marginBottom: 20};
|
||||
const formItemStyle = {width: "100%"};
|
||||
|
||||
const handleSetSearchText = (value) => dispatch(setSearchText(value));
|
||||
const handleCloseModal = () => dispatch(closeModal());
|
||||
@ -58,7 +58,10 @@ const useSetsUI = (sets) => {
|
||||
},
|
||||
};
|
||||
|
||||
const filteredSets = sets.filter(set => set.title.toLowerCase().includes(searchText.toLowerCase()));
|
||||
const filteredSets = useMemo(
|
||||
() => sets.filter(set => set.title.toLowerCase().includes(searchText.toLowerCase())),
|
||||
[sets, searchText]
|
||||
);
|
||||
|
||||
return {
|
||||
searchText,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import {
|
||||
notification,
|
||||
Table,
|
||||
Input,
|
||||
Row,
|
||||
@ -9,130 +8,28 @@ import {
|
||||
Button,
|
||||
FloatButton,
|
||||
Typography,
|
||||
Timeline, Grid, Pagination
|
||||
Timeline,
|
||||
Grid,
|
||||
Pagination
|
||||
} from "antd";
|
||||
import getAllLensIssues from "../api/lens_issues/getAllLensIssues.js";
|
||||
import {useEffect, useState} from "react";
|
||||
import {useAuth} from "../AuthContext.jsx";
|
||||
import {DatabaseOutlined, PlusOutlined, UnorderedListOutlined} from "@ant-design/icons";
|
||||
import LensIssueViewModal from "../components/lens_issues/LensIssueViewModal.jsx";
|
||||
import dayjs from "dayjs";
|
||||
import LensIssueFormModal from "../components/lens_issues/LensIssueFormModal.jsx";
|
||||
import addLensIssue from "../api/lens_issues/addLensIssue.js";
|
||||
import SelectViewMode from "../components/SelectViewMode.jsx";
|
||||
import LoadingIndicator from "../components/LoadingIndicator.jsx";
|
||||
import {getCachedInfo, getCacheTimestamp} from "../utils/cachedInfoUtils.js";
|
||||
import useIssues from "../hooks/data/useIssues.js";
|
||||
import useIssuesUI from "../hooks/ui/useIssuesUI.js";
|
||||
|
||||
const {Title} = Typography;
|
||||
const {useBreakpoint} = Grid;
|
||||
|
||||
const IssuesPage = () => {
|
||||
const {api} = useAuth();
|
||||
const issuesData = useIssues();
|
||||
const issuesUI = useIssuesUI(issuesData.issues);
|
||||
|
||||
const screens = useBreakpoint();
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [lensIssues, setLensIssues] = useState([]);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [selectedIssue, setSelectedIssue] = useState(null);
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [viewMode, setViewMode] = useState("table");
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
|
||||
const [timelinePage, setTimelinePage] = useState(1);
|
||||
const [timeLinePageSize, setTimeLinePageSize] = useState(10);
|
||||
|
||||
const [startFilterDate, setStartFilterDate] = useState(null);
|
||||
const [endFilterDate, setEndFilterDate] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchLensIssuesWithCache();
|
||||
fetchViewModeFromCache();
|
||||
document.title = "Выдача линз";
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isModalVisible) {
|
||||
const intervalId = setInterval(fetchLensIssues, 5000);
|
||||
return () => clearInterval(intervalId);
|
||||
}
|
||||
}, [isModalVisible]);
|
||||
|
||||
const fetchLensIssuesWithCache = async () => {
|
||||
const cachedData = getCachedInfo("lensIssuesData");
|
||||
const cacheTimestamp = getCacheTimestamp("lensIssuesData");
|
||||
|
||||
if (cachedData && cacheTimestamp && (Date.now() - cacheTimestamp) < 60 * 1000) {
|
||||
setLensIssues(JSON.parse(cachedData));
|
||||
setLoading(false);
|
||||
} else {
|
||||
await fetchLensIssues();
|
||||
}
|
||||
};
|
||||
|
||||
const fetchViewModeFromCache = () => {
|
||||
const cachedViewMode = getCachedInfo("viewModeIssues");
|
||||
if (cachedViewMode) {
|
||||
setViewMode(cachedViewMode);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddIssue = () => {
|
||||
setSelectedIssue(null);
|
||||
setIsModalVisible(true);
|
||||
};
|
||||
|
||||
const handleCloseViewModal = () => {
|
||||
setSelectedIssue(null);
|
||||
};
|
||||
|
||||
const handleCloseFormModal = () => {
|
||||
setIsModalVisible(false);
|
||||
};
|
||||
|
||||
const handleSubmitFormModal = async (issue_date, patient_id, lens_id) => {
|
||||
setIsModalVisible(false);
|
||||
await addLensIssue(api, {issue_date, patient_id, lens_id});
|
||||
notification.success({
|
||||
message: "Линза выдана",
|
||||
description: "Линза успешно выдана пациенту.",
|
||||
placement: "topRight",
|
||||
});
|
||||
await fetchLensIssues();
|
||||
};
|
||||
|
||||
const fetchLensIssues = async () => {
|
||||
const data = await getAllLensIssues(api);
|
||||
setLensIssues(data);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const handleSearch = (e) => {
|
||||
setSearchTerm(e.target.value.toLowerCase());
|
||||
};
|
||||
|
||||
const filteredIssues = lensIssues.filter(issue => {
|
||||
let dateFilter = true;
|
||||
|
||||
if (startFilterDate && endFilterDate) {
|
||||
const issueDate = dayjs(issue.issue_date);
|
||||
|
||||
dateFilter = issueDate.isAfter(startFilterDate) && issueDate.isBefore(endFilterDate);
|
||||
}
|
||||
|
||||
return (
|
||||
(
|
||||
issue.patient.last_name.toLowerCase().includes(searchTerm) ||
|
||||
issue.patient.first_name.toLowerCase().includes(searchTerm) ||
|
||||
issue.doctor.last_name.toLowerCase().includes(searchTerm) ||
|
||||
issue.doctor.first_name.toLowerCase().includes(searchTerm)
|
||||
) &&
|
||||
dateFilter
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
const viewModes = [
|
||||
{
|
||||
value: "table",
|
||||
@ -176,7 +73,7 @@ const IssuesPage = () => {
|
||||
title: "Действия",
|
||||
key: "actions",
|
||||
render: (_, issue) => (
|
||||
<Button type={"link"} onClick={() => setSelectedIssue(issue)}>Подробнее</Button>
|
||||
<Button type={"link"} onClick={() => issuesUI.handleSelectIssue(issue)}>Подробнее</Button>
|
||||
),
|
||||
},
|
||||
];
|
||||
@ -184,23 +81,14 @@ const IssuesPage = () => {
|
||||
const TableView = () => (
|
||||
<Table
|
||||
columns={columns}
|
||||
dataSource={filteredIssues}
|
||||
dataSource={issuesUI.filteredIssues}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
current: currentPage,
|
||||
pageSize: pageSize,
|
||||
showSizeChanger: true,
|
||||
pageSizeOptions: ["5", "10", "20", "50"],
|
||||
onChange: (page, newPageSize) => {
|
||||
setCurrentPage(page);
|
||||
setPageSize(newPageSize);
|
||||
},
|
||||
}}
|
||||
pagination={issuesUI.pagination}
|
||||
showSorterTooltip={false}
|
||||
/>
|
||||
);
|
||||
|
||||
const timeLineItems = filteredIssues.map(issue => ({
|
||||
const timeLineItems = issuesUI.filteredIssues.map(issue => ({
|
||||
label: dayjs(issue.issue_date).format("DD.MM.YYYY"),
|
||||
children: (
|
||||
<Row
|
||||
@ -216,7 +104,7 @@ const IssuesPage = () => {
|
||||
<Col xs={24} md={24} sm={24} xl={6}>
|
||||
<Button
|
||||
type={"dashed"}
|
||||
onClick={() => setSelectedIssue(issue)}
|
||||
onClick={() => issuesUI.handleSelectIssue(issue)}
|
||||
style={{marginRight: 40}}
|
||||
>
|
||||
Подробнее
|
||||
@ -228,8 +116,8 @@ const IssuesPage = () => {
|
||||
|
||||
const TimeLineView = () => {
|
||||
const paginatedItems = timeLineItems.slice(
|
||||
(timelinePage - 1) * timeLinePageSize,
|
||||
timelinePage * timeLinePageSize
|
||||
(issuesUI.currentPage - 1) * issuesUI.pageSize,
|
||||
issuesUI.currentPage * issuesUI.pageSize
|
||||
);
|
||||
|
||||
return (
|
||||
@ -244,13 +132,10 @@ const IssuesPage = () => {
|
||||
justify={"end"}
|
||||
>
|
||||
<Pagination
|
||||
current={timelinePage}
|
||||
pageSize={timeLinePageSize}
|
||||
current={issuesUI.currentPage}
|
||||
pageSize={issuesUI.pageSize}
|
||||
total={timeLineItems.length}
|
||||
onChange={(page, newPageSize) => {
|
||||
setTimelinePage(page);
|
||||
setTimeLinePageSize(newPageSize);
|
||||
}}
|
||||
onChange={issuesUI.handlePaginationChange}
|
||||
showSizeChanger={true}
|
||||
pageSizeOptions={["5", "10", "20", "50"]}
|
||||
/>
|
||||
@ -266,18 +151,18 @@ const IssuesPage = () => {
|
||||
<Col xs={24} md={24} sm={24} xl={12}>
|
||||
<Input
|
||||
placeholder="Поиск по пациенту или врачу"
|
||||
onChange={handleSearch}
|
||||
onChange={(e) => issuesUI.handleSetSearchText(e.target.value)}
|
||||
style={{width: "100%"}}
|
||||
allowClear
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col xs={24} md={
|
||||
startFilterDate && endFilterDate ? 12 : 16
|
||||
issuesUI.isFilterDates ? 12 : 16
|
||||
} sm={
|
||||
16
|
||||
} xl={
|
||||
startFilterDate && endFilterDate ? 6 : 8
|
||||
issuesUI.isFilterDates ? 6 : 8
|
||||
}>
|
||||
<Tooltip
|
||||
title="Фильтр по дате выдачи линзы"
|
||||
@ -287,24 +172,18 @@ const IssuesPage = () => {
|
||||
style={{width: "100%"}}
|
||||
placeholder={["Дата начала", "Дата окончания"]}
|
||||
format="DD.MM.YYYY"
|
||||
value={[startFilterDate, endFilterDate]}
|
||||
onChange={(dates) => {
|
||||
setStartFilterDate(dates[0]);
|
||||
setEndFilterDate(dates[1]);
|
||||
}}
|
||||
value={issuesUI.isFilterDates && issuesUI.filterDates}
|
||||
onChange={issuesUI.handleFilterDateChange}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{startFilterDate && endFilterDate && (
|
||||
{issuesUI.isFilterDates && (
|
||||
<Col xs={24} md={4} sm={8} xl={2}>
|
||||
<Tooltip
|
||||
title="Cбросить фильтр"
|
||||
>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setStartFilterDate(null);
|
||||
setEndFilterDate(null);
|
||||
}}
|
||||
onClick={issuesUI.handleResetFilterDate}
|
||||
type={"primary"}
|
||||
block
|
||||
>
|
||||
@ -314,21 +193,21 @@ const IssuesPage = () => {
|
||||
</Col>
|
||||
)}
|
||||
<Col xs={24}
|
||||
md={startFilterDate && endFilterDate ? 8 : 8}
|
||||
sm={startFilterDate && endFilterDate ? 24 : 8}
|
||||
md={issuesUI.isFilterDates ? 8 : 8}
|
||||
sm={issuesUI.isFilterDates ? 24 : 8}
|
||||
xl={4}>
|
||||
<SelectViewMode
|
||||
viewMode={viewMode}
|
||||
setViewMode={setViewMode}
|
||||
viewMode={issuesUI.viewMode}
|
||||
setViewMode={issuesUI.handleSetViewMode}
|
||||
localStorageKey={"viewModeIssues"}
|
||||
toolTipText={"Формат отображения выдач линз"}
|
||||
viewModes={viewModes}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
{loading ? (
|
||||
{issuesData.isLoading ? (
|
||||
<LoadingIndicator/>
|
||||
) : viewMode === "table" ? (
|
||||
) : issuesUI.viewMode === "table" ? (
|
||||
<TableView/>
|
||||
) : (
|
||||
<TimeLineView/>
|
||||
@ -337,21 +216,20 @@ const IssuesPage = () => {
|
||||
<FloatButton
|
||||
icon={<PlusOutlined/>}
|
||||
type={"primary"}
|
||||
style={{position: "fixed", bottom: 40, right: 40}}
|
||||
onClick={handleAddIssue}
|
||||
onClick={issuesUI.handleAddIssue}
|
||||
tooltip={"Добавить выдачу линзы"}
|
||||
/>
|
||||
|
||||
<LensIssueFormModal
|
||||
visible={isModalVisible}
|
||||
onCancel={handleCloseFormModal}
|
||||
onSubmit={handleSubmitFormModal}
|
||||
visible={issuesUI.isModalVisible}
|
||||
onCancel={issuesUI.handleCloseModal}
|
||||
onSubmit={issuesData.handleSubmitFormModal}
|
||||
/>
|
||||
|
||||
<LensIssueViewModal
|
||||
visible={selectedIssue !== null}
|
||||
onCancel={handleCloseViewModal}
|
||||
lensIssue={selectedIssue}
|
||||
visible={issuesUI.selectedIssue !== null}
|
||||
onCancel={issuesUI.resetSelectedIssue}
|
||||
lensIssue={issuesUI.selectedIssue}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
36
web-app/src/redux/services/lensIssuesApi.js
Normal file
36
web-app/src/redux/services/lensIssuesApi.js
Normal file
@ -0,0 +1,36 @@
|
||||
import {createApi, fetchBaseQuery} from "@reduxjs/toolkit/query/react";
|
||||
import CONFIG from "../../core/сonfig.js";
|
||||
|
||||
|
||||
export const lensIssuesApi = createApi({
|
||||
reducerPath: 'lensIssuesApi',
|
||||
baseQuery: fetchBaseQuery({
|
||||
baseUrl: CONFIG.BASE_URL,
|
||||
prepareHeaders: (headers) => {
|
||||
const token = localStorage.getItem('access_token');
|
||||
if (token) headers.set('Authorization', `Bearer ${token}`);
|
||||
return headers;
|
||||
}
|
||||
}),
|
||||
tagTypes: ['LensIssues'],
|
||||
endpoints: (builder) => ({
|
||||
getLensIssues: builder.query({
|
||||
query: () => '/lens_issues/',
|
||||
providesTags: ['LensIssues'],
|
||||
refetchOnMountOrArgChange: 5
|
||||
}),
|
||||
addLensIssues: builder.mutation({
|
||||
query: (lensIssues) => ({
|
||||
url: `/lens_issues/`,
|
||||
method: 'POST',
|
||||
body: lensIssues
|
||||
}),
|
||||
invalidatesTags: ['LensIssues']
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useGetLensIssuesQuery,
|
||||
useAddLensIssuesMutation
|
||||
} = lensIssuesApi;
|
||||
64
web-app/src/redux/slices/lensIssuesSlice.js
Normal file
64
web-app/src/redux/slices/lensIssuesSlice.js
Normal file
@ -0,0 +1,64 @@
|
||||
import {createSlice} from "@reduxjs/toolkit";
|
||||
import {cacheInfo} from "../../utils/cachedInfoUtils.js";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const initialState = {
|
||||
searchText: '',
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
selectedIssue: null,
|
||||
isModalVisible: false,
|
||||
viewMode: 'table',
|
||||
startFilterDate: null,
|
||||
endFilterDate: null,
|
||||
};
|
||||
|
||||
const lensIssuesSlice = createSlice({
|
||||
name: 'setIssuesUI',
|
||||
initialState,
|
||||
reducers: {
|
||||
setSearchText: (state, action) => {
|
||||
state.searchText = action.payload;
|
||||
},
|
||||
setCurrentPage: (state, action) => {
|
||||
state.currentPage = action.payload;
|
||||
},
|
||||
setPageSize: (state, action) => {
|
||||
state.pageSize = action.payload;
|
||||
},
|
||||
selectIssue: (state, action) => {
|
||||
state.selectedIssue = action.payload;
|
||||
},
|
||||
openModal: (state) => {
|
||||
state.isModalVisible = true;
|
||||
},
|
||||
closeModal: (state) => {
|
||||
state.isModalVisible = false;
|
||||
state.selectedIssue = null;
|
||||
},
|
||||
setViewMode: (state, action) => {
|
||||
state.viewMode = action.payload;
|
||||
cacheInfo("viewModeIssues", action.payload);
|
||||
},
|
||||
setStartFilterDate: (state, action) => {
|
||||
state.startFilterDate = action.payload;
|
||||
},
|
||||
setEndFilterDate: (state, action) => {
|
||||
state.endFilterDate = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setSearchText,
|
||||
setCurrentPage,
|
||||
setPageSize,
|
||||
selectIssue,
|
||||
openModal,
|
||||
closeModal,
|
||||
setViewMode,
|
||||
setStartFilterDate,
|
||||
setEndFilterDate,
|
||||
} = lensIssuesSlice.actions;
|
||||
|
||||
export default lensIssuesSlice.reducer;
|
||||
@ -6,6 +6,8 @@ import lensesUIReducer from './slices/lensesSlice.js';
|
||||
import {setsApi} from "./services/setsApi.js";
|
||||
import setsUIReducer from './slices/setsSlice.js';
|
||||
import {setContentApi} from "./services/setContentApi.js";
|
||||
import {lensIssuesApi} from "./services/lensIssuesApi.js";
|
||||
import lensIssuesReducer from "./slices/lensIssuesSlice.js";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
@ -19,6 +21,9 @@ export const store = configureStore({
|
||||
setsUI: setsUIReducer,
|
||||
|
||||
[setContentApi.reducerPath]: setContentApi.reducer,
|
||||
|
||||
[lensIssuesApi.reducerPath]: lensIssuesApi.reducer,
|
||||
lensIssuesUI: lensIssuesReducer,
|
||||
},
|
||||
middleware: (getDefaultMiddleware) => (
|
||||
getDefaultMiddleware().concat(
|
||||
@ -26,6 +31,7 @@ export const store = configureStore({
|
||||
lensesApi.middleware,
|
||||
setsApi.middleware,
|
||||
setContentApi.middleware,
|
||||
lensIssuesApi.middleware,
|
||||
)
|
||||
)
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user