Parcourir la source

rtk_goods, search yepp

Gennadysht il y a 2 ans
Parent
commit
9b50a76baa

+ 5 - 3
src/App.js

@@ -4,8 +4,8 @@ import { Router, Route, Switch, useParams } from 'react-router-dom';
 import { createBrowserHistory } from "history";
 import { createStore, combineReducers, applyMiddleware } from 'redux';
 import { Provider } from 'react-redux';
-import { authReducer, promiseReducer, actionAuthLogin, frontEndReducer, actionRootCats } from './reducers';
-import { CLoginForm, CMainAppBar, COrdersList } from "./Components";
+import { authReducer, promiseReducer, actionAuthLogin, frontEndReducer, actionRootCats, goodsReducer } from './reducers';
+import { CGoodsList, CLoginForm, CMainAppBar, COrdersList, goodsExample, GoodsList } from "./Components";
 import { CLogout } from './Components';
 import { CSidebar } from './Components/Sidebar';
 import thunk from 'redux-thunk';
@@ -24,7 +24,8 @@ export const store = configureStore({
     promise: promiseReducer,
     frontend: frontEndReducer,
     category: categoryReducer,
-    orders: ordersReducer
+    orders: ordersReducer,
+    goods: goodsReducer
   }
 });
 store.subscribe(() => console.log(store.getState()))
