Projekt

Obecné

Profil

« Předchozí | Další » 

Revize a6999074

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

re #10871: PlanViewPage: ListView integration

Zobrazit rozdíly:

src/api/planservice.ts
32 32
@room: id of room in which we are looking for items
33 33
@place: id of place inside a room in which we are looking for items
34 34
*/
35
export const getPlanItemsRequest = async (params: {activeTab: number, page: number, room: number, items: number, place?: number, inventory?: string}) => {
35
export const getPlanItemsRequest = async (params: { cursor: number, room: number, items?: number, place?: number, inventory?: string}) => {
36 36

  
37 37

  
38
    let url = `search_v2?activeTab=${params.activeTab}&page=${params.page}&tabbed=true&room=${params.room}&cursor=${(params.page - 1)*params.items}&items=${params.items}`
38
    let url = `search_v2?tabbed=true&room=${params.room}&cursor=${params.cursor}`
39 39

  
40 40
    if(params.place){
41 41
        url += `&place=${params.place}`
......
44 44
    if(params.inventory){
45 45
        url += `&inventory=${params.inventory}`
46 46
    }
47
    else{
48
        url += `&activeTab=0`
49
    }
50

  
51
    if(params.items){
52
        url += `&items=${params.items}`
53
    }
47 54

  
48 55
    console.log(url)
49 56

  
src/components/listView/ListView.tsx
10 10
import { Inventory } from "../../types/searchFormTypes"
11 11

  
12 12
type ListViewProps = {
13
    navigation: any,
13
    navigation: any
14 14

  
15
    inventories: Inventory[],
16
    numOfResults?: number,
15
    inventories: Inventory[]
16
    numOfResults?: number
17 17

  
18 18
    lastError?: string
19 19

  
......
21 21
    loadedPages: LoadedPagesOfInventories
22 22
    inventoriesDataLoading: {[key: string]: boolean}
23 23

  
24
    handleLoadMoreItems: (inventoryName: string, cursor: number) => void; 
24
    handleLoadMoreItems: (inventoryName: string, cursor: number) => void;
25
    
26
    hideHeaderText?: boolean
25 27
}
26 28

  
27 29
const ListView = (props: ListViewProps) => {
......
52 54

  
53 55
    return (
54 56
        <>
55
            <Text fontSize={16} fontWeight={"bold"} color={"primary.500"}>Search results{numberOfResults ? ` (${numberOfResults})` : ""}:</Text>
57
            {!props.hideHeaderText && <Text fontSize={16} fontWeight={"bold"} color={"primary.500"}>Search results{numberOfResults ? ` (${numberOfResults})` : ""}:</Text>}
56 58
            {inventories && inventories.length > 0 ?
57 59
                (inventories.length > 1 ?
58 60
                    inventories.map((inventory) => (
src/pages/PlanViewPage.tsx
1 1
import React, { useEffect, useState } from "react"
2 2
import { useDispatch, useSelector } from "react-redux"
3 3
import { AppDispatch, RootState } from "../stores/store"
4
import { useWindowDimensions } from "react-native"
5 4
import LoadingBox from "../components/loading/LoadingBox"
6 5
import { log } from "../logging/logger"
7 6
import { DrawerScreenProps } from "@react-navigation/drawer"
8 7
import { RootDrawerParamList } from "./Navigation"
9
import { Box, CloseIcon, Select, useToast, Button, Flex, Text } from "native-base"
8
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, Center, VStack, ScrollView } from "native-base"
10 9
import { ErrorToast } from "../components/toast/ErrorToast"
11 10
import { Floor, Place, Room } from "../types/plan"
12 11
import { getFloorList, getPlanInventories, getPlanItems } from "../stores/actions/planThunks"
13 12
import { login } from "../stores/actions/userThunks"
14 13
import { getPlanItemsRequest } from "../api/planservice"
15 14
import ItemPreview from "../components/listView/ItemPreview"
16
import { parseArtists, parseImage } from "../components/listView/ListViewInventoryGroup"
17 15
import PlanView from "../components/plan/PlanView"
18 16
import { BASE_API_URL } from "../api/constants"
17
import ListView from "../components/listView/ListView"
18
import SearchForm from "../components/search/SearchForm"
19
import { loadItemsByInventory } from "../stores/actions/listViewThunks"
19 20

  
20 21
const PlanViewPage = ({ route, navigation }: DrawerScreenProps<RootDrawerParamList, 'Plan'>) => {
21 22

  
22
  const layout = useWindowDimensions();
23
  const dispatch = useDispatch<AppDispatch>()
23 24

  
24 25
  // Route: set selected room / place from 
25 26
  useEffect(() => {
......
28 29
    dispatch(getFloorList())
29 30
  }, [])
30 31

  
31
  const pageSize = 20
32
  const currentPage = 0
33
  const totalPages = 100
34

  
35 32
  const DEFAULT_FLOOR = "first_floor"
36 33

  
37 34
  const [selectedFloor, setSelectedFloor] = useState<Floor | undefined>(undefined)
38 35
  const [selectedRoom, setSelectedRoom] = useState<Room | undefined>(undefined)
39 36
  const [selectedPlace, setSelectedPlace] = useState<Place | undefined>(undefined)
40 37

  
41
  const dispatch = useDispatch<AppDispatch>();
38
  const { floorListLoading, floorList, totalItemsCount, lastError } = useSelector((state: RootState) => state.planViewState)
39

  
40
  const inventories = useSelector((state: RootState) => state.planViewState.itemInventories)
41
  const inventoriesLoading = useSelector((state: RootState) => state.planViewState.itemInventoriesLoading)
42 42

  
43
  const { floorListLoading, floorList, itemListLoading, itemList, itemInventories, itemInventoriesLoading, totalItemsCount, lastError } = useSelector((state: RootState) => state.planViewState)
43
  const numberOfResults = useSelector((state: RootState) => state.planViewState.totalItemsCount)
44

  
45
  const data = useSelector((state: RootState) => state.planViewState.itemList)
46
  const dataLoading = useSelector((state: RootState) => state.planViewState.itemListLoading)
47
  const pagination = useSelector((state: RootState) => state.planViewState.itemListPagination)
44 48

  
45 49
  const toast = useToast();
46 50

  
47 51
  useEffect(() => {
48 52
    if (floorList && !selectedFloor) {
53

  
49 54
      if (route.params && route.params.roomId) {
50 55

  
51 56
        selectRoom(route.params.roomId)
......
54 59
          selectPlace(route.params.placeId)
55 60
        }
56 61

  
57
        if (!itemListLoading) {
58
          searchSubmit(currentPage, route.params.roomId, route.params.placeId)
59
        }
62
        // if (!itemListLoading) {
63
        //   searchSubmit(currentPage, route.params.roomId, route.params.placeId)
64
        // }
60 65

  
61 66
      }
62 67
      else {
......
66 71
  }, [floorList, route.params.roomId, route.params.placeId])
67 72

  
68 73
  useEffect(() => {
69
    if (floorList && selectedRoom) {
70
      if (!itemInventoriesLoading) {
71
        dispatch(getPlanInventories({ room: selectedRoom.id, place: selectedPlace?.id }))
74
    if (floorList) {
75
      if (!inventoriesLoading) {
76
        dispatch(getPlanInventories({ room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
72 77
      }
73 78
    }
74 79
  }, [selectedPlace, selectedRoom])
......
89 94
  }, [lastError])
90 95

  
91 96

  
92
  const searchSubmit = (pageNumber: number, roomId: number, placeId?: number) => {
97
  const searchSubmit = (roomId: number, placeId?: number) => {
93 98
    log.debug("PlanView", "searchSubmit")
94 99

  
95 100
    console.log("searching " + roomId + ", " + placeId)
96 101

  
97
    dispatch(getPlanItems({ page: pageNumber, items: pageSize, room: roomId, place: placeId, activeTab: 0 }))
102
    dispatch(getPlanInventories({ room: roomId, place: placeId }))
98 103
  }
99 104

  
100 105
  const selectFloor = (floorId: string) => {
......
150 155

  
151 156
  const clearForm = () => {
152 157
    log.debug("PlanView", "clearForm")
153
    selectFloor(DEFAULT_FLOOR)
154
    setSelectedRoom(undefined)
155 158
    setSelectedPlace(undefined)
159
    setSelectedRoom(undefined)
160
    selectFloor(DEFAULT_FLOOR)
156 161
  }
157 162

  
158 163
  const onBackPressed = () => {
......
161 166
  }
162 167

  
163 168
  return (
164
    <Box>
165
      {/* Selection */}
166

  
167
      {
168
        floorListLoading ?
169
          <LoadingBox text="Floor list loading"></LoadingBox>
170
          :
171
          <>
172
            {/* Floor */}
173
            <Select
174
              mt={2.5}
175
              ml={2.5}
176
              mr={2.5}
177

  
178
              placeholder={"Floor"}
179
              selectedValue={selectedFloor?.id}
180
              onValueChange={selectFloor}
181
              variant="rounded"
182
            >
183
              {floorList.map((floor, index) => {
184
                return (
185
                  <Select.Item value={floor.id} label={floor.label} />
186
                );
187
              })}
188
            </Select>
189

  
190
            {/* Room */}
191
            {selectedFloor && selectedFloor.roomList && selectedFloor.roomList.length > 0 &&
192
              < Select
193
                mt={2.5}
194
                ml={2.5}
195
                mr={2.5}
196

  
197
                placeholder={"Room"}
198
                selectedValue={selectedRoom?.id.toString()}
199
                onValueChange={(value: string) => selectRoom(parseInt(value))}
200
                variant="rounded"
201
              >
202
                {selectedFloor?.roomList?.map((room, index) => {
203
                  if (room.room_list) {
169
    <Center m={2} mr={0} mb={6} flex={1}>
170

  
171
      <ScrollView flex={1} w={"100%"} >
172
        <VStack space={1} mr={4}>
173

  
174
          {/* Selection */}
175

  
176
          {
177
            floorListLoading ?
178
              <LoadingBox text="Floor list loading"></LoadingBox>
179
              :
180
              <>
181
                {/* Floor */}
182
                <Select
183
                  mt={2.5}
184
                  ml={2.5}
185
                  mr={2.5}
186

  
187
                  placeholder={"Floor"}
188
                  selectedValue={selectedFloor?.id}
189
                  onValueChange={selectFloor}
190
                  variant="rounded"
191
                >
192
                  {floorList.map((floor, index) => {
204 193
                    return (
205
                      <Select.Item value={room.id.toString()} label={room.label} />
194
                      <Select.Item value={floor.id} label={floor.label} />
206 195
                    );
207
                  }
208
                })}
209
              </Select>
210
            }
211

  
212
            {/* Place */}
213
            {selectedRoom && selectedRoom.places && selectedRoom.places.length > 0 &&
214
              <Select
215
                mt={2.5}
216
                ml={2.5}
217
                mr={2.5}
218

  
219
                placeholder={"Place"}
220
                selectedValue={selectedPlace?.id.toString()}
221
                onValueChange={(value: string) => selectPlace(parseInt(value))}
222
                variant="rounded"
223
              >
224
                {selectedRoom?.places?.map((place, index) => {
225
                  return (
226
                    <Select.Item value={place.id.toString()} label={place.label} />
227
                  );
228
                })}
229
              </Select>
230
            }
231

  
232
            {/* Filter */}
233
            <Flex direction="row" alignItems="center" justify="flex-end"
234
              mt={2.5}
235
              ml={2.5}
236
              mr={3}
237
            >
238
              <Button
239
                endIcon={
240
                  <CloseIcon size="xs" />
196
                  })}
197
                </Select>
198

  
199
                {/* Room */}
200
                {selectedFloor && selectedFloor.roomList && selectedFloor.roomList.length > 0 &&
201
                  < Select
202
                    mt={2.5}
203
                    ml={2.5}
204
                    mr={2.5}
205

  
206
                    placeholder={"Room"}
207
                    selectedValue={selectedRoom?.id.toString()}
208
                    onValueChange={(value: string) => selectRoom(parseInt(value))}
209
                    variant="rounded"
210
                  >
211
                    {selectedFloor?.roomList?.map((room, index) => {
212
                      if (room.room_list) {
213
                        return (
214
                          <Select.Item value={room.id.toString()} label={room.label} />
215
                        );
216
                      }
217
                    })}
218
                  </Select>
241 219
                }
242
                onPress={clearForm}
243
                variant="outline"
244
                color="primary.500"
245
                borderColor="primary.100"
246
                mr={2}
247
                borderRadius={15}
248
                size={"md"}
249
              >
250
                Reset
251
              </Button>
252
              <Button
253
                onPress={() => {
254
                  if (selectedRoom && !selectedPlace) {
255
                    searchSubmit(currentPage, selectedRoom.id)
256
                  }
257
                  else if (selectedRoom && selectedPlace) {
258
                    searchSubmit(currentPage, selectedRoom.id, selectedPlace.id)
259
                  }
260

  
261
                }}
262
                colorScheme="primary"
263
                background={"primary.100"}
264
                variant="solid"
265
                borderRadius={15}
266
                size={"md"}
267
              >
268
                Search
269
              </Button>
270
            </Flex>
271
          </>
272
      }
273

  
274

  
275 220

  
276
      {/* Plan */}
277
      {/* temporary prototype */}
278

  
279
      {selectedFloor && !floorListLoading &&
280
        <PlanView imageUrl={BASE_API_URL + "/downloads/" + selectedFloor.id} />
281
      }
221
                {/* Place */}
222
                {selectedRoom && selectedRoom.places && selectedRoom.places.length > 0 &&
223
                  <Select
224
                    mt={2.5}
225
                    ml={2.5}
226
                    mr={2.5}
227

  
228
                    placeholder={"Place"}
229
                    selectedValue={selectedPlace?.id.toString()}
230
                    onValueChange={(value: string) => selectPlace(parseInt(value))}
231
                    variant="rounded"
232
                  >
233
                    {selectedRoom?.places?.map((place, index) => {
234
                      return (
235
                        <Select.Item value={place.id.toString()} label={place.label} />
236
                      );
237
                    })}
238
                  </Select>
239
                }
282 240

  
283
      {/* Item List */}
284
      <>
285
        {itemInventoriesLoading ?
286
          <LoadingBox text="Loading available inventories..." />
287
          :
241
                {/* Filter */}
242
                <Flex direction="row" alignItems="center" justify="flex-end"
243
                  mt={2.5}
244
                  ml={2.5}
245
                  mr={3}
246
                >
247
                  <Button
248
                    endIcon={
249
                      <CloseIcon size="xs" />
250
                    }
251
                    onPress={clearForm}
252
                    variant="outline"
253
                    color="primary.500"
254
                    borderColor="primary.100"
255
                    mr={2}
256
                    borderRadius={15}
257
                    size={"md"}
258
                  >
259
                    Reset
260
                  </Button>
261
                  <Button
262
                    onPress={() => {
263
                      if (selectedRoom && !selectedPlace) {
264
                        searchSubmit(selectedRoom.id)
265
                      }
266
                      else if (selectedRoom && selectedPlace) {
267
                        searchSubmit(selectedRoom.id, selectedPlace.id)
268
                      }
269

  
270
                    }}
271
                    colorScheme="primary"
272
                    background={"primary.100"}
273
                    variant="solid"
274
                    borderRadius={15}
275
                    size={"md"}
276
                  >
277
                    Search
278
                  </Button>
279
                </Flex>
280
              </>
281
          }
282

  
283
          {/* Plan */}
284
          {/* temporary prototype */}
285

  
286
          {/* {selectedFloor && !floorListLoading &&
287
            <PlanView imageUrl={BASE_API_URL + "/downloads/" + selectedFloor.id} />
288
          } */}
289

  
290
          {/* Item List */}
288 291
          <>
289
            <Text>TODO view inventories in SearchItemPreview way</Text>
290
            {itemInventories.map((inventory) => {
291
              <Text>{inventory.label}</Text>
292
            })}
292
            {inventoriesLoading ?
293
              <LoadingBox text="Loading available inventories..." />
294
              :
295
              <Box mt={2.5} ml={2.5}>
296
                <ListView
297

  
298
                  navigation={navigation}
299
                  hideHeaderText
300

  
301
                  inventories={inventories}
302
                  numOfResults={numberOfResults}
303

  
304
                  data={data}
305
                  loadedPages={pagination ?? {}}
306
                  inventoriesDataLoading={dataLoading ?? {}}
307
                  handleLoadMoreItems={(inventoryName: string, cursor: number) => {
308
                    dispatch(getPlanItems({ cursor: cursor, inventory: inventoryName, room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
309
                  }
310
                  }
311
                />
312
              </Box>
313
            }
293 314
          </>
294 315

  
295
        }
296
        {/* 
297
        {itemList.map((item, index) => {
298
          return (
299
            <Box>
300
              <ItemPreview
301
                // @ts-ignore
302
                caption={item.object[0].caption}
303
                title={item.text}
304
                name={parseArtists(item)}
305
                image={parseImage(item)}
306
                itemId={item.xml_id}
307
                inventoryLabel={item.inventory.label}
308
                navigation={navigation}
309
              />
310
            </Box> */}
311
      </>
312

  
313

  
314
    </Box >
316
        </VStack>
317
      </ScrollView>
318
    </Center>
315 319

  
316 320

  
317 321
  );
src/stores/actions/planThunks.ts
2 2
import { SortOptions } from "../../types/general";
3 3
import { Note } from "../../types/note";
4 4
import { getPlanAllRequest, getPlanItemsRequest } from "../../api/planservice";
5
import { Floor, InventoryTab, Room } from "../../types/plan";
5
import { Floor, Room } from "../../types/plan";
6 6
import { ItemPreviewType } from "../../types/listViewTypes";
7 7
import { StringLiteralType } from "typescript";
8
import { Inventory } from "../../types/searchFormTypes";
8 9

  
9 10
export const getFloorList = createAsyncThunk(
10 11
    "plan/getFloorList",
......
60 61
    async (params: { room: number, place?: number }) => {
61 62
        try {
62 63
            try {
63
                const response = await getPlanItemsRequest({ activeTab: 0, page: 1, room: params.room, items: 1, place: params.place })
64
                const response = await getPlanItemsRequest({ cursor: 0, room: params.room, items: 1, place: params.place })
64 65
                if (response.status === 200) {
65 66

  
66
                    let inventories: InventoryTab[] = []
67
                    console.log("response")
68
                    console.log(response.data.pagination.inventories)
67 69

  
68
                    for(let i = 0; i < response.data.pagination.inventories; i++){
69
                        let inventory = response.data.pagination.inventories[i]
70
                        
71
                        inventories.push({
72
                            tab: i,
73
                            label: inventory.label,
74
                            key: inventory.name
75
                        })
76
                    }
77

  
78
                    let allInventoriesRecords = response.data.pagination.records
79

  
80
                    console.log(inventories)
81
                    console.log(allInventoriesRecords)
70
                    const inventories: Inventory[] = response.data.pagination.inventories
71
                    const allInventoriesRecords = response.data.pagination.records
82 72

  
83 73
                    return {
84 74
                        inventories: inventories,
85
                        allInventoriesRecords : allInventoriesRecords
75
                        allInventoriesRecords: allInventoriesRecords
86 76
                    }
87 77
                } else {
88 78
                    return Promise.reject(response.data ? response.data : "Get plan items request failed")
......
99 89

  
100 90
export const getPlanItems = createAsyncThunk(
101 91
    "plan/getPlanItems",
102
    async (params: { activeTab: number, page: number, room: number, items: number, place?: number, inventory?: string }) => {
92
    async (params: { cursor: number, room: number, place?: number, inventory: string }) => {
103 93
        try {
104 94
            try {
105
                const response = await getPlanItemsRequest({ activeTab: params.activeTab, page: params.page, room: params.room, items: params.items, place: params.place, inventory: params.inventory })
95
                const response = await getPlanItemsRequest({ cursor: params.cursor, room: params.room, place: params.place, inventory: params.inventory })
106 96
                if (response.status === 200) {
107 97

  
108
                    let items: ItemPreviewType[] = response.data.data
109
                    let totalItemsCountByInventory: number = response.data.pagination.records
98
                    const items: ItemPreviewType[] = response.data.data
99
                    const inventoryPagination = {
100
                        cursor: response.data.pagination.cursor,
101
                        items: response.data.pagination.items,
102
                        records: response.data.pagination.records
103
                    }
110 104

  
111 105
                    return {
112 106
                        items: items,
113
                        totalItemsCount: totalItemsCountByInventory,
107
                        inventoryPagination: inventoryPagination,
114 108
                    }
115 109
                } else {
116 110
                    return Promise.reject(response.data ? response.data : "Get plan items request failed")
src/stores/reducers/planSlice.ts
5 5
const initialState: PlanViewState = {
6 6
    lastError: "",
7 7

  
8

  
9 8
    // TODO backend -> retrieve list of floors, not static -> not implemented at the time of coding
10 9
    floorList: [
11
        { label: "Ground floor", id: "ground_floor", roomList: [] },
12
        { label: "First floor", id: "first_floor", roomList: [] },
13
        { label: "Second floor", id: "second_floor", roomList: [] }
14 10
    ],
15 11
    floorListLoading: false,
16 12

  
17 13
    itemInventories: [],
14
    itemInventoriesLoading: false,
18 15

  
19
    itemList: [],
16
    // reseting itemList
17
    itemListLoading: {},
18
    itemList: {},
19
    itemListPagination: {},
20 20
}
21 21

  
22 22
export const planSlice = createSlice({
......
27 27

  
28 28
        // getFloorList
29 29
        builder.addCase(getFloorList.fulfilled, (state, action) => {
30

  
31 30
            state.floorList = action.payload
32 31
            state.floorListLoading = false;
33 32
        })
......
41 40

  
42 41
        // getPlanItems
43 42
        builder.addCase(getPlanItems.fulfilled, (state, action) => {
44
            state.itemList = action.payload.items
45
            state.itemListLoading = false;
43
            if (!state.itemList) {
44
                state.itemList = {}
45
            }
46

  
47
            if (action.meta.arg.inventory in state.itemList) {
48
                state.itemList[action.meta.arg.inventory] = state.itemList[action.meta.arg.inventory].concat(action.payload.items)
49
            }
50
            else {
51
                state.itemList[action.meta.arg.inventory] = action.payload.items
52
            }
53

  
54
            if (!state.itemListLoading) {
55
                state.itemListLoading = {}
56
            }
57
            state.itemListLoading[action.meta.arg.inventory] = false;
58

  
59
            if (!state.itemListPagination) {
60
                state.itemListPagination = {}
61
            }
62
            state.itemListPagination[action.meta.arg.inventory] = action.payload.inventoryPagination;
46 63
        })
64

  
47 65
        builder.addCase(getPlanItems.pending, (state, action) => {
48
            state.itemListLoading = true;
66

  
67
            if (!state.itemListLoading) {
68
                state.itemListLoading = {}
69
            }
70
            state.itemListLoading[action.meta.arg.inventory] = true;
49 71
        })
50 72
        builder.addCase(getPlanItems.rejected, (state, action) => {
51
            state.itemListLoading = false;
73

  
74
            if (!state.itemListLoading) {
75
                state.itemListLoading = {}
76
            }
77
            state.itemListLoading[action.meta.arg.inventory] = false;
52 78
            state.lastError = action.error.message
53 79
        })
54 80

  
55
        
56 81
        // getPlanInventories
57 82
        builder.addCase(getPlanInventories.fulfilled, (state, action) => {
58 83
            state.itemInventories = action.payload.inventories
59 84
            state.totalItemsCount = action.payload.allInventoriesRecords
60 85
            state.itemInventoriesLoading = false;
86

  
87
            // reseting itemList
88
            state.itemListLoading = {}
89
            state.itemList = {}
90
            state.itemListPagination = {}
61 91
        })
62 92
        builder.addCase(getPlanInventories.pending, (state, action) => {
63 93
            state.itemInventoriesLoading = true;
src/types/plan.ts
1
import { ItemPreviewType } from "./listViewTypes"
1
import { ItemPreviewType, LoadedPagesOfInventories } from "./listViewTypes"
2
import { Inventory } from "./searchFormTypes"
2 3

  
3 4

  
4 5
export type Floor = {
......
33 34
    label: string
34 35
}
35 36

  
36

  
37
export type InventoryTab = { tab: number, key: string, label: string }
38

  
39

  
40 37
export type PlanViewState = {
41 38

  
42 39
    // floorList
43 40
    floorListLoading?: boolean
44 41
    floorList: Floor[]
45 42

  
46

  
47
    // items
48
    itemInventories: InventoryTab[],
49
    itemInventoriesLoading?: boolean,
50

  
51
    itemListLoading?: boolean,
52
    itemList: ItemPreviewType[]
43
    // inventories
44
    itemInventories: Inventory[]
45
    itemInventoriesLoading?: boolean
53 46
    totalItemsCount?: number
54 47

  
48
    // itemsx
49
    itemListPagination?: LoadedPagesOfInventories
50
    itemListLoading?: { [key: string]: boolean }
51
    itemList: Record<string, ItemPreviewType[]>
52

  
55 53
    // plan
56 54
    // @TODO
57 55

  
56

  
57
    // last error
58 58
    lastError?: string
59 59
}

Také k dispozici: Unified diff