Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 1c710f4f

Přidáno uživatelem Václav Honzík před asi 2 roky(ů)

filter functional

re #9545

Zobrazit rozdíly:

frontend/package.json
63 63
    "@types/react-dom": "^17.0.9",
64 64
    "@types/react-redux": "^7.1.23",
65 65
    "@types/redux-persist": "^4.3.1",
66
    "@types/yup": "^0.29.13"
66
    "@types/yup": "^0.29.13",
67
    "redux-devtools-extension": "^2.13.9"
67 68
  }
68 69
}
frontend/src/features/Catalog/Catalog.tsx
1 1
import {
2
    Box,
3
    Button,
4
    Collapse,
5 2
    Container,
6
    Grid,
7 3
    Paper,
8
    Stack,
9
    TextField,
10 4
    Typography,
11 5
} from '@mui/material'
12 6
import CatalogTable from './CatalogTable'
13
import { Fragment, useState } from 'react'
7
import { Fragment } from 'react'
8
import CatalogFilter from './CatalogFilter'
14 9

  
15 10
const Catalog = () => {
16
    const [filterOpen, setFilterOpen] = useState(false)
17
    const toggleFilter = () => {
18
        setFilterOpen(!filterOpen)
19
    }
11
    
20 12

  
21 13
    return (
22 14
        <Fragment>
......
27 19
            >
28 20
                <Container sx={{ mt: 4 }}>
29 21
                    <Typography variant="h3" sx={{mb: 2}} fontWeight="bold" >Catalog</Typography>
30
                    <Button variant="outlined" color="primary" onClick={toggleFilter}>
31
                        Filter
32
                    </Button>
33
                    <Collapse in={filterOpen} timeout="auto" unmountOnExit>
34
                        <Grid container spacing={1} alignItems="stretch">
35
                            <Grid item xs={6}>
36
                                <Stack
37
                                    direction="column"
38
                                    spacing={1}
39
                                    sx={{ mt: 2 }}
40
                                >
41
                                    <Stack direction="row" spacing={2}>
42
                                        <TextField
43
                                            size="small"
44
                                            id="name"
45
                                            label="Name"
46
                                        />
47
                                        <TextField
48
                                            size="small"
49
                                            id="type"
50
                                            label="Type"
51
                                        />
52
                                    </Stack>
53
                                    <Stack direction="row" spacing={2}>
54
                                        <TextField
55
                                            size="small"
56
                                            id="writtenForm"
57
                                            label="Written form"
58
                                        />
59
                                        <TextField
60
                                            size="small"
61
                                            id="stateOrTerritory"
62
                                            label="State or territory"
63
                                        />
64
                                        <TextField
65
                                            size="small"
66
                                            id="groupBy"
67
                                            label="Group by"
68
                                        />
69
                                    </Stack>
70
                                </Stack>
71
                            </Grid>
72
                            <Grid item xs sx={{ mt: 'auto', ml: 1, mb: 1 }}>
73
                                <Stack
74
                                    direction="row"
75
                                    justifyContent="flex-start"
76
                                    alignItems="flex-end"
77
                                >
78
                                    <Button variant="outlined">Search</Button>
79
                                </Stack>
80
                            </Grid>
81
                        </Grid>
82
                    </Collapse>
83

  
84
                    <Box sx={{ mt: 4 }}>
22
                        <CatalogFilter />
85 23
                        <CatalogTable />
86
                    </Box>
87 24
                </Container>
88 25
            </Paper>
89 26
        </Fragment>
frontend/src/features/Catalog/CatalogFilter.tsx
1
import { Button, Collapse, Grid, Stack, TextField } from '@mui/material'
2
import { Fragment, useState } from 'react'
3
import { useDispatch } from 'react-redux'
4
import { setFilter, CatalogFilter as Filter } from './catalogSlice'
5
import { fetchItems } from './catalogThunks'
6

  
7
const CatalogFilter = () => {
8
    const dispatch = useDispatch()
9

  
10
    const [filterOpen, setFilterOpen] = useState(false)
11
    const toggleFilter = () => {
12
        setFilterOpen(!filterOpen)
13
    }
14

  
15
    // current filter object
16
    const filter: Filter = {}
17
    const applyFilter = () => {
18
        dispatch(fetchItems())
19
    }
20

  
21

  
22
    return (
23
        <Fragment>
24
            <Button variant="outlined" color="primary" onClick={toggleFilter}>
25
                Filter
26
            </Button>
27
            <Collapse in={filterOpen} timeout="auto" unmountOnExit>
28
                <Grid container spacing={1} alignItems="stretch">
29
                    <Grid item xs={6}>
30
                        <Stack direction="column" spacing={1} sx={{ mt: 2 }}>
31
                            <Stack direction="row" spacing={2}>
32
                                <TextField
33
                                    size="small"
34
                                    id="name"
35
                                    label="Name"
36
                                    onChange={(e: any) => { 
37
                                        filter.name = e.target.value 
38
                                        dispatch(setFilter(filter))
39
                                    }}
40
                                />
41
                                <TextField
42
                                    size="small"
43
                                    id="type"
44
                                    label="Type"
45
                                    onChange={(e: any) => {
46
                                        filter.type = e.target.value
47
                                        dispatch(setFilter(filter))
48
                                     }}
49
                                />
50
                            </Stack>
51
                            <Stack direction="row" spacing={2}>
52
                                <TextField
53
                                    size="small"
54
                                    id="writtenForm"
55
                                    label="Written form"
56
                                />
57
                                <TextField
58
                                    size="small"
59
                                    id="stateOrTerritory"
60
                                    label="State or territory"
61
                                    onChange={(e: any) => { 
62
                                        filter.country = e.target.value 
63
                                        dispatch(setFilter(filter))
64
                                    }}
65
                                />
66
                                <TextField
67
                                    size="small"
68
                                    id="groupBy"
69
                                    label="Group by"
70
                                />
71
                            </Stack>
72
                        </Stack>
73
                    </Grid>
74
                    <Grid item xs sx={{ mt: 'auto', ml: 1, mb: 1 }}>
75
                        <Stack
76
                            direction="row"
77
                            justifyContent="flex-start"
78
                            alignItems="flex-end"
79
                        >
80
                            <Button variant="outlined" onClick={applyFilter}>Search</Button>
81
                        </Stack>
82
                    </Grid>
83
                </Grid>
84
            </Collapse>
85
        </Fragment>
86
    )
87
}
88

  
89
export default CatalogFilter
frontend/src/features/Catalog/catalogSlice.tsx
26 26
    name: 'catalog',
27 27
    initialState,
28 28
    reducers: {
29
        setCatalogFilter: (state, action) => ({
29
        setFilter: (state, action) => ({
30 30
            ...state,
31
            catalogFilter: action.payload.catalogFilter,
31
            filter: {...action.payload},
32 32
        }),
33 33
        clearFilter: (state, action) => ({
34 34
            ...state,
35 35
            loading: true,
36
            catalogFilter: {},
36
            filter: {},
37 37
        }),
38 38
        clear: (state) => ({ ...initialState }),
39 39
        setLoading: (state) => ({ ...state, loading: true }),
......
57 57
    },
58 58
})
59 59

  
60
export const { setCatalogFilter, clearFilter, clear, setLoading, consumeError } = catalogSlice.actions
60
export const { setFilter, clearFilter, clear, setLoading, consumeError } = catalogSlice.actions
61 61
const reducer = catalogSlice.reducer
62 62
export default reducer
frontend/src/features/redux/store.ts
1

  
2 1
import { applyMiddleware, combineReducers, createStore } from 'redux'
3 2
import { persistStore } from 'redux-persist'
4 3
import thunk from 'redux-thunk'
5 4
import userReducer from '../Auth/userSlice'
6 5
import themeReducer from '../Theme/themeReducer'
7 6
import catalogReducer from '../Catalog/catalogSlice'
7
import { composeWithDevTools } from 'redux-devtools-extension'
8 8

  
9
const composeEnhancers = composeWithDevTools({})
9 10

  
10 11
// Store holds shared state in the application
11 12
const store = createStore(
12
    combineReducers({ user: userReducer, theme: themeReducer, catalog: catalogReducer }),
13
    applyMiddleware(thunk) // Thunk middleware so we can async fetch data from the api
13
    combineReducers({
14
        user: userReducer,
15
        theme: themeReducer,
16
        catalog: catalogReducer,
17
    }),
18
    process.env.REACT_APP_DEV_ENV === 'true'
19
        ? composeEnhancers(
20
              applyMiddleware(thunk) // Thunk middleware so we can async fetch data from the api
21
          )
22
        : applyMiddleware(thunk)
14 23
)
15 24

  
16 25
export default store
frontend/src/index.tsx
15 15
ReactDOM.render(
16 16
    <Provider store={store}>
17 17
        <PersistGate loading={null} persistor={persistor}>
18
            <React.StrictMode>
18
            {/* <React.StrictMode> */}
19 19
                <BrowserRouter>
20 20
                    <App />
21 21
                </BrowserRouter>
22
            </React.StrictMode>
22
            {/* </React.StrictMode> */}
23 23
        </PersistGate>
24 24
    </Provider>,
25 25
    document.getElementById('root')
frontend/yarn.lock
7759 7759
    indent-string "^4.0.0"
7760 7760
    strip-indent "^3.0.0"
7761 7761

  
7762
redux-devtools-extension@^2.13.9:
7763
  version "2.13.9"
7764
  resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.9.tgz#6b764e8028b507adcb75a1cae790f71e6be08ae7"
7765
  integrity sha512-cNJ8Q/EtjhQaZ71c8I9+BPySIBVEKssbPpskBfsXqb8HJ002A3KRVHfeRzwRo6mGPqsm7XuHTqNSNeS1Khig0A==
7766

  
7762 7767
redux-persist@*, redux-persist@^6.0.0:
7763 7768
  version "6.0.0"
7764 7769
  resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"

Také k dispozici: Unified diff