Commit 589dfa53 authored by Merekeyev Dias's avatar Merekeyev Dias

added syncBtn funcionality

parent 6880164c
......@@ -6,7 +6,6 @@ import Header from './components/Header/Header';
import AuthPage from './pages/AuthPage/AuthPage';
import HomePage from './pages/HomePage/HomePage';
import RequestPage from './pages/RequestPage/RequestPage';
import ManualPage from './pages/ManualPage/ManualPage';
import AddEditPage from './pages/ManageOrganization/ManageOrganization';
import './App.css';
......@@ -35,7 +34,6 @@ const App: React.FC = () => {
<Route path="/" element={<HomePage />} />
<Route path="/add" element={<AddEditPage />} />
<Route path="/edit/:id" element={<AddEditPage />} />
<Route path='/manuals' element={<ManualPage />} />
<Route path="/requests" element={<RequestPage />} />
<Route path="/*" element={<Navigate to="/" />} />
</Route>
......
......@@ -11,7 +11,6 @@ type MenuItem = Required<MenuProps>['items'][number];
const MenuItems: MenuItem[] = [
{ key: 'org', icon: <MaterialSymbol icon='list' size={24} color='#fff' />, label: <Link to="/">Список организаций</Link> },
{ key: 'man', icon: <MaterialSymbol icon='developer_guide' size={24} color='#fff' />, label: <Link to="/manuals">Справочники</Link> },
{ key: 'req', icon: <MaterialSymbol icon='info' size={24} color='#fff' />, label: <Link to="/requests">Информация о запросах</Link> },
];
......@@ -25,8 +24,6 @@ const Header: React.FC = () => {
useEffect(() => {
const pathToNavKey = (path: string) => {
switch (path) {
case '/manuals':
return 'man';
case '/requests':
return 'req';
default:
......
......@@ -19,6 +19,6 @@ export const apiSlice = createApi({
return headers;
},
}),
tagTypes: ["organizations", "requests"],
tagTypes: ["organizations", "requests", "manuals"],
endpoints: () => ({}),
});
\ No newline at end of file
import { apiSlice } from "./apiSlice";
export const manualApiSlice = apiSlice.injectEndpoints({
endpoints: (builder) => ({
updateDictionary: builder.mutation({
query: (codes) => ({
url: 'dictionary/update',
method: 'POST',
body: codes,
}), invalidatesTags: ['manuals']
})
})
})
export const {
useUpdateDictionaryMutation
} = manualApiSlice;
\ No newline at end of file
......@@ -11,6 +11,7 @@ interface Organization {
login: string;
password: string;
host: string;
checked?: Boolean;
}
export const organizationApiSlice = apiSlice.injectEndpoints({
......
import { createSlice } from "@reduxjs/toolkit";
interface InitialState {
checkedCodes: string[];
disabled: boolean;
}
const initialState: InitialState = {
checkedCodes: [],
disabled: true
};
const syncBtnSlice = createSlice({
name: 'syncBtn',
initialState,
reducers: {
addCheckedCodes: (state, action) => {
state.checkedCodes.push(action.payload);
},
removeCheckedCodes: (state, action) => {
state.checkedCodes = state.checkedCodes.filter(code => code !== action.payload);
},
setDisabled: (state, action) => {
state.disabled = action.payload;
}
}
});
export const { addCheckedCodes, removeCheckedCodes, setDisabled } = syncBtnSlice.actions;
export default syncBtnSlice.reducer;
\ No newline at end of file
import React, { useState } from 'react';
import { useNavigate } from 'react-router';
import { Button, Space, Tag, Modal, message } from 'antd';
import { Button, Space, Tag, Modal, Checkbox, message } from 'antd';
import type { TableProps } from 'antd';
import { useDispatch } from 'react-redux';
import { useDeleteOrganizationMutation } from '../../features/api/organizationApiSlice';
import { getStatusText, getStatusColor } from './utils';
import { addCheckedCodes, removeCheckedCodes } from '../../features/sync_btn/syncBtn';
export interface DataType {
id: number;
......@@ -15,6 +17,10 @@ export interface DataType {
}
export const columns: TableProps<DataType>['columns'] = [
{
width: '1%',
render: (_, record) => <CheckboxColumn data={record} />
},
{
title: "ID",
dataIndex: "id",
......@@ -53,14 +59,33 @@ export const columns: TableProps<DataType>['columns'] = [
{
title: "Действия",
width: 60,
render: (_, record) => {
return (
<ActionColumn data={record} />
)
}
render: (_, record) => <ActionColumn data={record} />
}
]
export const CheckboxColumn: React.FC<{ data: DataType }> = ({ data }) => {
const dispatch = useDispatch();
const [checked, setChecked] = useState(false);
const handleCheck = (e: { target: { checked: any; }; }) => {
const isChecked = e.target.checked;
setChecked(isChecked);
if (isChecked) {
dispatch(addCheckedCodes(data.code));
} else {
dispatch(removeCheckedCodes(data.code));
}
};
return (
<Checkbox
className='checkbox_org--custom'
checked={checked}
onChange={handleCheck}
/>
);
};
export const ActionColumn: React.FC<{ data: DataType }> = ({ data }) => {
const [open, setOpen] = useState<boolean>(false);
const navigate = useNavigate();
......
import React, { createRef, useEffect } from 'react';
import React, { createRef, useEffect, useState } from 'react';
import { useNavigate } from 'react-router';
import { useSelector, useDispatch } from 'react-redux';
import { Button, Pagination, Spin, Table } from 'antd';
import { useGetOrganizationsQuery } from '../../features/api/organizationApiSlice';
import { Button, message, Pagination, Space, Spin, Table } from 'antd';
import { useDeleteOrganizationMutation, useGetOrganizationsQuery } from '../../features/api/organizationApiSlice';
import { setCurrentPage, setTotalOrgNumber } from '../../features/pagination/mainPagination';
import { DataType, columns } from './Columns';
import { TableRef } from 'antd/es/table';
import './Homepage.css';
import { setDisabled } from '../../features/sync_btn/syncBtn';
const HomePage: React.FC = () => {
const navigate = useNavigate();
......@@ -15,11 +16,24 @@ const HomePage: React.FC = () => {
const totalOrgNumber = useSelector((state: any) => state.mainPagination.totalOrgNumber);
const currentPage = useSelector((state: any) => state.mainPagination.currentPage);
const ORG_NUMBER_PER_PAGE = useSelector((state: any) => state.mainPagination.ORG_NUMBER_PER_PAGE);
const syncBtnState = useSelector((state: any) => state.syncBtn.disabled);
const checkedCodes = useSelector((state: any) => state.syncBtn.checkedCodes);
const [updateDictionary] = useDeleteOrganizationMutation();
const handleAddClick = () => {
navigate("/add");
};
const handleSyncClick = async () => {
try {
console.log(checkedCodes);
await updateDictionary(JSON.stringify(checkedCodes)).unwrap();
message.success('Организации успешны синхронизированы!')
} catch (err) {
message.error('Произошла ошибка при синхронизации организации!')
}
};
const handlePaginationChange = (page: number) => {
/*
scrollIntoView resets to the top of the table after changing the page with Pagination. But the bug was found - the div above the table scrolls to top of the page too, under the Header component. It happens because of overflow
......@@ -48,12 +62,12 @@ const HomePage: React.FC = () => {
table = <Spin />
} else if (isSuccess) {
table = <Table
dataSource={paginatedData(orgs)}
columns={columns} pagination={false}
rowKey="id"
className='home_table'
ref={tableRef}
/>
dataSource={paginatedData(orgs)}
columns={columns} pagination={false}
rowKey="id"
className='home_table'
ref={tableRef}
/>
} else if (isError) {
table = <div>{error.toString()}</div>
}
......@@ -64,18 +78,32 @@ const HomePage: React.FC = () => {
}
}, [isSuccess, orgs]);
useEffect(() => {
if (checkedCodes.length > 0) {
dispatch(setDisabled(false));
} else {
dispatch(setDisabled(true));
}
}, [checkedCodes, dispatch])
return (
<div className="container">
<section className='section'>
<div>
<Space size={'middle'}>
<Button
className='add_title'
type='primary'
onClick={handleAddClick}
>
Добавить
</Button>
</div>
<Button
className='add_title'
onClick={handleSyncClick}
disabled={syncBtnState}
>
Синхронизировать справочники
</Button>
</Space>
<div className="data">
{table}
</div>
......
......@@ -31,4 +31,10 @@
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
display: flex;
justify-content: center;
}
/* Custom checkbox */
.checkbox_org--custom .ant-checkbox-inner {
border-color: #33333386;
}
\ No newline at end of file
import React from "react";
const ManualPage:React.FC = () => {
return (
<>
</>
)
}
export default ManualPage;
\ No newline at end of file
......@@ -45,7 +45,7 @@ const RequestPage: React.FC = () => {
const applyFilters = () => {
let filtered = reqs.list;
/*
subtract method is added because of the unique dates (hh:mm:ss = 00:00:00). The code below is the easiest way to deal with it, but it is not the ideal form
subtract method is added because of the unique dates (hh:mm:ss = 00:00:00). The code below is the easiest way to deal with it, but it might be not the ideal form
*/
const adjustedStartDate = dayjs(startDate).subtract(1, 'day');
if (startDate && endDate) {
......
......@@ -4,6 +4,7 @@ import { persistReducer, persistStore } from 'redux-persist';
import { apiSlice } from '../features/api/apiSlice';
import mainPaginationReducer from '../features/pagination/mainPagination';
import reqPaginationReducer from '../features/pagination/reqPagination';
import syncBtnReducer from '../features/sync_btn/syncBtn';
interface AuthState {
token: string | null;
......@@ -40,6 +41,7 @@ const store: Store = configureStore({
auth: persistedReducer,
mainPagination: mainPaginationReducer,
reqPagination: reqPaginationReducer,
syncBtn: syncBtnReducer,
[apiSlice.reducerPath]: apiSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment