Projekt

Obecné

Profil

« Předchozí | Další » 

Revize ab632fe5

Přidáno uživatelem Michal Schwob před více než 1 rok

NEW: added loading indicator for individual inventories
re #10850

Zobrazit rozdíly:

src/components/listView/ListView.tsx
7 7
import { log } from "../../logging/logger"
8 8
import ListViewInventoryGroup from "./ListViewInventoryGroup"
9 9
import { ErrorToast } from "../toast/ErrorToast"
10
import LoadingBox from "../loading/LoadingBox"
10 11

  
11 12
type ListViewProps = {
12 13
    navigation: any
......
16 17

  
17 18
    const inventories = useSelector((state: RootState) => state.listView.inventories)
18 19
    const numberOfResults = useSelector((state: RootState) => state.listView.numOfResults)
19

  
20
    const loading = useSelector((state: RootState) => state.listView.loading)
20 21

  
21 22
    const lastError = useSelector((state: RootState) => state.listView.lastError)
22 23
    const toast = useToast();
......
38 39
    return (
39 40
        <>
40 41
            <Text fontSize={16} fontWeight={"bold"} color={"primary.500"}>Search results{numberOfResults ? ` (${numberOfResults})` : ""}:</Text>
41
            {inventories && inventories.length > 0 ?
42
            {loading ? (
43
                <LoadingBox text={"Loading..."} />
44
            )  :
45
            inventories && inventories.length > 0 ?
42 46
                (inventories.length > 1 ?
43 47
                    inventories.map((inventory) => (
44 48
                        <ListViewInventoryGroup
......
57 61
                    )) : (
58 62
                    <Text alignSelf={"center"}>No results found</Text>
59 63
                )
64

  
60 65
            }
61 66
        </>
62 67
    )
src/components/listView/ListViewInventoryGroup.tsx
1
import { Badge, Button, Pressable, VStack, Text, Fab, Divider } from "native-base"
2
import { ItemPreviewType } from "../../types/listViewTypes"
1
import {Badge, Button, Pressable, VStack, Text, Fab, Divider} from "native-base"
2
import {ItemPreviewType} from "../../types/listViewTypes"
3 3
import ItemPreview from "./ItemPreview"
4
import { useDispatch, useSelector } from "react-redux"
5
import { AppDispatch, RootState } from "../../stores/store"
6
import { useEffect, useState } from "react"
7
import { loadItemsByInventory } from "../../stores/actions/listViewThunks"
4
import {useDispatch, useSelector} from "react-redux"
5
import {AppDispatch, RootState} from "../../stores/store"
6
import {useEffect, useState} from "react"
7
import {loadItemsByInventory} from "../../stores/actions/listViewThunks"
8
import LoadingBox from "../loading/LoadingBox"
8 9

  
9 10
interface ListViewInventoryGroupProps {
10 11
    inventoryName: string
......
16 17
const ListViewInventoryGroup = (props: ListViewInventoryGroupProps) => {
17 18
    const items = useSelector((state: RootState) => state.listView.data[props.inventoryName])
18 19
    const loading = useSelector((state: RootState) => state.listView.loading)
20
    const inventoriesDataLoading = useSelector((state: RootState) => state.listView.inventoriesDataLoading)
21
    const [isInventoryDataLoading, setIsInventoryDataLoading] = useState(false)
19 22
    const [isExpanded, setIsExpanded] = useState(props.defaultOpen ? props.defaultOpen : false)
20 23
    const pagination = useSelector((state: RootState) => state.listView.loadedPages[props.inventoryName])
21 24

  
......
77 80
        }
78 81
    }, [loading])
79 82

  
83
    useEffect(() => {
84
        setIsInventoryDataLoading(inventoriesDataLoading[props.inventoryName] ? inventoriesDataLoading[props.inventoryName] : false)
85
    }, [inventoriesDataLoading]);
86

  
80 87
    useEffect(() => {
81 88
        if (props.defaultOpen) {
82 89
            if (!items || items.length == 0) {
......
86 93
    }, [])
87 94

  
88 95
    return (
89
        <VStack mb={2} key={props.inventoryName}>
96
        <VStack mb={ 2 } key={ props.inventoryName }>
90 97
            <Button
91
                onPress={() => setIsExpanded(!isExpanded)}
92
                alignSelf={"flex-start"}
98
                onPress={ () => setIsExpanded(!isExpanded) }
99
                alignSelf={ "flex-start" }
93 100
                variant="solid"
94
                bg={"primary.500"}
95
                mb={2}
96
                p={1}
97
                key={props.inventoryName}
98
                size={"md"}
101
                bg={ "primary.500" }
102
                mb={ 2 }
103
                p={ 1 }
104
                key={ props.inventoryName }
105
                size={ "md" }
99 106
            >
100
                {props.inventoryLabel}
107
                { props.inventoryLabel }
101 108
            </Button>
102
            {isExpanded && items && items.map((item) => (
109
            { isExpanded && items && items.map((item) => (
103 110
                <ItemPreview
104 111
                    // @ts-ignore
105
                    caption={item.object[0].caption}
106
                    title={item.text}
107
                    name={parseArtists(item)}
108
                    image={parseImage(item)}
109
                    itemId={item.xml_id}
110
                    inventoryLabel={props.inventoryLabel}
111
                    navigation={props.navigation}
112
                    caption={ item.object[0].caption }
113
                    title={ item.text }
114
                    name={ parseArtists(item) }
115
                    image={ parseImage(item) }
116
                    itemId={ item.xml_id }
117
                    inventoryLabel={ props.inventoryLabel }
118
                    navigation={ props.navigation }
112 119
                />
113
            ))}
114
            {isExpanded && items && pagination && pagination.cursor < pagination.records && (
120
            )) }
121
            { isExpanded && items && pagination && pagination.cursor < pagination.records && !isInventoryDataLoading && (
115 122
                <Button
116
                    onPress={() => dispatch(loadItemsByInventory(props.inventoryName))}
117
                    variant={"Link"}
118
                    mt={0}
119
                    size={"sm"}
120
                    color={"primary.500"}
121
                    textDecoration={"underline"}
123
                    onPress={ () => dispatch(loadItemsByInventory(props.inventoryName)) }
124
                    variant={ "Link" }
125
                    mt={ 0 }
126
                    size={ "sm" }
127
                    color={ "primary.500" }
128
                    textDecoration={ "underline" }
122 129
                >
123
                    <Text fontSize={"sm"} color={"primary.500"} underline>Load more</Text>
130
                    <Text fontSize={ "sm" } color={ "primary.500" } underline>Load more</Text>
124 131
                </Button>
125
            )}
126
            <Divider my={2} colorScheme={"primary"}/>
132
            ) }
133
            { isExpanded && isInventoryDataLoading && (
134
                <LoadingBox text={ "Loading..." }/>
135
            ) }
136
            <Divider my={ 2 } colorScheme={ "primary" }/>
127 137

  
128 138
        </VStack>
129 139
    )
src/components/search/SearchForm.tsx
17 17
import MultiSelect from "./MultiSelect"
18 18
import SwitchWithLabel from "./SwitchWithLabel"
19 19
import { log } from "../../logging/logger"
20
import { setFilterState } from "../../stores/reducers/listViewSlice"
20
import {resetInventories, setFilterState} from "../../stores/reducers/listViewSlice"
21 21
import { SearchParams } from "../../api/searchService"
22 22

  
23 23
interface SearchFormProps {
......
27 27

  
28 28
const SearchForm = (props: SearchFormProps) => {
29 29
    const [isFilterOpen, setIsFilterOpen] = useState<boolean>(true)
30
    const loading = useSelector((state: RootState) => state.listView.loading)
30 31

  
31 32
    const inventories: Inventory[] = useSelector((state: RootState) => state.searchForm.inventories)
32 33
    const nationalities = useSelector((state: RootState) => state.searchForm.nationalities)
......
75 76
            isLowQuality,
76 77
            searchQuery: searchQuery,
77 78
        }
79
        dispatch(resetInventories())
78 80
        dispatch(setFilterState(filterState))
79 81
        dispatch(search(filterState))
80 82
        setIsFilterOpen(false)
......
161 163
                </Button>
162 164
                { !isFilterOpen && (
163 165
                    <Button
166
                        isLoading={ loading }
164 167
                        borderRadius={ 10 }
165 168
                        onPress={ () => searchSubmit() }
166 169
                        colorScheme="primary"
......
279 282
                            Reset
280 283
                        </Button>
281 284
                        <Button
285
                            isLoading={ loading }
282 286
                            borderRadius={ 10 }
283 287
                            onPress={ () => searchSubmit() }
284 288
                            colorScheme="primary"
src/stores/reducers/listViewSlice.ts
32 32
        resetListView: () => initialState,
33 33
        setFilterState: (state, action) => {
34 34
            state.filterState = action.payload
35
        },
36
        resetInventories: (state) => {
37
            state.inventories = []
35 38
        }
36 39
    },
37 40
    extraReducers: (builder) => {
......
57 60
            state.data[inventories[0].name] = state.data[inventories[0].name] ? [...prevData, ...data] : [...data]
58 61
            state.loading = false
59 62
            state.loadedPages[inventories[0].name] = {cursor, items, records}
63
            state.inventoriesDataLoading[action.meta.arg] = false
60 64
        })
61 65
        builder.addCase(loadItemsByInventory.pending, (state, action) => {
62 66
            state.inventoriesDataLoading[action.meta.arg] = true
......
64 68
    }
65 69
})
66 70

  
67
export const { resetListView, setFilterState } = listViewSlice.actions
71
export const { resetListView, setFilterState, resetInventories } = listViewSlice.actions
68 72
export default listViewSlice.reducer

Také k dispozici: Unified diff