Skip to content

Commit 7773197

Browse files
jbyrne6jbyrne
and
jbyrne
authored
Feature/swodlr UI 114 - implement endpoint for My Data page filtering (#116)
* feature/swodlr-ui-114: implemented filtering endpoint for some my data page properties * feature/swodlr-ui-114: fixed merge marker * feature/swodlr-ui-114: resolved comments by Josh in PR --------- Co-authored-by: jbyrne <[email protected]>
1 parent e84f200 commit 7773197

File tree

8 files changed

+142
-82
lines changed

8 files changed

+142
-82
lines changed

src/components/history/DataPagination.tsx

+7-19
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import { Col, Pagination, Row, Spinner } from "react-bootstrap";
1+
import { Col, Pagination, Row } from "react-bootstrap";
22
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
33
import { setUserProducts } from "../sidebar/actions/productSlice";
44
import { productsPerPage } from "../../constants/rasterParameterConstants";
55
import { useState } from "react";
66

77

88
const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilteredProducts: number, }) => {
9-
const {totalNumberOfProducts, totalNumberOfFilteredProducts} = props
9+
const { totalNumberOfFilteredProducts} = props
1010
const dispatch = useAppDispatch()
1111
const userProducts = useAppSelector((state) => state.product.userProducts)
1212
const allUserProducts = useAppSelector((state) => state.product.allUserProducts)
1313
const [noNextPage, setNoNextPage] = useState<boolean>(false)
1414
const [noPreviousPage, setNoPreviousPage] = useState<boolean>(true)
15-
const [waitingForPagination, setWaitingForPagination] = useState<boolean>(false)
1615
const [currentPageNumber, setCurrentPageNumber] = useState<number>(1)
1716
const numberOfTotalPages = Math.ceil(allUserProducts.length / parseInt(productsPerPage))
1817

@@ -33,16 +32,6 @@ const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilt
3332
}
3433
}
3534

36-
const waitingForPaginationSpinner = () => {
37-
return (
38-
<div>
39-
<Spinner animation="border" role="status">
40-
<span className="visually-hidden">Loading...</span>
41-
</Spinner>
42-
</div>
43-
)
44-
}
45-
4635
const getPaginationItemsWithEllipsis = () => {
4736
let numberOfSlotsFreeLeft = 0
4837
if(currentPageNumber >= numberOfTotalPages-4) {
@@ -78,12 +67,12 @@ const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilt
7867
}
7968
}
8069

81-
if(pagesAllowed[0] > 2) pagesToShow.unshift(<Pagination.Ellipsis />)
82-
if(pagesAllowed[pagesAllowed.length-1] < numberOfTotalPages-1) pagesToShow.push(<Pagination.Ellipsis />)
70+
if(pagesAllowed[0] > 2) pagesToShow.unshift(<Pagination.Ellipsis key='ellipsis-first' />)
71+
if(pagesAllowed[pagesAllowed.length-1] < numberOfTotalPages-1) pagesToShow.push(<Pagination.Ellipsis key='ellipsis-last'/>)
8372
return pagesToShow
8473
}
8574

86-
return waitingForPagination ? waitingForPaginationSpinner() : (
75+
return (
8776
<Row>
8877
<Col xs={2}></Col>
8978
<Col xs={7}>
@@ -99,10 +88,9 @@ const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilt
9988
: null
10089
}
10190
</Col>
102-
<Col xs={3} style={{paddingTop: '15px'}}><h6><b>{totalNumberOfProducts}</b> Total Generated Products</h6></Col>
91+
<Col xs={3} style={{paddingTop: '15px'}}><h6><b>{totalNumberOfFilteredProducts}</b> Total Generated Products</h6></Col>
10392
</Row>
10493
)
10594
}
10695

107-
export default DataPagination;
108-
96+
export default DataPagination;

src/components/history/GeneratedProductHistory.tsx

