commit ab632fe533a6a1cafb30ee1d737dc892e0ea1526
Author: Michal Schwob <michal.schwob@seznam.cz>
Date:   Fri Nov 3 16:13:40 2023 +0100

    NEW: added loading indicator for individual inventories
    re #10850

diff --git a/src/components/listView/ListView.tsx b/src/components/listView/ListView.tsx
index 5786b45..8515926 100644
--- a/src/components/listView/ListView.tsx
+++ b/src/components/listView/ListView.tsx
@@ -7,6 +7,7 @@ import { ItemPreviewType } from "../../types/listViewTypes"
 import { log } from "../../logging/logger"
 import ListViewInventoryGroup from "./ListViewInventoryGroup"
 import { ErrorToast } from "../toast/ErrorToast"
+import LoadingBox from "../loading/LoadingBox"
 
 type ListViewProps = {
     navigation: any
@@ -16,7 +17,7 @@ const ListView = (props: ListViewProps) => {
 
     const inventories = useSelector((state: RootState) => state.listView.inventories)
     const numberOfResults = useSelector((state: RootState) => state.listView.numOfResults)
-
+    const loading = useSelector((state: RootState) => state.listView.loading)
 
     const lastError = useSelector((state: RootState) => state.listView.lastError)
     const toast = useToast();
@@ -38,7 +39,10 @@ const ListView = (props: ListViewProps) => {
     return (
         <>
             <Text fontSize={16} fontWeight={"bold"} color={"primary.500"}>Search results{numberOfResults ? ` (${numberOfResults})` : ""}:</Text>
-            {inventories && inventories.length > 0 ?
+            {loading ? (
+                <LoadingBox text={"Loading..."} />
+            )  :
+            inventories && inventories.length > 0 ?
                 (inventories.length > 1 ?
                     inventories.map((inventory) => (
                         <ListViewInventoryGroup
@@ -57,6 +61,7 @@ const ListView = (props: ListViewProps) => {
                     )) : (
                     <Text alignSelf={"center"}>No results found</Text>
                 )
+
             }
         </>
     )
diff --git a/src/components/listView/ListViewInventoryGroup.tsx b/src/components/listView/ListViewInventoryGroup.tsx
index dbfa6b5..3c9254b 100644
--- a/src/components/listView/ListViewInventoryGroup.tsx
+++ b/src/components/listView/ListViewInventoryGroup.tsx
@@ -1,10 +1,11 @@
-import { Badge, Button, Pressable, VStack, Text, Fab, Divider } from "native-base"
-import { ItemPreviewType } from "../../types/listViewTypes"
+import {Badge, Button, Pressable, VStack, Text, Fab, Divider} from "native-base"
+import {ItemPreviewType} from "../../types/listViewTypes"
 import ItemPreview from "./ItemPreview"
-import { useDispatch, useSelector } from "react-redux"
-import { AppDispatch, RootState } from "../../stores/store"
-import { useEffect, useState } from "react"
-import { loadItemsByInventory } from "../../stores/actions/listViewThunks"
+import {useDispatch, useSelector} from "react-redux"
+import {AppDispatch, RootState} from "../../stores/store"
+import {useEffect, useState} from "react"
+import {loadItemsByInventory} from "../../stores/actions/listViewThunks"
+import LoadingBox from "../loading/LoadingBox"
 
 interface ListViewInventoryGroupProps {
     inventoryName: string
@@ -16,6 +17,8 @@ interface ListViewInventoryGroupProps {
 const ListViewInventoryGroup = (props: ListViewInventoryGroupProps) => {
     const items = useSelector((state: RootState) => state.listView.data[props.inventoryName])
     const loading = useSelector((state: RootState) => state.listView.loading)
+    const inventoriesDataLoading = useSelector((state: RootState) => state.listView.inventoriesDataLoading)
+    const [isInventoryDataLoading, setIsInventoryDataLoading] = useState(false)
     const [isExpanded, setIsExpanded] = useState(props.defaultOpen ? props.defaultOpen : false)
     const pagination = useSelector((state: RootState) => state.listView.loadedPages[props.inventoryName])
 
@@ -77,6 +80,10 @@ const ListViewInventoryGroup = (props: ListViewInventoryGroupProps) => {
         }
     }, [loading])
 
+    useEffect(() => {
+        setIsInventoryDataLoading(inventoriesDataLoading[props.inventoryName] ? inventoriesDataLoading[props.inventoryName] : false)
+    }, [inventoriesDataLoading]);
+
     useEffect(() => {
         if (props.defaultOpen) {
             if (!items || items.length == 0) {
@@ -86,44 +93,47 @@ const ListViewInventoryGroup = (props: ListViewInventoryGroupProps) => {
     }, [])
 
     return (
-        <VStack mb={2} key={props.inventoryName}>
+        <VStack mb={ 2 } key={ props.inventoryName }>
             <Button
-                onPress={() => setIsExpanded(!isExpanded)}
-                alignSelf={"flex-start"}
+                onPress={ () => setIsExpanded(!isExpanded) }
+                alignSelf={ "flex-start" }
                 variant="solid"
-                bg={"primary.500"}
-                mb={2}
-                p={1}
-                key={props.inventoryName}
-                size={"md"}
+                bg={ "primary.500" }
+                mb={ 2 }
+                p={ 1 }
+                key={ props.inventoryName }
+                size={ "md" }
             >
-                {props.inventoryLabel}
+                { props.inventoryLabel }
             </Button>
-            {isExpanded && items && items.map((item) => (
+            { isExpanded && items && items.map((item) => (
                 <ItemPreview
                     // @ts-ignore
-                    caption={item.object[0].caption}
-                    title={item.text}
-                    name={parseArtists(item)}
-                    image={parseImage(item)}
-                    itemId={item.xml_id}
-                    inventoryLabel={props.inventoryLabel}
-                    navigation={props.navigation}
+                    caption={ item.object[0].caption }
+                    title={ item.text }
+                    name={ parseArtists(item) }
+                    image={ parseImage(item) }
+                    itemId={ item.xml_id }
+                    inventoryLabel={ props.inventoryLabel }
+                    navigation={ props.navigation }
                 />
-            ))}
-            {isExpanded && items && pagination && pagination.cursor < pagination.records && (
+            )) }
+            { isExpanded && items && pagination && pagination.cursor < pagination.records && !isInventoryDataLoading && (
                 <Button
-                    onPress={() => dispatch(loadItemsByInventory(props.inventoryName))}
-                    variant={"Link"}
-                    mt={0}
-                    size={"sm"}
-                    color={"primary.500"}
-                    textDecoration={"underline"}
+                    onPress={ () => dispatch(loadItemsByInventory(props.inventoryName)) }
+                    variant={ "Link" }
+                    mt={ 0 }
+                    size={ "sm" }
+                    color={ "primary.500" }
+                    textDecoration={ "underline" }
                 >
-                    <Text fontSize={"sm"} color={"primary.500"} underline>Load more</Text>
+                    <Text fontSize={ "sm" } color={ "primary.500" } underline>Load more</Text>
                 </Button>
-            )}
-            <Divider my={2} colorScheme={"primary"}/>
+            ) }
+            { isExpanded && isInventoryDataLoading && (
+                <LoadingBox text={ "Loading..." }/>
+            ) }
+            <Divider my={ 2 } colorScheme={ "primary" }/>
 
         </VStack>
     )
diff --git a/src/components/search/SearchForm.tsx b/src/components/search/SearchForm.tsx
index accc638..54e015b 100644
--- a/src/components/search/SearchForm.tsx
+++ b/src/components/search/SearchForm.tsx
@@ -17,7 +17,7 @@ import { search } from "../../stores/actions/listViewThunks"
 import MultiSelect from "./MultiSelect"
 import SwitchWithLabel from "./SwitchWithLabel"
 import { log } from "../../logging/logger"
-import { setFilterState } from "../../stores/reducers/listViewSlice"
+import {resetInventories, setFilterState} from "../../stores/reducers/listViewSlice"
 import { SearchParams } from "../../api/searchService"
 
 interface SearchFormProps {
@@ -27,6 +27,7 @@ interface SearchFormProps {
 
 const SearchForm = (props: SearchFormProps) => {
     const [isFilterOpen, setIsFilterOpen] = useState<boolean>(true)
+    const loading = useSelector((state: RootState) => state.listView.loading)
 
     const inventories: Inventory[] = useSelector((state: RootState) => state.searchForm.inventories)
     const nationalities = useSelector((state: RootState) => state.searchForm.nationalities)
@@ -75,6 +76,7 @@ const SearchForm = (props: SearchFormProps) => {
             isLowQuality,
             searchQuery: searchQuery,
         }
+        dispatch(resetInventories())
         dispatch(setFilterState(filterState))
         dispatch(search(filterState))
         setIsFilterOpen(false)
@@ -161,6 +163,7 @@ const SearchForm = (props: SearchFormProps) => {
                 </Button>
                 { !isFilterOpen && (
                     <Button
+                        isLoading={ loading }
                         borderRadius={ 10 }
                         onPress={ () => searchSubmit() }
                         colorScheme="primary"
@@ -279,6 +282,7 @@ const SearchForm = (props: SearchFormProps) => {
                             Reset
                         </Button>
                         <Button
+                            isLoading={ loading }
                             borderRadius={ 10 }
                             onPress={ () => searchSubmit() }
                             colorScheme="primary"
diff --git a/src/stores/reducers/listViewSlice.ts b/src/stores/reducers/listViewSlice.ts
index 5b41a34..bba9f2a 100644
--- a/src/stores/reducers/listViewSlice.ts
+++ b/src/stores/reducers/listViewSlice.ts
@@ -32,6 +32,9 @@ export const listViewSlice = createSlice({
         resetListView: () => initialState,
         setFilterState: (state, action) => {
             state.filterState = action.payload
+        },
+        resetInventories: (state) => {
+            state.inventories = []
         }
     },
     extraReducers: (builder) => {
@@ -57,6 +60,7 @@ export const listViewSlice = createSlice({
             state.data[inventories[0].name] = state.data[inventories[0].name] ? [...prevData, ...data] : [...data]
             state.loading = false
             state.loadedPages[inventories[0].name] = {cursor, items, records}
+            state.inventoriesDataLoading[action.meta.arg] = false
         })
         builder.addCase(loadItemsByInventory.pending, (state, action) => {
             state.inventoriesDataLoading[action.meta.arg] = true
@@ -64,5 +68,5 @@ export const listViewSlice = createSlice({
     }
 })
 
-export const { resetListView, setFilterState } = listViewSlice.actions
+export const { resetListView, setFilterState, resetInventories } = listViewSlice.actions
 export default listViewSlice.reducer
\ No newline at end of file
