From 6a2f296d7c3f77d80f2f2c6e4380e7a0ca77aebb Mon Sep 17 00:00:00 2001 From: nadeocfg Date: Sun, 29 Oct 2023 00:42:46 +0600 Subject: [PATCH 1/2] feat: add layout for filters --- frontend/src/assets/scss/utils/_layouts.scss | 42 ++-- frontend/src/components/Btn/Btn.scss | 12 ++ frontend/src/components/Btn/Btn.tsx | 15 +- .../OrdersSearchPanel/OrdersSearchPanel.scss | 16 ++ .../OrdersSearchPanel/OrdersSearchPanel.tsx | 197 ++++++++++++++++++ .../src/components/OrdersSearchPanel/index.ts | 1 + .../UpdateCustomerModal.tsx | 4 +- .../CreateBoilerModal/CreateBoilerModal.tsx | 6 +- .../CreateCustomerModal.tsx | 6 +- .../CreateJobTypeModal/CreateJobTypeModal.tsx | 6 +- .../CreateOrderStatusModal.tsx | 6 +- .../CreatePartModal/CreatePartModal.tsx | 6 +- .../CreateRoleModal/CreateRoleModal.tsx | 6 +- .../CreateUserModal/CreateUserModal.tsx | 6 +- frontend/src/pages/Customers/Customers.tsx | 39 ++-- frontend/src/pages/EditUser/EditUser.tsx | 4 +- frontend/src/pages/PaidOuts/PaidOuts.tsx | 43 ++-- frontend/src/pages/SignIn/SignIn.tsx | 2 +- frontend/src/pages/Users/Users.scss | 34 --- frontend/src/pages/Users/Users.tsx | 27 +-- .../src/pages/administration/Cash/Cash.scss | 13 -- .../src/pages/administration/Cash/Cash.tsx | 10 +- .../DictBoilers/DictBoilers.tsx | 29 +-- .../DictJobTypes/DictJobTypes.tsx | 29 +-- .../administration/DictParts/DictParts.tsx | 29 +-- .../administration/Settings/Settings.tsx | 10 +- .../pages/orders/CreateOrder/CreateOrder.tsx | 8 +- .../src/pages/orders/OrderEdit/OrderEdit.tsx | 8 +- .../src/pages/orders/OrderView/OrderView.tsx | 6 +- .../pages/orders/OrdersList/OrdersList.tsx | 69 +++--- 30 files changed, 443 insertions(+), 246 deletions(-) create mode 100644 frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss create mode 100644 frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx create mode 100644 frontend/src/components/OrdersSearchPanel/index.ts diff --git a/frontend/src/assets/scss/utils/_layouts.scss b/frontend/src/assets/scss/utils/_layouts.scss index 4305204..ce99747 100644 --- a/frontend/src/assets/scss/utils/_layouts.scss +++ b/frontend/src/assets/scss/utils/_layouts.scss @@ -10,15 +10,6 @@ } } -.search-row { - display: flex; - flex-direction: column; - - h1 { - margin: 16px 0; - } -} - .select-modal { height: 600px; @@ -28,23 +19,34 @@ } } -@media (min-width: 600px) { - .btn-container { - flex-direction: row; - padding: 0 32px 16px 32px; +.search-row { + display: flex; + flex-direction: column; + flex-wrap: wrap; + align-items: center; + width: 100%; + margin-bottom: 20px; - .MuiButtonBase-root.btn { - width: auto; + .MuiInputBase-root { + flex-grow: 1; + width: 100%; + margin: 16px 0; + } - & + .btn { - margin-left: 8px; - } - } + h1 { + margin: 16px 0; } +} +@media (min-width: 600px) { .search-row { - display: flex; flex-direction: row; + flex-wrap: nowrap; justify-content: space-between; + + .MuiInputBase-root { + width: auto; + margin: 0 16px; + } } } diff --git a/frontend/src/components/Btn/Btn.scss b/frontend/src/components/Btn/Btn.scss index 3cc2023..bf77cee 100644 --- a/frontend/src/components/Btn/Btn.scss +++ b/frontend/src/components/Btn/Btn.scss @@ -30,6 +30,18 @@ } } + &_link { + padding: 0; + background: transparent; + color: var(--primary-color); + text-transform: none; + text-decoration: underline; + + &:hover { + background: transparent; + } + } + &_success { background: var(--success-color); color: var(--white-color); diff --git a/frontend/src/components/Btn/Btn.tsx b/frontend/src/components/Btn/Btn.tsx index fb5d05d..a15f5c4 100644 --- a/frontend/src/components/Btn/Btn.tsx +++ b/frontend/src/components/Btn/Btn.tsx @@ -1,28 +1,30 @@ -import { Button } from '@material-ui/core'; +import { Button, ButtonBaseProps } from '@material-ui/core'; import { NavLink } from 'react-router-dom'; -interface ButtonProps { +interface ButtonProps extends ButtonBaseProps { children: any; - classes?: string; + className?: string; onClick?: React.MouseEventHandler; href?: string; disabled?: boolean; target?: string; to?: any; type?: 'button' | 'submit' | 'reset' | undefined; + disableRipple?: boolean | undefined; } export default function Btn({ to, children, - classes, + className, disabled, onClick, type, + disableRipple, }: ButtonProps) { if (to) { return ( - + {children} ); @@ -34,8 +36,9 @@ export default function Btn({ disableElevation onClick={onClick} disabled={disabled} - className={classes} + className={className} type={type} + disableRipple={disableRipple} > {children} diff --git a/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss new file mode 100644 index 0000000..cb74875 --- /dev/null +++ b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss @@ -0,0 +1,16 @@ +.search-panel { + margin-bottom: 20px; +} + +.filter { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 16px; + padding: 16px 0; + + &__item { + flex-basis: 40%; + flex-grow: 1; + } +} diff --git a/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx new file mode 100644 index 0000000..ea227ec --- /dev/null +++ b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx @@ -0,0 +1,197 @@ +import { + Box, + Collapse, + FormControl, + InputBase, + MenuItem, + TextField, +} from '@material-ui/core'; +import Btn from '../Btn'; +import SearchIcon from '@material-ui/icons/Search'; +import AddIcon from '@material-ui/icons/Add'; +import { ChangeEvent, FormEvent, useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { + OrderStatusItemModel, + StoreModel, + UsersItemModel, +} from '../../models/storeModel'; +import './OrdersSearchPanel.scss'; +import { Stack } from '@mui/material'; +import { getUsers } from '../../store/actions/usersPageActions'; +import ReactInputMask from 'react-input-mask'; + +export interface OrdersSearchPanelProps { + label?: string; + searchField: string; + addFunction: () => void; + onSearch: () => void; + handleChangeSearch: (event: ChangeEvent) => void; +} + +export const OrdersSearchPanel = ({ + label = 'Введите параметры поиска', + searchField, + onSearch, + handleChangeSearch, + addFunction, +}: OrdersSearchPanelProps) => { + const [openFilter, setOpenFilter] = useState(false); + const dispatch = useDispatch(); + const userRoleCode = useSelector( + (store: StoreModel) => store.userStore.authResponse.roleCode + ); + const serviceManList = useSelector( + (store: StoreModel) => store.usersStore.usersList + ); + const statuses = useSelector( + (store: StoreModel) => store.dictsStore.dictOrderStatuses.statuses + ); + const [selectedFilters, setSelectedFilters] = useState<{ + users: UsersItemModel[]; + statuses: OrderStatusItemModel[]; + fromDate: string; + toDate: string; + }>({ + users: [], + statuses: [], + fromDate: '', + toDate: '', + }); + + useEffect(() => { + dispatch(getUsers(0, 50, undefined, '', 'SERVICE_MAN')); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const onSubmit = (event: FormEvent) => { + event.preventDefault(); + + onSearch(); + }; + + const changeFilter = () => { + setOpenFilter(!openFilter); + }; + + const onSelect = + (key: keyof typeof selectedFilters) => + ( + event: ChangeEvent<{ + name?: string | undefined; + value: unknown; + }> + ) => { + setSelectedFilters((prev) => { + return { + ...prev, + [key]: event.target.value, + }; + }); + }; + + return ( +
+ + + + Поиск + + + + + {(userRoleCode === 'SUPER_ADMIN' || userRoleCode === 'ADMIN') && ( + + + Добавить + + )} + + + + Расширенный поиск + + + + +
+ + + selectedFilters.users.map((user) => user.fullName).join(', '), + }} + fullWidth + > + {serviceManList.map((user) => ( + + {user.fullName} + + ))} + + + + + selectedFilters.statuses + .map((status) => status.name) + .join(', '), + }} + fullWidth + > + {statuses.map((status) => ( + + {status.name} + + ))} + + + + + + + + + + + + +
+
+
+ ); +}; diff --git a/frontend/src/components/OrdersSearchPanel/index.ts b/frontend/src/components/OrdersSearchPanel/index.ts new file mode 100644 index 0000000..4260ba1 --- /dev/null +++ b/frontend/src/components/OrdersSearchPanel/index.ts @@ -0,0 +1 @@ +export { OrdersSearchPanel } from './OrdersSearchPanel'; diff --git a/frontend/src/components/UpdateCustomerModal/UpdateCustomerModal.tsx b/frontend/src/components/UpdateCustomerModal/UpdateCustomerModal.tsx index b61b81c..03d80e4 100644 --- a/frontend/src/components/UpdateCustomerModal/UpdateCustomerModal.tsx +++ b/frontend/src/components/UpdateCustomerModal/UpdateCustomerModal.tsx @@ -301,10 +301,10 @@ export default function UpdateCustomerModal({ /> - handleChangeModal()}> + handleChangeModal()}> Отмена - + Сохранить diff --git a/frontend/src/components/modals/CreateBoilerModal/CreateBoilerModal.tsx b/frontend/src/components/modals/CreateBoilerModal/CreateBoilerModal.tsx index 1e6b123..5171a97 100644 --- a/frontend/src/components/modals/CreateBoilerModal/CreateBoilerModal.tsx +++ b/frontend/src/components/modals/CreateBoilerModal/CreateBoilerModal.tsx @@ -71,7 +71,7 @@ const CreateBoilerModal = () => { return ( <> - + Добавить @@ -161,10 +161,10 @@ const CreateBoilerModal = () => { /> - + Отмена - + Добавить diff --git a/frontend/src/components/modals/CreateCustomerModal/CreateCustomerModal.tsx b/frontend/src/components/modals/CreateCustomerModal/CreateCustomerModal.tsx index 7e97e65..c53ae66 100644 --- a/frontend/src/components/modals/CreateCustomerModal/CreateCustomerModal.tsx +++ b/frontend/src/components/modals/CreateCustomerModal/CreateCustomerModal.tsx @@ -150,7 +150,7 @@ const CreateCustomerModal = ({ btnTitle }: CreateCustomerModalProps) => { return ( <> - + {btnTitle || 'Добавить'} @@ -256,10 +256,10 @@ const CreateCustomerModal = ({ btnTitle }: CreateCustomerModalProps) => { /> - + Отмена - + Добавить diff --git a/frontend/src/components/modals/CreateJobTypeModal/CreateJobTypeModal.tsx b/frontend/src/components/modals/CreateJobTypeModal/CreateJobTypeModal.tsx index 65ba754..3b631ed 100644 --- a/frontend/src/components/modals/CreateJobTypeModal/CreateJobTypeModal.tsx +++ b/frontend/src/components/modals/CreateJobTypeModal/CreateJobTypeModal.tsx @@ -70,7 +70,7 @@ const CreateJobTypeModal = () => { return ( <> - + Добавить @@ -150,10 +150,10 @@ const CreateJobTypeModal = () => { /> - + Отмена - + Добавить diff --git a/frontend/src/components/modals/CreateOrderStatusModal/CreateOrderStatusModal.tsx b/frontend/src/components/modals/CreateOrderStatusModal/CreateOrderStatusModal.tsx index fef2152..c6aaf8e 100644 --- a/frontend/src/components/modals/CreateOrderStatusModal/CreateOrderStatusModal.tsx +++ b/frontend/src/components/modals/CreateOrderStatusModal/CreateOrderStatusModal.tsx @@ -76,7 +76,7 @@ const CreateOrderStatusModal = () => { return ( <> - + Добавить @@ -109,10 +109,10 @@ const CreateOrderStatusModal = () => { /> - + Отмена - + Добавить diff --git a/frontend/src/components/modals/CreatePartModal/CreatePartModal.tsx b/frontend/src/components/modals/CreatePartModal/CreatePartModal.tsx index 8560c72..3f98bb4 100644 --- a/frontend/src/components/modals/CreatePartModal/CreatePartModal.tsx +++ b/frontend/src/components/modals/CreatePartModal/CreatePartModal.tsx @@ -71,7 +71,7 @@ const CreatePartModal = () => { return ( <> - + Добавить @@ -161,10 +161,10 @@ const CreatePartModal = () => { /> - + Отмена - + Добавить diff --git a/frontend/src/components/modals/CreateRoleModal/CreateRoleModal.tsx b/frontend/src/components/modals/CreateRoleModal/CreateRoleModal.tsx index f02541c..6a3c3f5 100644 --- a/frontend/src/components/modals/CreateRoleModal/CreateRoleModal.tsx +++ b/frontend/src/components/modals/CreateRoleModal/CreateRoleModal.tsx @@ -76,7 +76,7 @@ const CreateRoleModal = () => { return ( <> - + Добавить @@ -109,10 +109,10 @@ const CreateRoleModal = () => { /> - + Отмена - + Добавить diff --git a/frontend/src/components/modals/CreateUserModal/CreateUserModal.tsx b/frontend/src/components/modals/CreateUserModal/CreateUserModal.tsx index 38ac167..7307dc7 100644 --- a/frontend/src/components/modals/CreateUserModal/CreateUserModal.tsx +++ b/frontend/src/components/modals/CreateUserModal/CreateUserModal.tsx @@ -66,7 +66,7 @@ const CreateUserModal = ({ btnTitle }: CreateUserModalProps) => { return ( <> - + {btnTitle || 'Добавить'} @@ -202,10 +202,10 @@ const CreateUserModal = ({ btnTitle }: CreateUserModalProps) => { - + Отмена - + Добавить diff --git a/frontend/src/pages/Customers/Customers.tsx b/frontend/src/pages/Customers/Customers.tsx index 9e54671..71d0c5b 100644 --- a/frontend/src/pages/Customers/Customers.tsx +++ b/frontend/src/pages/Customers/Customers.tsx @@ -28,6 +28,7 @@ import history from '../../utils/history'; import { SET_ORDER_DATA } from '../../store/storeConstants/ordersConstants'; import TableSort from '../../components/TableSort'; import UpdateCustomerModal from '../../components/UpdateCustomerModal'; +import { Stack } from '@mui/material'; const Customers = () => { const dispatch = useDispatch(); @@ -171,7 +172,7 @@ const Customers = () => { return ( <>
- + Поиск @@ -283,24 +284,26 @@ const Customers = () => { {formatDate(customer.updatedDate || '', true)} {customer.comment} - {(userRoleCode === 'SUPER_ADMIN' || - userRoleCode === 'ADMIN') && ( - - + + {(userRoleCode === 'SUPER_ADMIN' || + userRoleCode === 'ADMIN') && ( + + - createOrder(customer)} - > - - - - )} + createOrder(customer)} + > + + + + )} + ))} diff --git a/frontend/src/pages/EditUser/EditUser.tsx b/frontend/src/pages/EditUser/EditUser.tsx index f669dd7..46f97c4 100644 --- a/frontend/src/pages/EditUser/EditUser.tsx +++ b/frontend/src/pages/EditUser/EditUser.tsx @@ -189,10 +189,10 @@ const EditUser = () => { - + Назад - + Сохранить diff --git a/frontend/src/pages/PaidOuts/PaidOuts.tsx b/frontend/src/pages/PaidOuts/PaidOuts.tsx index cd3be16..8feff9d 100644 --- a/frontend/src/pages/PaidOuts/PaidOuts.tsx +++ b/frontend/src/pages/PaidOuts/PaidOuts.tsx @@ -29,6 +29,7 @@ import { formatSum } from '../../utils/formatSum'; import api from '../../utils/axiosMiddleware'; import { ADD_NOTIFY } from '../../store/storeConstants/snackbarConstants'; import { setLoader } from '../../store/actions/mainActions'; +import { Stack } from '@mui/material'; const PaidOuts = () => { const dispatch = useDispatch(); @@ -170,7 +171,7 @@ const PaidOuts = () => { return ( <>
- + Поиск @@ -216,23 +217,25 @@ const PaidOuts = () => { : 'Не готова к переводу'} - viewOrder(paidOut.orderId)} - > - - - {(userRoleCode === 'ADMIN' || - userRoleCode === 'SUPER_ADMIN') && - paidOut.canBePaid && - !paidOut.isPaid && ( - initPay(paidOut)} - > - - - )} + + viewOrder(paidOut.orderId)} + > + + + {(userRoleCode === 'ADMIN' || + userRoleCode === 'SUPER_ADMIN') && + paidOut.canBePaid && + !paidOut.isPaid && ( + initPay(paidOut)} + > + + + )} + ))} @@ -261,10 +264,10 @@ const PaidOuts = () => { paidModal.paidOut?.sum || 0 )} на общий счет ${paidModal.paidOut?.fullName} ?`} - + Отмена - + Перевести diff --git a/frontend/src/pages/SignIn/SignIn.tsx b/frontend/src/pages/SignIn/SignIn.tsx index deb652c..d3fbb31 100644 --- a/frontend/src/pages/SignIn/SignIn.tsx +++ b/frontend/src/pages/SignIn/SignIn.tsx @@ -52,7 +52,7 @@ export default function SignIn() { value={fields.password} /> - + Войти diff --git a/frontend/src/pages/Users/Users.scss b/frontend/src/pages/Users/Users.scss index 64d8bfd..ad14680 100644 --- a/frontend/src/pages/Users/Users.scss +++ b/frontend/src/pages/Users/Users.scss @@ -1,22 +1,3 @@ -.search-row { - display: flex; - flex-direction: column; - flex-wrap: wrap; - align-items: center; - width: 100%; - margin-bottom: 20px; - - * { - width: 100%; - } - - .MuiInputBase-root { - flex-grow: 1; - margin: 16px 0; - // background: var(--white-color); - } -} - .MuiTable-root { .MuiTableHead-root { .MuiTableCell-root { @@ -24,18 +5,3 @@ } } } - -@media (min-width: 600px) { - .search-row { - flex-direction: row; - flex-wrap: nowrap; - - * { - width: auto; - } - - .MuiInputBase-root { - margin: 0 16px; - } - } -} diff --git a/frontend/src/pages/Users/Users.tsx b/frontend/src/pages/Users/Users.tsx index 01b4569..fa18dd8 100644 --- a/frontend/src/pages/Users/Users.tsx +++ b/frontend/src/pages/Users/Users.tsx @@ -21,6 +21,7 @@ import React, { useEffect, useState } from 'react'; import CreateUserModal from '../../components/modals/CreateUserModal'; import history from '../../utils/history'; import TableSort from '../../components/TableSort'; +import { Stack } from '@mui/material'; const Users = () => { const dispatch = useDispatch(); @@ -115,7 +116,7 @@ const Users = () => { return ( <>
- + Поиск @@ -200,17 +201,19 @@ const Users = () => { {formatDate(user.updatedDate || '', true)} - {(userRoleCode === 'SUPER_ADMIN' || - userRoleCode === 'ADMIN') && ( - - editUser(user.id || index)} - > - - - - )} + + {(userRoleCode === 'SUPER_ADMIN' || + userRoleCode === 'ADMIN') && ( + + editUser(user.id || index)} + > + + + + )} + ))} diff --git a/frontend/src/pages/administration/Cash/Cash.scss b/frontend/src/pages/administration/Cash/Cash.scss index 32e7233..507b78d 100644 --- a/frontend/src/pages/administration/Cash/Cash.scss +++ b/frontend/src/pages/administration/Cash/Cash.scss @@ -1,16 +1,3 @@ .input { width: 100%; } - -.MuiTable-root { - .MuiTableBody-root { - .MuiTableRow-root { - .MuiTableCell-root { - &:last-child { - display: flex; - align-items: center; - } - } - } - } -} diff --git a/frontend/src/pages/administration/Cash/Cash.tsx b/frontend/src/pages/administration/Cash/Cash.tsx index 16d3f95..7edbd0a 100644 --- a/frontend/src/pages/administration/Cash/Cash.tsx +++ b/frontend/src/pages/administration/Cash/Cash.tsx @@ -218,7 +218,7 @@ const Cash = () => { return ( <>
- + Поиск @@ -364,13 +364,13 @@ const Cash = () => { handleChangeModal(undefined)} > Отмена @@ -393,12 +393,12 @@ const Cash = () => { handleChangeResetModal(undefined)} > Отмена - + Обнулить diff --git a/frontend/src/pages/administration/DictBoilers/DictBoilers.tsx b/frontend/src/pages/administration/DictBoilers/DictBoilers.tsx index 08f35bc..b8fffe6 100644 --- a/frontend/src/pages/administration/DictBoilers/DictBoilers.tsx +++ b/frontend/src/pages/administration/DictBoilers/DictBoilers.tsx @@ -27,6 +27,7 @@ import Transition from '../../../components/Transition'; import Btn from '../../../components/Btn'; import { ADD_NOTIFY } from '../../../store/storeConstants/snackbarConstants'; import api from '../../../utils/axiosMiddleware'; +import { Stack } from '@mui/material'; const DictBoilers = () => { const dispatch = useDispatch(); @@ -173,17 +174,19 @@ const DictBoilers = () => { {formatDate(boiler.updatedDate || '', true)} - {(userRoleCode === 'SUPER_ADMIN' || - userRoleCode === 'ADMIN') && ( - - selectBoiler(boiler)} - > - - - - )} + + {(userRoleCode === 'SUPER_ADMIN' || + userRoleCode === 'ADMIN') && ( + + selectBoiler(boiler)} + > + + + + )} + ))} @@ -299,10 +302,10 @@ const DictBoilers = () => { /> - + Отмена - + Сохранить diff --git a/frontend/src/pages/administration/DictJobTypes/DictJobTypes.tsx b/frontend/src/pages/administration/DictJobTypes/DictJobTypes.tsx index c4ec9b5..062c80d 100644 --- a/frontend/src/pages/administration/DictJobTypes/DictJobTypes.tsx +++ b/frontend/src/pages/administration/DictJobTypes/DictJobTypes.tsx @@ -27,6 +27,7 @@ import { formatDate } from '../../../utils/formatDate'; import EditIcon from '@material-ui/icons/Edit'; import api from '../../../utils/axiosMiddleware'; import { ADD_NOTIFY } from '../../../store/storeConstants/snackbarConstants'; +import { Stack } from '@mui/material'; const DictBoilers = () => { const dispatch = useDispatch(); @@ -174,17 +175,19 @@ const DictBoilers = () => { ))} {job.daysOfGuarantee} {formatDate(job.updatedDate || '', true)} - {(userRoleCode === 'SUPER_ADMIN' || - userRoleCode === 'ADMIN') && ( - - selectJob(job)} - > - - - - )} + + {(userRoleCode === 'SUPER_ADMIN' || + userRoleCode === 'ADMIN') && ( + + selectJob(job)} + > + + + + )} + ))} @@ -267,10 +270,10 @@ const DictBoilers = () => { /> - + Отмена - + Сохранить diff --git a/frontend/src/pages/administration/DictParts/DictParts.tsx b/frontend/src/pages/administration/DictParts/DictParts.tsx index 8810485..bc202e1 100644 --- a/frontend/src/pages/administration/DictParts/DictParts.tsx +++ b/frontend/src/pages/administration/DictParts/DictParts.tsx @@ -27,6 +27,7 @@ import Btn from '../../../components/Btn'; import { ADD_NOTIFY } from '../../../store/storeConstants/snackbarConstants'; import api from '../../../utils/axiosMiddleware'; import CreatePartModal from '../../../components/modals/CreatePartModal'; +import { Stack } from '@mui/material'; const DictParts = () => { const dispatch = useDispatch(); @@ -178,17 +179,19 @@ const DictParts = () => { {formatDate(part.updatedDate || '', true)} - {(userRoleCode === 'SUPER_ADMIN' || - userRoleCode === 'ADMIN') && ( - - selectPart(part)} - > - - - - )} + + {(userRoleCode === 'SUPER_ADMIN' || + userRoleCode === 'ADMIN') && ( + + selectPart(part)} + > + + + + )} + ))} @@ -280,10 +283,10 @@ const DictParts = () => { /> - + Отмена - + Сохранить diff --git a/frontend/src/pages/administration/Settings/Settings.tsx b/frontend/src/pages/administration/Settings/Settings.tsx index 64787f9..68e3779 100644 --- a/frontend/src/pages/administration/Settings/Settings.tsx +++ b/frontend/src/pages/administration/Settings/Settings.tsx @@ -9,6 +9,7 @@ import { getSettings, saveSettings, } from '../../../store/actions/settingsActions'; +import { ADD_NOTIFY } from '../../../store/storeConstants/snackbarConstants'; const Settings = () => { const dispatch = useDispatch(); @@ -31,6 +32,13 @@ const Settings = () => { const save = async () => { await dispatch(saveSettings(settings)); + dispatch({ + type: ADD_NOTIFY, + payload: { + message: 'Настройки успешно сохранены', + type: 'success', + }, + }); await dispatch(getSettings()); }; @@ -57,7 +65,7 @@ const Settings = () => {
))} - + Сохранить diff --git a/frontend/src/pages/orders/CreateOrder/CreateOrder.tsx b/frontend/src/pages/orders/CreateOrder/CreateOrder.tsx index 9c19057..79ad19b 100644 --- a/frontend/src/pages/orders/CreateOrder/CreateOrder.tsx +++ b/frontend/src/pages/orders/CreateOrder/CreateOrder.tsx @@ -431,7 +431,7 @@ const CreateOrder = () => { changeModal(getParts, 'Выберите запчасть', 'parts') } @@ -497,7 +497,7 @@ const CreateOrder = () => { changeModal(getJobTypes, 'Выберите вид работы', 'jobTypes') } @@ -597,10 +597,10 @@ const CreateOrder = () => { - + Назад - + Сохранить diff --git a/frontend/src/pages/orders/OrderEdit/OrderEdit.tsx b/frontend/src/pages/orders/OrderEdit/OrderEdit.tsx index acc562b..727a331 100644 --- a/frontend/src/pages/orders/OrderEdit/OrderEdit.tsx +++ b/frontend/src/pages/orders/OrderEdit/OrderEdit.tsx @@ -425,7 +425,7 @@ const OrderEdit = () => { changeModal(getParts, 'Выберите запчасть', 'parts') } @@ -489,7 +489,7 @@ const OrderEdit = () => { changeModal(getJobTypes, 'Выберите вид работы', 'jobTypes') } @@ -591,10 +591,10 @@ const OrderEdit = () => { - + Назад - + Сохранить diff --git a/frontend/src/pages/orders/OrderView/OrderView.tsx b/frontend/src/pages/orders/OrderView/OrderView.tsx index 78239c1..75c84a0 100644 --- a/frontend/src/pages/orders/OrderView/OrderView.tsx +++ b/frontend/src/pages/orders/OrderView/OrderView.tsx @@ -463,7 +463,7 @@ const OrderView = () => { {actions.map((action, index) => ( onSelectAction(action)} > {action.action} @@ -523,10 +523,10 @@ const OrderView = () => { /> - + Отмена - + {action.action} diff --git a/frontend/src/pages/orders/OrdersList/OrdersList.tsx b/frontend/src/pages/orders/OrdersList/OrdersList.tsx index 65e4e6d..fc57613 100644 --- a/frontend/src/pages/orders/OrdersList/OrdersList.tsx +++ b/frontend/src/pages/orders/OrdersList/OrdersList.tsx @@ -1,6 +1,5 @@ import { IconButton, - InputBase, Paper, Table, TableBody, @@ -12,14 +11,11 @@ import { } from '@material-ui/core'; import { useDispatch, useSelector } from 'react-redux'; import { StoreModel } from '../../../models/storeModel'; -import SearchIcon from '@material-ui/icons/Search'; import EditIcon from '@material-ui/icons/Edit'; import VisibilityIcon from '@material-ui/icons/Visibility'; -import Btn from '../../../components/Btn'; import { formatDate } from '../../../utils/formatDate'; import React, { useEffect } from 'react'; import { getOrders } from '../../../store/actions/ordersActions'; -import AddIcon from '@material-ui/icons/Add'; import history from '../../../utils/history'; import { OrderItemModel } from '../../../models/orderModel'; import { @@ -28,6 +24,8 @@ import { SET_ORDERS_SORT, } from '../../../store/storeConstants/ordersConstants'; import TableSort from '../../../components/TableSort'; +import { OrdersSearchPanel } from '../../../components/OrdersSearchPanel'; +import { Stack } from '@mui/material'; const OrdersList = () => { const dispatch = useDispatch(); @@ -135,26 +133,13 @@ const OrdersList = () => { return ( <> -
- - - Поиск - - - - - {(userRoleCode === 'SUPER_ADMIN' || userRoleCode === 'ADMIN') && ( - - - Добавить - - )} -
+ @@ -234,24 +219,26 @@ const OrdersList = () => { {order.statusName}{order.comment} - viewOrder(order)} - > - - + + viewOrder(order)} + > + + - {(userRoleCode === 'SUPER_ADMIN' || - userRoleCode === 'ADMIN') && - order.statusCode !== 'DONE' && - order.statusCode !== 'CANCELED' && ( - editOrder(order)} - > - - - )} + {(userRoleCode === 'SUPER_ADMIN' || + userRoleCode === 'ADMIN') && + order.statusCode !== 'DONE' && + order.statusCode !== 'CANCELED' && ( + editOrder(order)} + > + + + )} + ))} From c983de6f80287aa32566e192ff54eaf4edab3da6 Mon Sep 17 00:00:00 2001 From: nadeocfg Date: Sun, 5 Nov 2023 21:12:34 +0600 Subject: [PATCH 2/2] feat: add filter params to orders.controller --- backend/controllers/orders.controller.ts | 219 +++++++++++++----- frontend/src/components/Btn/Btn.scss | 14 +- .../OrdersSearchPanel/OrdersSearchPanel.scss | 10 +- .../OrdersSearchPanel/OrdersSearchPanel.tsx | 134 +++++------ .../pages/orders/OrdersList/OrdersList.tsx | 90 ++++--- frontend/src/store/actions/ordersActions.ts | 22 +- queries.sql | 108 ++++++++- 7 files changed, 423 insertions(+), 174 deletions(-) diff --git a/backend/controllers/orders.controller.ts b/backend/controllers/orders.controller.ts index 843c793..a58ae12 100644 --- a/backend/controllers/orders.controller.ts +++ b/backend/controllers/orders.controller.ts @@ -755,11 +755,45 @@ const getOrders = async ( next: NextFunction ) => { try { - const { page, count, searchValue, sort = 'id,desc' } = request.query; + const { + page, + count, + searchValue, + users, + statuses, + fromDate, + toDate, + sort = 'id,desc', + } = request.query; + const sortBy = (sort).split(',')[0]; const order = (sort).split(',')[1]; const roleCode = request.user?.roleCode || ''; const userId = request.user?.id || ''; + let formattedFromDate = fromDate; + let formattedToDate = toDate; + const formattedUsers = format( + '%L', + (users as string).split(',').map(Number) + ); + const formattedStatuses = format( + '%L', + (statuses as string).split(',').map(Number) + ); + + if (formattedFromDate) { + const fromArr = ((fromDate ?? '') as string).split('-'); + formattedFromDate = `${fromArr[2] ?? '2000'}-${fromArr[1] ?? '01'}-${ + fromArr[0] ?? '01' + }`; + } + + if (formattedToDate) { + const toArr = ((toDate ?? '') as string).split('-'); + formattedToDate = `${toArr[2] ?? '3000'}-${toArr[1] ?? '01'}-${ + toArr[0] ?? '01' + }`; + } let offset = 0; @@ -775,61 +809,76 @@ const getOrders = async ( let total = null; if (roleCode === 'ADMIN' || roleCode === 'SUPER_ADMIN') { - const getAllOrders = await db.query( - ` - SELECT - orders.id, - orders.address, - orders."createdDate", - orders."updatedDate", - orders.comment, - orders."customerId", - orders."serviceManId", - orders."createdBy", - orders."phone", - status.name as "statusName", - status.code as "statusCode", - customers."fullName", - customers."boilerSerial", - users."fullName" as "serviceManFullName", - boilers.name as "boilerName" - FROM - "${process.env.DB_NAME}"."orders" as orders - LEFT JOIN - "${process.env.DB_NAME}"."dictOrderStatuses" as status - ON - orders.status = status.id - LEFT JOIN - "${process.env.DB_NAME}"."customers" as customers - ON - orders."customerId" = customers.id - LEFT JOIN - "${process.env.DB_NAME}"."users" as users - ON - orders."serviceManId" = users.id - LEFT JOIN - "${process.env.DB_NAME}"."dictBoilers" as boilers - ON - customers."boilerId" = boilers.id - WHERE - orders."isActive" = true AND - (LOWER(customers."fullName") LIKE $3 OR - orders.id::text LIKE $3 OR - LOWER(orders.address) LIKE $3 OR - LOWER(users."fullName") LIKE $3 OR - LOWER(customers."boilerSerial") LIKE $3 OR - LOWER(boilers.name) LIKE $3 OR - LOWER(status.name) LIKE $3 OR - LOWER(orders.comment) LIKE $3) - ORDER BY - ${format('%I', sortBy)} ${format('%s', order)} - LIMIT - $1 - OFFSET - $2; - `, - [count, offset, `%${searchValue}%`.toLowerCase()] - ); + const query = ` + SELECT + orders.id, + orders.address, + orders."createdDate", + orders."updatedDate", + orders.comment, + orders."customerId", + orders."serviceManId", + orders."createdBy", + orders."phone", + status.name as "statusName", + status.code as "statusCode", + customers."fullName", + customers."boilerSerial", + users."fullName" as "serviceManFullName", + boilers.name as "boilerName" + FROM + "${process.env.DB_NAME}"."orders" as orders + LEFT JOIN + "${process.env.DB_NAME}"."dictOrderStatuses" as status + ON + orders.status = status.id + LEFT JOIN + "${process.env.DB_NAME}"."customers" as customers + ON + orders."customerId" = customers.id + LEFT JOIN + "${process.env.DB_NAME}"."users" as users + ON + orders."serviceManId" = users.id + LEFT JOIN + "${process.env.DB_NAME}"."dictBoilers" as boilers + ON + customers."boilerId" = boilers.id + WHERE + orders."isActive" = true AND + (LOWER(customers."fullName") LIKE $3 OR + orders.id::text LIKE $3 OR + LOWER(orders.address) LIKE $3 OR + LOWER(users."fullName") LIKE $3 OR + LOWER(customers."boilerSerial") LIKE $3 OR + LOWER(boilers.name) LIKE $3 OR + LOWER(status.name) LIKE $3 OR + LOWER(orders.comment) LIKE $3) + ${users ? `AND orders."serviceManId" IN (${formattedUsers})` : ''} + ${statuses ? `AND orders."status" IN (${formattedStatuses})` : ''} + ${ + fromDate + ? `AND orders."createdDate" > ${format('%L', formattedFromDate)}` + : '' + } + ${ + toDate + ? `AND orders."createdDate" < ${format('%L', formattedToDate)}` + : '' + } + ORDER BY + ${format('%I', sortBy)} ${format('%s', order)} + LIMIT + $1 + OFFSET + $2; + `; + + const getAllOrders = await db.query(query, [ + count, + offset, + `%${((searchValue as string) ?? '').toLowerCase()}%`, + ]); total = await db.query( ` @@ -861,9 +910,24 @@ const getOrders = async ( LOWER(users."fullName") LIKE $1 OR LOWER(boilers.name) LIKE $1 OR LOWER(status.name) LIKE $1 OR - LOWER(orders.comment) LIKE $1); + LOWER(orders.comment) LIKE $1) + ${users ? `AND orders."serviceManId" IN (${formattedUsers})` : ''} + ${statuses ? `AND orders."status" IN (${formattedStatuses})` : ''} + ${ + fromDate + ? `AND orders."createdDate" > ${format( + '%L', + formattedFromDate + )}` + : '' + } + ${ + toDate + ? `AND orders."createdDate" < ${format('%L', formattedToDate)}` + : '' + } `, - [`%${searchValue}%`.toLowerCase()] + [`%${((searchValue as string) ?? '').toLowerCase()}%`] ); orders = getAllOrders.rows; @@ -915,6 +979,20 @@ const getOrders = async ( LOWER(boilers.name) LIKE $4 OR LOWER(status.name) LIKE $4 OR LOWER(orders.comment) LIKE $4) + ${statuses ? `AND orders."status" IN (${formattedStatuses})` : ''} + ${ + fromDate + ? `AND orders."createdDate" > ${format( + '%L', + formattedFromDate + )}` + : '' + } + ${ + toDate + ? `AND orders."createdDate" < ${format('%L', formattedToDate)}` + : '' + } ORDER BY ${format('%I', sortBy)} ${format('%s', order)} LIMIT @@ -922,7 +1000,12 @@ const getOrders = async ( OFFSET $2; `, - [count, offset, userId, `%${searchValue}%`.toLowerCase()] + [ + count, + offset, + userId, + `%${((searchValue as string) ?? '').toLowerCase()}%`, + ] ); total = await db.query( @@ -956,9 +1039,23 @@ const getOrders = async ( LOWER(users."fullName") LIKE $2 OR LOWER(boilers.name) LIKE $2 OR LOWER(status.name) LIKE $2 OR - LOWER(orders.comment) LIKE $2); + LOWER(orders.comment) LIKE $2) + ${statuses ? `AND orders."status" IN (${formattedStatuses})` : ''} + ${ + fromDate + ? `AND orders."createdDate" > ${format( + '%L', + formattedFromDate + )}` + : '' + } + ${ + toDate + ? `AND orders."createdDate" < ${format('%L', formattedToDate)}` + : '' + } `, - [userId, `%${searchValue}%`.toLowerCase()] + [userId, `%${((searchValue as string) ?? '').toLowerCase()}%`] ); orders = getUserOrders.rows; diff --git a/frontend/src/components/Btn/Btn.scss b/frontend/src/components/Btn/Btn.scss index bf77cee..78e792b 100644 --- a/frontend/src/components/Btn/Btn.scss +++ b/frontend/src/components/Btn/Btn.scss @@ -35,7 +35,19 @@ background: transparent; color: var(--primary-color); text-transform: none; - text-decoration: underline; + // border-bottom: 1px solid var(--primary-color); + border-radius: 0; + + &.active { + .MuiButton-label svg.MuiSvgIcon-root { + transform: rotate(180deg); + } + } + + .MuiButton-label svg.MuiSvgIcon-root { + margin-right: 0; + transition: all 300ms ease; + } &:hover { background: transparent; diff --git a/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss index cb74875..489e17d 100644 --- a/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss +++ b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.scss @@ -10,7 +10,15 @@ padding: 16px 0; &__item { - flex-basis: 40%; + flex-basis: 100%; flex-grow: 1; } } + +@media (min-width: 600px) { + .filter { + &__item { + flex-basis: 40%; + } + } +} diff --git a/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx index ea227ec..3f1fedf 100644 --- a/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx +++ b/frontend/src/components/OrdersSearchPanel/OrdersSearchPanel.tsx @@ -20,6 +20,7 @@ import './OrdersSearchPanel.scss'; import { Stack } from '@mui/material'; import { getUsers } from '../../store/actions/usersPageActions'; import ReactInputMask from 'react-input-mask'; +import { ArrowDownward } from '@material-ui/icons'; export interface OrdersSearchPanelProps { label?: string; @@ -27,6 +28,20 @@ export interface OrdersSearchPanelProps { addFunction: () => void; onSearch: () => void; handleChangeSearch: (event: ChangeEvent) => void; + selectedFilters: FilterProps; + onSelect: (key: keyof FilterProps) => ( + event: ChangeEvent<{ + name?: string | undefined; + value: unknown; + }> + ) => void; +} + +export interface FilterProps { + users: UsersItemModel[]; + statuses: OrderStatusItemModel[]; + fromDate: string; + toDate: string; } export const OrdersSearchPanel = ({ @@ -35,6 +50,8 @@ export const OrdersSearchPanel = ({ onSearch, handleChangeSearch, addFunction, + selectedFilters, + onSelect, }: OrdersSearchPanelProps) => { const [openFilter, setOpenFilter] = useState(false); const dispatch = useDispatch(); @@ -47,17 +64,9 @@ export const OrdersSearchPanel = ({ const statuses = useSelector( (store: StoreModel) => store.dictsStore.dictOrderStatuses.statuses ); - const [selectedFilters, setSelectedFilters] = useState<{ - users: UsersItemModel[]; - statuses: OrderStatusItemModel[]; - fromDate: string; - toDate: string; - }>({ - users: [], - statuses: [], - fromDate: '', - toDate: '', - }); + const userRole = useSelector( + (store: StoreModel) => store.userStore.authResponse.roleCode + ); useEffect(() => { dispatch(getUsers(0, 50, undefined, '', 'SERVICE_MAN')); @@ -75,22 +84,6 @@ export const OrdersSearchPanel = ({ setOpenFilter(!openFilter); }; - const onSelect = - (key: keyof typeof selectedFilters) => - ( - event: ChangeEvent<{ - name?: string | undefined; - value: unknown; - }> - ) => { - setSelectedFilters((prev) => { - return { - ...prev, - [key]: event.target.value, - }; - }); - }; - return (
@@ -117,35 +110,62 @@ export const OrdersSearchPanel = ({ direction={'row'} sx={{ justifyContent: { xs: 'center', sm: 'flex-end' } }} > - + Расширенный поиск +
+ {(userRole === 'ADMIN' || userRole === 'SUPER_ADMIN') && ( + + + selectedFilters.users + .map((user) => user.fullName) + .join(', '), + }} + fullWidth + > + {serviceManList.map((user) => ( + + {user.fullName} + + ))} + + + )} - - selectedFilters.users.map((user) => user.fullName).join(', '), - }} - fullWidth + - {serviceManList.map((user) => ( - - {user.fullName} - - ))} - + + + + + + + - - - - - - - - - -
diff --git a/frontend/src/pages/orders/OrdersList/OrdersList.tsx b/frontend/src/pages/orders/OrdersList/OrdersList.tsx index fc57613..32ce35a 100644 --- a/frontend/src/pages/orders/OrdersList/OrdersList.tsx +++ b/frontend/src/pages/orders/OrdersList/OrdersList.tsx @@ -14,7 +14,7 @@ import { StoreModel } from '../../../models/storeModel'; import EditIcon from '@material-ui/icons/Edit'; import VisibilityIcon from '@material-ui/icons/Visibility'; import { formatDate } from '../../../utils/formatDate'; -import React, { useEffect } from 'react'; +import React, { ChangeEvent, useEffect, useState } from 'react'; import { getOrders } from '../../../store/actions/ordersActions'; import history from '../../../utils/history'; import { OrderItemModel } from '../../../models/orderModel'; @@ -26,6 +26,7 @@ import { import TableSort from '../../../components/TableSort'; import { OrdersSearchPanel } from '../../../components/OrdersSearchPanel'; import { Stack } from '@mui/material'; +import { FilterProps } from '../../../components/OrdersSearchPanel/OrdersSearchPanel'; const OrdersList = () => { const dispatch = useDispatch(); @@ -42,19 +43,26 @@ const OrdersList = () => { (store: StoreModel) => store.ordersStore.pagination ); const sort = useSelector((store: StoreModel) => store.ordersStore.sort); + const [selectedFilters, setSelectedFilters] = useState({ + users: [], + statuses: [], + fromDate: '', + toDate: '', + }); useEffect(() => { - dispatch( - getOrders( - pagination.currentPage, - pagination.rowsPerPage, - searchField, - sort - ) - ); + if (history.location.search) { + dispatch(getOrders(history.location.search)); + } // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [history.location.search]); + + useEffect(() => { + applyFilters(); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [pagination.currentPage, pagination.rowsPerPage, sort.name, sort.order]); const handleSearchChange = (event: React.ChangeEvent) => { dispatch({ @@ -63,15 +71,26 @@ const OrdersList = () => { }); }; - const handleSearch = () => { - dispatch( - getOrders( - pagination.currentPage, - pagination.rowsPerPage, - searchField, - sort - ) - ); + const applyFilters = () => { + const users = selectedFilters.users.map((user) => user.id).join(','); + const statuses = selectedFilters.statuses + .map((status) => status.id) + .join(','); + + const searchParams = new URLSearchParams({ + users, + statuses, + fromDate: selectedFilters.fromDate, + toDate: selectedFilters.toDate, + sort: `${sort.name},${sort.order}`, + searchField, + page: String(pagination.currentPage), + count: String(pagination.rowsPerPage), + }).toString(); + + history.replace({ + search: searchParams, + }); }; const handleChangeRowsPerPage = ( @@ -84,10 +103,6 @@ const OrdersList = () => { value: +event.target.value, }, }); - - dispatch( - getOrders(pagination.currentPage, +event.target.value, searchField, sort) - ); }; const handleChangePage = (event: any, page: number) => { @@ -98,8 +113,6 @@ const OrdersList = () => { value: page, }, }); - - dispatch(getOrders(page, pagination.rowsPerPage, searchField, sort)); }; const createOrderNav = () => { @@ -122,15 +135,24 @@ const OrdersList = () => { name: property, }, }); - - dispatch( - getOrders(pagination.currentPage, pagination.rowsPerPage, searchField, { - order: sort.order === 'desc' ? 'asc' : 'desc', - name: property, - }) - ); }; + const onSelect = + (key: keyof typeof selectedFilters) => + ( + event: ChangeEvent<{ + name?: string | undefined; + value: unknown; + }> + ) => { + setSelectedFilters((prev) => { + return { + ...prev, + [key]: event.target.value, + }; + }); + }; + return ( <> { handleChangeSearch={handleSearchChange} searchField={searchField} label="Введите параметры поиска (ФИО клиента, ID, Адрес, ФИО специалиста, Комментарий, Статус заказа, Наименование котла)" - onSearch={handleSearch} + onSearch={applyFilters} + selectedFilters={selectedFilters} + onSelect={onSelect} /> diff --git a/frontend/src/store/actions/ordersActions.ts b/frontend/src/store/actions/ordersActions.ts index 613e2db..73e1163 100644 --- a/frontend/src/store/actions/ordersActions.ts +++ b/frontend/src/store/actions/ordersActions.ts @@ -1,5 +1,5 @@ import { Dispatch } from 'react'; -import { OrderDataModel, SortModel } from '../../models/storeModel'; +import { OrderDataModel } from '../../models/storeModel'; import api from '../../utils/axiosMiddleware'; import { CLEAR_ORDER_DATA, @@ -9,21 +9,21 @@ import { ADD_NOTIFY } from '../storeConstants/snackbarConstants'; import { setLoader } from './mainActions'; import history from '../../utils/history'; +export interface SearchFilters { + searchValue?: string; + users?: string[]; + statuses?: string[]; + fromDate?: string; + toDate?: string; +} + export const getOrders = - ( - page: number = 0, - count: number = 10, - searchField: string = '', - sort: SortModel = { name: 'id', order: 'desc' } - ) => - async (dispatch: Dispatch) => { + (searchString: string) => async (dispatch: Dispatch) => { try { dispatch(setLoader(true)); api - .get( - `/api/orders?page=${page}&count=${count}&searchValue=${searchField}&sort=${sort.name},${sort.order}` - ) + .get(`/api/orders${searchString}`) .then((res) => { dispatch({ type: SET_ORDERS, diff --git a/queries.sql b/queries.sql index 09332c6..a43c423 100644 --- a/queries.sql +++ b/queries.sql @@ -596,4 +596,110 @@ FROM (1, 23, NOW()) ) as u2(id, value, updateDate) WHERE - u2.id = u.id; \ No newline at end of file + u2.id = u.id; + +-- GET ORDERS WITH FILTERS -- +SELECT + orders.id, + orders.address, + orders."createdDate", + orders."updatedDate", + orders.comment, + orders."customerId", + orders."serviceManId", + orders."createdBy", + orders."phone", + status.name as "statusName", + status.code as "statusCode", + customers."fullName", + customers."boilerSerial", + users."fullName" as "serviceManFullName", + boilers.name as "boilerName" + FROM + "service-crm"."orders" as orders + LEFT JOIN + "service-crm"."dictOrderStatuses" as status + ON + orders.status = status.id + LEFT JOIN + "service-crm"."customers" as customers + ON + orders."customerId" = customers.id + LEFT JOIN + "service-crm"."users" as users + ON + orders."serviceManId" = users.id + LEFT JOIN + "service-crm"."dictBoilers" as boilers + ON + customers."boilerId" = boilers.id + WHERE + orders."isActive" = true AND + orders."serviceManId" IN (36, 39) AND + (LOWER(customers."fullName") LIKE '%%' OR + orders.id::text LIKE '%%' OR + LOWER(orders.address) LIKE '%%' OR + LOWER(users."fullName") LIKE '%%' OR + LOWER(customers."boilerSerial") LIKE '%%' OR + LOWER(boilers.name) LIKE '%%' OR + LOWER(status.name) LIKE '%%' OR + LOWER(orders.comment) LIKE '%%') + ORDER BY + id DESC + LIMIT + 10 + OFFSET + 0; + +SELECT + orders.id, + orders.address, + orders."createdDate", + orders."updatedDate", + orders.comment, + orders."customerId", + orders."serviceManId", + orders."createdBy", + orders."phone", + status.name as "statusName", + status.code as "statusCode", + customers."fullName", + customers."boilerSerial", + users."fullName" as "serviceManFullName", + boilers.name as "boilerName" + FROM + "service-crm"."orders" as orders + LEFT JOIN + "service-crm"."dictOrderStatuses" as status + ON + orders.status = status.id + LEFT JOIN + "service-crm"."customers" as customers + ON + orders."customerId" = customers.id + LEFT JOIN + "service-crm"."users" as users + ON + orders."serviceManId" = users.id + LEFT JOIN + "service-crm"."dictBoilers" as boilers + ON + customers."boilerId" = boilers.id + WHERE + orders."isActive" = true AND + (LOWER(customers."fullName") LIKE '%%' OR + orders.id::text LIKE '%%' OR + LOWER(orders.address) LIKE '%%' OR + LOWER(users."fullName") LIKE '%%' OR + LOWER(customers."boilerSerial") LIKE '%%' OR + LOWER(boilers.name) LIKE '%%' OR + LOWER(status.name) LIKE '%%' OR + LOWER(orders.comment) LIKE '%%') + ORDER BY + id ASC + LIMIT + 10 + OFFSET + 0; + +SELECT * FROM "service-crm"."orders" as orders WHERE orders."createdDate" >= '2023-11-04' AND orders."createdDate" < '2023-11-05'; \ No newline at end of file