+16-50
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,17 @@
11
import { Alert, Col, OverlayTrigger, Row, Table, Tooltip, Spinner, Form, DropdownButton, Dropdown, Badge } from "react-bootstrap";
22
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
3-
import { Product, ProductState } from "../../types/graphqlTypes";
3+
import { Product } from "../../types/graphqlTypes";
44
import { useEffect, useState } from "react";
55
import { InfoCircle } from "react-bootstrap-icons";
66
import { generatedProductsLabels, infoIconsToRender, parameterHelp, productsPerPage } from "../../constants/rasterParameterConstants";
77
import { getUserProducts } from "../../user/userData";
88
import { useLocation, useNavigate } from "react-router-dom";
99
import DataPagination from "./DataPagination";
10-
import HistoryFilters from "./HistoryFilters";
11-
import { Adjust, FilterParameters, OutputGranuleExtentFlagOptions, OutputSamplingGridType, RasterResolution } from "../../types/historyPageTypes";
10+
import HistoryFilters, { getFilterParameters, productPassesFilterCheck } from "./HistoryFilters";
1211
import { setShowReGenerateProductModalTrue } from "../sidebar/actions/modalSlice";
1312
import ReGenerateProductsModal from "./ReGenerateProductsModal";
14-
import { setAllUserProducts, setGranulesToReGenerate, setUserProducts, setWaitingForMyDataFiltering, setWaitingForProductsToLoad } from "../sidebar/actions/productSlice";
15-
16-
export const productPassesFilterCheck = (currentFilters: FilterParameters, cycle: number, pass: number, scene: number, outputGranuleExtentFlag: boolean, status: string, outputSamplingGridType: string, rasterResolution: number, dateGenerated: string, utmZoneAdjust?: number, mgrsBandAdjust?: number): boolean => {
17-
let productPassesFilter = true
18-
const outputGranuleExtentFlagMap = ['128 x 128','256 x 128']
19-
20-
if(currentFilters.cycle !== 'none' && currentFilters.cycle !== String(cycle)) {
21-
productPassesFilter = false
22-
}
23-
if (currentFilters.pass !== 'none' && currentFilters.pass !== String(pass)) {
24-
productPassesFilter = false
25-
}
26-
if (currentFilters.scene !== 'none' && currentFilters.scene !== String(scene)) {
27-
productPassesFilter = false
28-
}
29-
if (currentFilters.outputGranuleExtentFlag.length > 0 && !currentFilters.outputGranuleExtentFlag.includes(outputGranuleExtentFlagMap[+outputGranuleExtentFlag] as OutputGranuleExtentFlagOptions)) {
30-
productPassesFilter = false
31-
}
32-
if (currentFilters.status.length > 0 && !currentFilters.status.includes(status as ProductState)) {
33-
productPassesFilter = false
34-
}
35-
if (currentFilters.outputSamplingGridType.length > 0 && !currentFilters.outputSamplingGridType.includes(outputSamplingGridType as OutputSamplingGridType)) {
36-
productPassesFilter = false
37-
}
38-
if (currentFilters.rasterResolution.length > 0 && !currentFilters.rasterResolution.includes(String(rasterResolution) as RasterResolution)) {
39-
productPassesFilter = false
40-
}
41-
if (utmZoneAdjust !== undefined && currentFilters.utmZoneAdjust.length > 0 && !currentFilters.utmZoneAdjust.includes(String(utmZoneAdjust) as Adjust)) {
42-
productPassesFilter = false
43-
}
44-
if (mgrsBandAdjust !== undefined && currentFilters.mgrsBandAdjust.length > 0 && !currentFilters.mgrsBandAdjust.includes(String(mgrsBandAdjust) as Adjust)) {
45-
productPassesFilter = false
46-
}
47-
if(currentFilters.startDate !== 'none' && new Date(dateGenerated) < currentFilters.startDate) {
48-
productPassesFilter = false
49-
}
50-
if(currentFilters.endDate !== 'none' && new Date(dateGenerated) > currentFilters.endDate) {
51-
productPassesFilter = false
52-
}
53-
return productPassesFilter
54-
}
13+
import { setAllUserProducts, setGranulesToReGenerate, setUserProducts, setWaitingForMyDataFiltering, setWaitingForMyDataFilteringReset, setWaitingForProductsToLoad } from "../sidebar/actions/productSlice";
14+
import { defaultUserProductsLimit } from "../../constants/graphqlQueries";
5515

