Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/swodlr UI 114 - implement endpoint for My Data page filtering #116

Merged
merged 8 commits into from
Jun 21, 2024
26 changes: 7 additions & 19 deletions src/components/history/DataPagination.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { Col, Pagination, Row, Spinner } from "react-bootstrap";
import { Col, Pagination, Row } from "react-bootstrap";
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
import { setUserProducts } from "../sidebar/actions/productSlice";
import { productsPerPage } from "../../constants/rasterParameterConstants";
import { useState } from "react";


const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilteredProducts: number, }) => {
const {totalNumberOfProducts, totalNumberOfFilteredProducts} = props
const { totalNumberOfFilteredProducts} = props
const dispatch = useAppDispatch()
const userProducts = useAppSelector((state) => state.product.userProducts)
const allUserProducts = useAppSelector((state) => state.product.allUserProducts)
const [noNextPage, setNoNextPage] = useState<boolean>(false)
const [noPreviousPage, setNoPreviousPage] = useState<boolean>(true)
const [waitingForPagination, setWaitingForPagination] = useState<boolean>(false)
const [currentPageNumber, setCurrentPageNumber] = useState<number>(1)
const numberOfTotalPages = Math.ceil(allUserProducts.length / parseInt(productsPerPage))

Expand All @@ -33,16 +32,6 @@ const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilt
}
}

const waitingForPaginationSpinner = () => {
return (
<div>
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
</div>
)
}

const getPaginationItemsWithEllipsis = () => {
let numberOfSlotsFreeLeft = 0
if(currentPageNumber >= numberOfTotalPages-4) {
Expand Down Expand Up @@ -78,12 +67,12 @@ const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilt
}
}

if(pagesAllowed[0] > 2) pagesToShow.unshift(<Pagination.Ellipsis />)
if(pagesAllowed[pagesAllowed.length-1] < numberOfTotalPages-1) pagesToShow.push(<Pagination.Ellipsis />)
if(pagesAllowed[0] > 2) pagesToShow.unshift(<Pagination.Ellipsis key='ellipsis-first' />)
if(pagesAllowed[pagesAllowed.length-1] < numberOfTotalPages-1) pagesToShow.push(<Pagination.Ellipsis key='ellipsis-last'/>)
return pagesToShow
}

