Skip to content

Commit

Permalink
issue/swodlr-ui-edsc-integration: remove slashes from cmr urls
Browse files Browse the repository at this point in the history
  • Loading branch information
jbyrne committed Sep 26, 2024
1 parent 927cbee commit d746a76
Show file tree
Hide file tree
Showing 21 changed files with 641 additions and 397 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ on:
commit:
type: string
description: Custom commit hash

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
Expand All @@ -58,11 +58,14 @@ jobs:
- name: Initial checkout ${{ github.ref }}
if: github.event.inputs.commit == ''
uses: actions/checkout@v4
with:
token: ${{ steps.podaac-cicd.outputs.token }}
- name: Adjust to proper commit hash ${{ github.event.inputs.commit }}
if: github.event.inputs.commit != ''
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit }}
token: ${{ steps.podaac-cicd.outputs.token }}
- name: get-npm-version
id: package-version
uses: martinbeentjes/[email protected]
Expand Down Expand Up @@ -121,7 +124,7 @@ jobs:
echo "deploy_env=${{ env.TARGET_ENV }}" >> $GITHUB_OUTPUT
VENUE=$(echo "${{ env.TARGET_ENV }}" | tr '[:upper:]' '[:lower:]')
echo "deploy_env_lower=$VENUE" >> $GITHUB_OUTPUT
## Build
## Build
- uses: hashicorp/setup-terraform@v2
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
Expand Down
1 change: 0 additions & 1 deletion CHANGE

This file was deleted.

34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

## [1.2.0]

### Changed
- [issues/114](https://github.com/podaac/swodlr-ui/issues/114): My data page now uses server side filtering for most columns

## [1.1.1]

### Fixed
- UI was getting API version from incorrect venue

## [1.1.0]

### Added
- Feature/swodlr UI 102 - refactor spatial search validation (#111)
- Feature/swodlr UI sci orbit message (#112)
- Feature/swodlr UI 107 - gray out some product customization options (#110)
- Feature/demo uwg june2024 - bug fixes (#109)
- Feature/swodlr UI 70 - add filtering to my data page and re-generation button (#105)
- Feature/swodlr UI 101 - add file name to granule footprint (#103)
- Issues/swodlr UI 92 - fix tutorial bugs (#99)
- Feature/swodlr UI 71 - add pagination to my data page (#98)
- Feature/swodlr UI cps verification (#100)


2 changes: 1 addition & 1 deletion cmr/ops_swodlr_cmr_umm_t.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"URL": {
"URLContentType": "DistributionURL",
"Type": "GOTO WEB TOOL",
"URLValue": "http://swodlr.podaac.earthdatacloud.nasa.gov/"
"URLValue": "http://swodlr.podaac.earthdatacloud.nasa.gov"
},
"MetadataSpecification": {
"URL": "https://cdn.earthdata.nasa.gov/umm/tool/v1.2.0",
Expand Down
2 changes: 1 addition & 1 deletion cmr/sit_swodlr_cmr_umm_t.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"URL": {
"URLContentType": "DistributionURL",
"Type": "GOTO WEB TOOL",
"URLValue": "http://swodlr.podaac.sit.earthdatacloud.nasa.gov/"
"URLValue": "http://swodlr.podaac.sit.earthdatacloud.nasa.gov"
},
"Description": "SWODLR (swaa·dler) is an open-source software system developed to generate custom Level 2 raster data products for the SWOT mission. It provides an Application Programming Interface (API) and Graphical User Interface (GUI) that allows end-users to provide custom configurations to generate on-demand raster data products from underlying standard data products (PIXC, PIXCVec).",
"ToolKeywords" : [
Expand Down
2 changes: 1 addition & 1 deletion cmr/uat_swodlr_cmr_umm_t.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"URL": {
"URLContentType": "DistributionURL",
"Type": "GOTO WEB TOOL",
"URLValue": "http://swodlr.podaac.uat.earthdatacloud.nasa.gov/"
"URLValue": "http://swodlr.podaac.uat.earthdatacloud.nasa.gov"
},
"MetadataSpecification": {
"URL": "https://cdn.earthdata.nasa.gov/umm/tool/v1.2.0",
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swodlr-ui",
"version": "1.0.1-1",
"version": "1.3.0-0",
"private": true,
"engines": {
"node": ">=18.0.0"
Expand Down
2 changes: 1 addition & 1 deletion src/components/about/About.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const About = () => {
const [backendVersion, setBackendVersion] = useState('')
useEffect(() => {
const fetchData = async () => {
setBackendVersion(await fetch('https://swodlr.podaac.sit.earthdatacloud.nasa.gov/api/about').then((version) => version.json()).then(response => response.version))
setBackendVersion(await fetch(`${process.env.REACT_APP_SWODLR_API_BASE_URI}/about`).then((version) => version.json()).then(response => response.version))
}
fetchData()
.catch(console.error);
Expand Down
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

0 comments on commit d746a76

Please sign in to comment.