@@ -59,6 +60,7 @@ function App() {
             <Switch>
               <Route path="/" component={Main} exact />
               <Route path="/orders" component={COrdersList} />
+              <Route path="/goods" component={CGoodsList} />
               <Route path="/category/:_id" component={CCategory} />
               <Route path="/login" component={CLoginForm} />
               <Route path="/logout" component={CLogout} />

+ 2 - 2
src/Components/Category.js

@@ -6,7 +6,7 @@ import { connect } from "react-redux"
 import { useParams } from "react-router-dom"
 import { MyLink } from "."
 import { actionCategoryFindOne } from "../reducers"
-import { GoodsList } from "./GoodsList"
+import { CGoodsList } from "./GoodsList"
 import { CatsList } from "./RootCats"
 
 const CSubCategories = connect(state => ({ cats: state.category.catFindOne?.payload?.subCategories }),
@@ -56,7 +56,7 @@ const Category = (props) => {
                         </List>
                     )
                     }
-                    <GoodsList goods={cat.goods} />
+                    <CGoodsList goods={cat.goods} />
                 </Box>
             </Container>
         </>

+ 31 - 10
src/Components/GoodsList.js

@@ -1,11 +1,11 @@
-import React, { Component, useState } from 'react';
-import Button from '@mui/material/Button';
-import { styled, alpha } from '@mui/material/styles';
-import { Container, Avatar, Typography, Grid, CardActionArea, Card, CardContent, CardMedia, AvatarGroup, CardActions, Collapse, IconButton, Paper, List, ListItem, Box } from '@mui/material';
-//CssBaseline, TextField, FormControlLabel, Checkbox, Link, Divider
-import { getFullImageUrl } from "./../utills";
-import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
+import React, { useEffect } from 'react';
+import { Container, Box } from '@mui/material';
 import { Good } from './Good';
+import { connect } from 'react-redux';
+import { actionGoodFind, actionGoodsCount } from '../reducers';
+import { CGoodsSearchInput } from './SearchInput';
+import { CGoodsPagination } from './Pagination';
+
 
 let goodsExample = [
     {
@@ -403,18 +403,39 @@ let goodsExample = [
     }
 ];
 
-const GoodsList = ({ goods }) => {
+const GoodsList = ({ goods, searchStr, fromPage = 0, pageSize = 5, loadData, loadGoodsCount, currentCategory }) => {
+    useEffect(() => {
+        let categoryFilter = currentCategory ? { "categories._id": currentCategory._id } : {};
+        loadData(fromPage, pageSize, searchStr, categoryFilter);
+        loadGoodsCount(searchStr, categoryFilter);
+    }, [fromPage, pageSize, searchStr, currentCategory]);
+
     return (
         <Container maxWidth='lg'>
+            <CGoodsSearchInput />
             <Box sx={{ display: 'flex', flexWrap: 'wrap' }}>
                 {
-                    goods.map(good => {
+                    goods?.map(good => {
                         return (
                             <Good key={good._id} good={good} maxWidth='xs' />
                         )
                     })}
             </Box>
+            <CGoodsPagination />
         </Container>
     )
 }
-export { goodsExample, GoodsList };
+const CGoodsList = connect(
+    state => {
+        return (
+            {
+                currentCategory: state.category.catFindOne?.payload,
+                goods: state.goods?.goods?.payload,
+                searchStr: state.frontend.goodsSearchStr,
+                fromPage: state.frontend.goodsPaging.fromPage,
+                pageSize: state.frontend.goodsPaging.pageSize,
+            })
+    },
+    { loadData: actionGoodFind, loadGoodsCount: actionGoodsCount })(GoodsList);
+
+export { CGoodsList };

+ 13 - 3
src/Components/Pagination.js

@@ -1,8 +1,8 @@
 import { TablePagination } from '@mui/material';
 import { useState } from 'react';
 import { connect } from 'react-redux';
-import { actionFindOrders, actionOrdersCount } from '../reducers';
-import { actionSetOrdersPaging } from '../reducers/frontEndReducer';
+import { actionFindOrders, actionGoodFind, actionGoodsCount, actionOrdersCount } from '../reducers';
+import { actionSetGoodsPaging, actionSetOrdersPaging } from '../reducers/frontEndReducer';
 
 const Pagination = ({ allEntitiesCount, changePage, changePageFE, changeRowsPerPage, changeRowsPerPageFE }) => {
     allEntitiesCount = allEntitiesCount ?? 0;
@@ -43,6 +43,16 @@ export const COrdersPagination = connect(
         changePage: (fromPage, pageSize) => actionFindOrders(fromPage, pageSize),
         changeRowsPerPageFE: pageSize => actionSetOrdersPaging({ fromPage: 0, pageSize }),
         changeRowsPerPage: pageSize => actionFindOrders(0, pageSize),
-        retrieveOrdersCount: actionOrdersCount,
+    })(Pagination);
+export const CGoodsPagination = connect(
+    state => (
+        {
+            allEntitiesCount: state.goods.goodsCount?.payload ?? 0,
+        }),
+    {
+        changePageFE: (fromPage, pageSize) => actionSetGoodsPaging({ fromPage, pageSize }),
+        changePage: (fromPage, pageSize) => actionGoodFind(fromPage, pageSize),
+        changeRowsPerPageFE: pageSize => actionSetGoodsPaging({ fromPage: 0, pageSize }),
+        changeRowsPerPage: pageSize => actionGoodFind(0, pageSize),
     })(Pagination);
 

+ 9 - 1
src/Components/SearchInput.js

@@ -6,7 +6,7 @@ import Typography from '@mui/material/Typography';
 import InputBase from '@mui/material/InputBase';
 import SearchIcon from '@mui/icons-material/Search';
 import { connect } from 'react-redux';
-import { actionSetOrderSearch } from '../reducers/frontEndReducer';
+import { actionSetGoodsSearch, actionSetOrderSearch } from '../reducers/frontEndReducer';
 
 const Search = styled('div')(({ theme }) => ({
   position: 'relative',
@@ -83,4 +83,12 @@ export const COrdersSearchInput = connect(
   {
     onChange: seacrhStr => actionSetOrderSearch(seacrhStr)
   }
+)(SearchInput);
+export const CGoodsSearchInput = connect(
+  state => {
+
+  },
+  {
+    onChange: seacrhStr => actionSetGoodsSearch(seacrhStr)
+  }
 )(SearchInput);

+ 1 - 1
src/Components/index.js

@@ -1,6 +1,6 @@
 export { CLoginForm } from './LoginForm';
 export { Good, GoodExample } from './Good';
-export { goodsExample, GoodsList } from './GoodsList';
+export { CGoodsList } from './GoodsList';
 export { OrderGood, exampleOrderGood } from './OrderGood';
 export { OrderGoodsList, exampleOrderGoodsList } from './OrderGoodsList'
 export { Order, exampleOrder } from './Order';

+ 18 - 10
src/jql/gqlGoods.js

@@ -1,8 +1,9 @@
 import { gql } from "../utills/gql";
-import {actionPromise} from "../reducers";
+import { createFullQuery } from "./jqlUtils";
 
 export const gqlGoodFindOne = (id) => {
-    const catQuery = `
+    let params = createFullQuery({ searchStr: id, searchFieldNames: ["_id"] });
+    const gqlQuery = `
                 query GoodFindOne($q: String) {
                     GoodFindOne(query: $q) {
                         _id name  price description
@@ -10,13 +11,12 @@ export const gqlGoodFindOne = (id) => {
                     }
                 }
                 `;
-    return gql(catQuery, { q: `[{\"_id\": \"${id}\"}]` });
+    return gql(gqlQuery, params);
 }
-export const actionGoodFindOne = (id) =>
-    actionPromise('goodFindOne', gqlGoodFindOne(id));
 
-export const gqlGoodFind = () => {
-    const catQuery = `
+export const gqlGoodFind = (fromPage, pageSize, searchStr = '', queryExt = {}) => {
+    let params = createFullQuery(getGoodsSearchParams(searchStr, queryExt), { fromPage, pageSize });
+    const gqlQuery = `
                 query GoodFind($q: String) {
                     GoodFind(query: $q) {
                         _id name  price description
@@ -24,7 +24,15 @@ export const gqlGoodFind = () => {
                     }
                 }
                 `;
-    return gql(catQuery, { q: `[{\"name\": \"//\"}]` });
+    return gql(gqlQuery, params);
 }
-export const actionGoodFind = () =>
-    actionPromise('goodFind', gqlGoodFind());
+export const gqlGoodsCount = (query = '', queryExt = {}) => {
+    let params = createFullQuery(getGoodsSearchParams(query, queryExt));
+    const gqlQuery = `query GoodsCount($q: String) { GoodCount(query: $q) }`;
+    return gql(gqlQuery, params);
+}
+const getGoodsSearchParams = (searchStr, queryExt) => (
+    {
+        searchStr: searchStr, searchFieldNames: ["name", "description"],
+        queryExt
+    });

+ 1 - 1
src/jql/index.js

@@ -1,3 +1,3 @@
 export { actionAuthUpsert, actionLogin, actionFullLogin } from './gqlAuth';
-export { actionGoodFind, actionGoodFindOne } from './gqlGoods';
+export { gqlGoodFind, gqlGoodFindOne } from './gqlGoods';
 export { actionOrderFullUpsert, actionOrderUpsert } from './gqlOrders';

+ 12 - 5
src/jql/jqlUtils.js

@@ -1,11 +1,18 @@
 const createQuery = (searchStr, searchFieldNames) => {
-    let result = {};
+    let result = [];
     if (searchStr) {
         for (let searchFieldName of searchFieldNames) {
-            result[searchFieldName] = searchFieldName === '_id' ? searchStr : `/${searchStr}/`;
+            //result[searchFieldName] = searchFieldName === '_id' ? searchStr : `/${searchStr}/`;
+            result.push({ [searchFieldName]: searchFieldName === '_id' ? searchStr : `/${searchStr}/` });
         }
     }
-    return result;
+    return result.length == 0 ? {} :  { $or: result };
+}
+
+const createQueryExt = (searchQuery = {}, queryExt = {}) => {
+    if (!queryExt)
+        return searchQuery;
+    return { $and: [searchQuery, queryExt] };
 }
 
 const createQueryPaging = (fromPage, pageSize) => {
@@ -17,6 +24,6 @@ const createQueryPaging = (fromPage, pageSize) => {
     return result;
 }
 
-export const createFullQuery = ({ searchStr, searchFieldNames }, { fromPage, pageSize } = {}) => {
-    return { q: JSON.stringify([createQuery(searchStr, searchFieldNames), createQueryPaging(fromPage, pageSize)]) };
+export const createFullQuery = ({ searchStr, searchFieldNames, queryExt = {} }, { fromPage, pageSize } = {}) => {
+    return { q: JSON.stringify([createQueryExt(createQuery(searchStr, searchFieldNames), queryExt), createQueryPaging(fromPage, pageSize)]) };
 }

+ 26 - 5
src/reducers/frontEndReducer.js

@@ -2,7 +2,11 @@ import { createSlice } from "@reduxjs/toolkit"
 
 const frontEndReducerSlice = createSlice({ //promiseReducer
     name: 'frontend', //префикс типа наподобие AUTH_
-    initialState: { sidebar: {}, ordersPaging: { fromPage: 0, pageSize: 5 } }, //state={} в параметрах
+    initialState: { 
+        sidebar: {}, 
+        ordersPaging: { fromPage: 0, pageSize: 5 },
+        goodsPaging: { fromPage: 0, pageSize: 5 } 
+     }, //state={} в параметрах
     reducers: {
         setSidebar(state, action) {
             state.sidebar = { opened: action.payload.open };
@@ -15,7 +19,15 @@ const frontEndReducerSlice = createSlice({ //promiseReducer
         setOrdersSearch(state, action) {
             state.ordersSearchStr = action.payload.searchStr;
             return state;
-        }
+        },
+        setGoodsPaging(state, action) {
+            state.goodsPaging = { fromPage: action.payload.page.fromPage, pageSize: action.payload.page.pageSize };
+            return state;
+        },
+        setGoodsSearch(state, action) {
+            state.goodsSearchStr = action.payload.searchStr;
+            return state;
+        },
     }
 })
 
@@ -30,10 +42,19 @@ let actionSetOrdersPaging = ({ fromPage, pageSize }) =>
         dispatch(frontEndReducerSlice.actions.setOrdersPaging({ page: { fromPage, pageSize } }))
     }
 
-let actionSetOrderSearch = ({ searchStr }) =>
+let actionSetOrderSearch = (searchStr) =>
     async dispatch => {
-        dispatch(frontEndReducerSlice.actions.setOrdersPaging({ searchStr }))
+        dispatch(frontEndReducerSlice.actions.setOrdersSearch({ searchStr }))
     }
 
+let actionSetGoodsPaging = ({ fromPage, pageSize }) =>
+    async dispatch => {
+        dispatch(frontEndReducerSlice.actions.setGoodsPaging({ page: { fromPage, pageSize } }))
+    }
+
+let actionSetGoodsSearch = (searchStr) =>
+    async dispatch => {
+        dispatch(frontEndReducerSlice.actions.setGoodsSearch({ searchStr }))
+    }
 
-export { frontEndReducer, actionSetSidebar, actionSetOrdersPaging, actionSetOrderSearch };
+export { frontEndReducer, actionSetSidebar, actionSetOrdersPaging, actionSetOrderSearch, actionSetGoodsPaging, actionSetGoodsSearch };

+ 16 - 0
src/reducers/goodsReducer.js

@@ -0,0 +1,16 @@
+import { gqlGoodFind, gqlGoodFindOne, gqlGoodsCount } from '../jql/gqlGoods';
+import { createPromiseReducerSlice, actionPromiseGeneric } from './promiseReducer';
+
+const actionGoodFindOne = (id) =>
+    actionPromiseGoods('selectedGood', gqlGoodFindOne(id));
+const actionGoodFind = (fromPage = 0, pageSize = undefined, searchStr = null, queryExt = {}) =>
+    actionPromiseGoods('goods', gqlGoodFind(fromPage, pageSize, searchStr, queryExt));
+const actionGoodsCount = (searchStr = null, queryExt = {}) =>
+    actionPromiseGoods('goodsCount', gqlGoodsCount(searchStr, queryExt));
+
+const goodsReducerSlice = createPromiseReducerSlice('goods');
+const actionPromiseGoods = (name, promise) =>
+    actionPromiseGeneric(goodsReducerSlice, name, promise);
+
+let goodsReducer = goodsReducerSlice.reducer;
+export { goodsReducer, actionGoodFindOne, actionGoodFind, actionGoodsCount }

+ 1 - 0
src/reducers/index.js

@@ -5,3 +5,4 @@ export { localStoredReducer, } from "./localStoredReducer";
 export { frontEndReducer, } from "./frontEndReducer";
 export { actionRootCats, actionCategoryFindOne } from './categoryReducer';
 export { actionFindOrders, actionOrdersCount } from './ordersReducer';
+export { goodsReducer, actionGoodFind, actionGoodFindOne, actionGoodsCount } from './goodsReducer';