return waitingForPagination ? waitingForPaginationSpinner() : (
return (
<Row>
<Col xs={2}></Col>
<Col xs={7}>
Expand All @@ -99,10 +88,9 @@ const DataPagination = (props: {totalNumberOfProducts: number, totalNumberOfFilt
: null
}
</Col>
<Col xs={3} style={{paddingTop: '15px'}}><h6><b>{totalNumberOfProducts}</b> Total Generated Products</h6></Col>
<Col xs={3} style={{paddingTop: '15px'}}><h6><b>{totalNumberOfFilteredProducts}</b> Total Generated Products</h6></Col>
</Row>
)
}

export default DataPagination;

export default DataPagination;
66 changes: 16 additions & 50 deletions src/components/history/GeneratedProductHistory.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,17 @@
import { Alert, Col, OverlayTrigger, Row, Table, Tooltip, Spinner, Form, DropdownButton, Dropdown, Badge } from "react-bootstrap";
import { useAppDispatch, useAppSelector } from "../../redux/hooks";
import { Product, ProductState } from "../../types/graphqlTypes";
import { Product } from "../../types/graphqlTypes";
import { useEffect, useState } from "react";
import { InfoCircle } from "react-bootstrap-icons";
import { generatedProductsLabels, infoIconsToRender, parameterHelp, productsPerPage } from "../../constants/rasterParameterConstants";
import { getUserProducts } from "../../user/userData";
import { useLocation, useNavigate } from "react-router-dom";
import DataPagination from "./DataPagination";
import HistoryFilters from "./HistoryFilters";
import { Adjust, FilterParameters, OutputGranuleExtentFlagOptions, OutputSamplingGridType, RasterResolution } from "../../types/historyPageTypes";
import HistoryFilters, { getFilterParameters, productPassesFilterCheck } from "./HistoryFilters";
import { setShowReGenerateProductModalTrue } from "../sidebar/actions/modalSlice";
import ReGenerateProductsModal from "./ReGenerateProductsModal";
import { setAllUserProducts, setGranulesToReGenerate, setUserProducts, setWaitingForMyDataFiltering, setWaitingForProductsToLoad } from "../sidebar/actions/productSlice";

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 => {
let productPassesFilter = true
const outputGranuleExtentFlagMap = ['128 x 128','256 x 128']

if(currentFilters.cycle !== 'none' && currentFilters.cycle !== String(cycle)) {
productPassesFilter = false
}
if (currentFilters.pass !== 'none' && currentFilters.pass !== String(pass)) {
productPassesFilter = false
}
if (currentFilters.scene !== 'none' && currentFilters.scene !== String(scene)) {
productPassesFilter = false
}
if (currentFilters.outputGranuleExtentFlag.length > 0 && !currentFilters.outputGranuleExtentFlag.includes(outputGranuleExtentFlagMap[+outputGranuleExtentFlag] as OutputGranuleExtentFlagOptions)) {
productPassesFilter = false
}
if (currentFilters.status.length > 0 && !currentFilters.status.includes(status as ProductState)) {
productPassesFilter = false
}
if (currentFilters.outputSamplingGridType.length > 0 && !currentFilters.outputSamplingGridType.includes(outputSamplingGridType as OutputSamplingGridType)) {
productPassesFilter = false
}
if (currentFilters.rasterResolution.length > 0 && !currentFilters.rasterResolution.includes(String(rasterResolution) as RasterResolution)) {
productPassesFilter = false
}
if (utmZoneAdjust !== undefined && currentFilters.utmZoneAdjust.length > 0 && !currentFilters.utmZoneAdjust.includes(String(utmZoneAdjust) as Adjust)) {
productPassesFilter = false
}
if (mgrsBandAdjust !== undefined && currentFilters.mgrsBandAdjust.length > 0 && !currentFilters.mgrsBandAdjust.includes(String(mgrsBandAdjust) as Adjust)) {
productPassesFilter = false
}
if(currentFilters.startDate !== 'none' && new Date(dateGenerated) < currentFilters.startDate) {
productPassesFilter = false
}
if(currentFilters.endDate !== 'none' && new Date(dateGenerated) > currentFilters.endDate) {
productPassesFilter = false
}
return productPassesFilter
}
import { setAllUserProducts, setGranulesToReGenerate, setUserProducts, setWaitingForMyDataFiltering, setWaitingForMyDataFilteringReset, setWaitingForProductsToLoad } from "../sidebar/actions/productSlice";
import { defaultUserProductsLimit } from "../../constants/graphqlQueries";

const GeneratedProductHistory = () => {
const dispatch = useAppDispatch()
Expand All @@ -60,43 +20,49 @@ const GeneratedProductHistory = () => {
const currentFilters = useAppSelector((state) => state.product.currentFilters)
const waitingForProductsToLoad = useAppSelector((state) => state.product.waitingForProductsToLoad)
const waitingForMyDataFiltering = useAppSelector((state) => state.product.waitingForMyDataFiltering)
const waitingForMyDataFilteringReset = useAppSelector((state) => state.product.waitingForMyDataFilteringReset)
const { search } = useLocation()
const navigate = useNavigate()
const [totalNumberOfProducts, setTotalNumberOfProducts] = useState<number>(0)
const [totalNumberOfFilteredProducts, setTotalNumberOfFilteredProducts] = useState<number>(0)
const [checkedProducts, setCheckedProducts] = useState<Product[]>([])
const [allChecked, setAllChecked] = useState<boolean>(false)
const [hasAlreadyLoadedInitialProducts, setHasAlreadyLoadedInitialProducts] = useState<boolean>(false)

useEffect(() => {
// get the data for the first page
// go through all the user product data to get the id of each one so that
const fetchData = async () => {
if(!waitingForMyDataFiltering) dispatch(setWaitingForProductsToLoad(true))
await getUserProducts({limit: '1000000'}).then(response => {

const productQueryParameters = getFilterParameters(currentFilters, defaultUserProductsLimit)
// add variables for filters
await getUserProducts(productQueryParameters).then(response => {
dispatch(setWaitingForProductsToLoad(false))
// filter products for what is in the filter
const allProducts = response.products as Product[]
setTotalNumberOfProducts(allProducts.length)
const filteredProducts = allProducts.filter(product => {
const {status, utmZoneAdjust, mgrsBandAdjust, outputGranuleExtentFlag, outputSamplingGridType, rasterResolution, timestamp: dateGenerated, cycle, pass, scene, granules} = product
const {status, utmZoneAdjust, mgrsBandAdjust, rasterResolution} = product
const statusToUse = status[0].state
const outputSamplingGridTypeToUse = outputSamplingGridType === 'GEO' ? 'LAT/LON' : outputSamplingGridType
const productPassesFilter = productPassesFilterCheck(currentFilters, cycle, pass, scene, outputGranuleExtentFlag, statusToUse, outputSamplingGridTypeToUse, rasterResolution, dateGenerated, utmZoneAdjust, mgrsBandAdjust)
const productPassesFilter = productPassesFilterCheck(currentFilters, statusToUse, rasterResolution, utmZoneAdjust, mgrsBandAdjust)
if(productPassesFilter) {
return product
} else {
return null
}
})
setTotalNumberOfFilteredProducts(filteredProducts.length)
setHasAlreadyLoadedInitialProducts(true)
dispatch(setAllUserProducts(filteredProducts))
const productsPerPageToInt = parseInt(productsPerPage)
dispatch(setUserProducts(filteredProducts.slice(0, productsPerPageToInt)))
dispatch(setWaitingForMyDataFiltering(false))
dispatch(setWaitingForMyDataFilteringReset(false))
})
}
fetchData().catch(console.error)
}, [currentFilters]);
}, [dispatch, currentFilters, waitingForMyDataFiltering, waitingForMyDataFilteringReset]);

// reset all checked checkbox when going to next page
useEffect(() => {
Expand Down Expand Up @@ -226,7 +192,7 @@ const GeneratedProductHistory = () => {
</div>
{<DataPagination totalNumberOfProducts={totalNumberOfProducts} totalNumberOfFilteredProducts={totalNumberOfFilteredProducts} />}
{!waitingForProductsToLoad && userProducts.length === 0 ? <Row>{productHistoryAlert()}</Row> : null}
{waitingForProductsToLoad ? waitingForProductsToLoadSpinner() : null}
{waitingForProductsToLoad && !hasAlreadyLoadedInitialProducts ? waitingForProductsToLoadSpinner() : null}
</div>
</Col>
</Row>
Expand Down
Loading
Loading