5616
const GeneratedProductHistory = () => {
5717
const dispatch = useAppDispatch()
@@ -60,43 +20,49 @@ const GeneratedProductHistory = () => {
6020
const currentFilters = useAppSelector((state) => state.product.currentFilters)
6121
const waitingForProductsToLoad = useAppSelector((state) => state.product.waitingForProductsToLoad)
6222
const waitingForMyDataFiltering = useAppSelector((state) => state.product.waitingForMyDataFiltering)
23+
const waitingForMyDataFilteringReset = useAppSelector((state) => state.product.waitingForMyDataFilteringReset)
6324
const { search } = useLocation()
6425
const navigate = useNavigate()
6526
const [totalNumberOfProducts, setTotalNumberOfProducts] = useState<number>(0)
6627
const [totalNumberOfFilteredProducts, setTotalNumberOfFilteredProducts] = useState<number>(0)
6728
const [checkedProducts, setCheckedProducts] = useState<Product[]>([])
6829
const [allChecked, setAllChecked] = useState<boolean>(false)
30+
const [hasAlreadyLoadedInitialProducts, setHasAlreadyLoadedInitialProducts] = useState<boolean>(false)
6931

7032
useEffect(() => {
7133
// get the data for the first page
7234
// go through all the user product data to get the id of each one so that
7335
const fetchData = async () => {
7436
if(!waitingForMyDataFiltering) dispatch(setWaitingForProductsToLoad(true))
75-
await getUserProducts({limit: '1000000'}).then(response => {
37+
38+
const productQueryParameters = getFilterParameters(currentFilters, defaultUserProductsLimit)
39+
// add variables for filters
40+
await getUserProducts(productQueryParameters).then(response => {
7641
dispatch(setWaitingForProductsToLoad(false))
7742
// filter products for what is in the filter
7843
const allProducts = response.products as Product[]
7944
setTotalNumberOfProducts(allProducts.length)
8045
const filteredProducts = allProducts.filter(product => {
81-
const {status, utmZoneAdjust, mgrsBandAdjust, outputGranuleExtentFlag, outputSamplingGridType, rasterResolution, timestamp: dateGenerated, cycle, pass, scene, granules} = product
46+
const {status, utmZoneAdjust, mgrsBandAdjust, rasterResolution} = product
8247
const statusToUse = status[0].state
83-
const outputSamplingGridTypeToUse = outputSamplingGridType === 'GEO' ? 'LAT/LON' : outputSamplingGridType
84-
const productPassesFilter = productPassesFilterCheck(currentFilters, cycle, pass, scene, outputGranuleExtentFlag, statusToUse, outputSamplingGridTypeToUse, rasterResolution, dateGenerated, utmZoneAdjust, mgrsBandAdjust)
48+
const productPassesFilter = productPassesFilterCheck(currentFilters, statusToUse, rasterResolution, utmZoneAdjust, mgrsBandAdjust)
8549
if(productPassesFilter) {
8650
return product
8751
} else {
8852
return null
8953
}
9054
})
9155
setTotalNumberOfFilteredProducts(filteredProducts.length)
56+
setHasAlreadyLoadedInitialProducts(true)
9257
dispatch(setAllUserProducts(filteredProducts))
9358
const productsPerPageToInt = parseInt(productsPerPage)
9459
dispatch(setUserProducts(filteredProducts.slice(0, productsPerPageToInt)))
9560
dispatch(setWaitingForMyDataFiltering(false))
61+
dispatch(setWaitingForMyDataFilteringReset(false))
9662
})
9763
}
9864
fetchData().catch(console.error)
99-
}, [currentFilters]);
65+
}, [dispatch, currentFilters, waitingForMyDataFiltering, waitingForMyDataFilteringReset]);
10066

10167
// reset all checked checkbox when going to next page
10268
useEffect(() => {
@@ -226,7 +192,7 @@ const GeneratedProductHistory = () => {
226192
</div>
227193
{<DataPagination totalNumberOfProducts={totalNumberOfProducts} totalNumberOfFilteredProducts={totalNumberOfFilteredProducts} />}
228194
{!waitingForProductsToLoad && userProducts.length === 0 ? <Row>{productHistoryAlert()}</Row> : null}
229-
{waitingForProductsToLoad ? waitingForProductsToLoadSpinner() : null}
195+
{waitingForProductsToLoad && !hasAlreadyLoadedInitialProducts ? waitingForProductsToLoadSpinner() : null}
230196
</div>
231197
</Col>
232198
</Row>

0 commit comments

Comments
 (0)