From 3b89c33ee8a45c30315d25339c3a91312681276a Mon Sep 17 00:00:00 2001 From: "Bradley (Brad) Andrick" Date: Wed, 7 Aug 2024 09:23:06 -0400 Subject: [PATCH] Ba/adding search export (#403) * add simple json export button and logic * fix package lock version * add export in example config * update changelog & readme --- CHANGELOG.md | 12 +++++ README.md | 1 + config_helper/config.example.json | 3 +- package-lock.json | 4 +- src/components/ExportButton/ExportButton.css | 16 +++++++ src/components/ExportButton/ExportButton.jsx | 46 +++++++++++++++++++ .../Content/RightContent/RightContent.css | 5 ++ .../Content/RightContent/RightContent.jsx | 2 + 8 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 src/components/ExportButton/ExportButton.css create mode 100644 src/components/ExportButton/ExportButton.jsx diff --git a/CHANGELOG.md b/CHANGELOG.md index e59d0a62..a1b8a3ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +### Added + +- Simple export feature to allow exporting search results as geojson + +### Changed + +- Refactor call to action button to reduce prominence and match export button size + +### Fixed + +- bump version in `package-lock.json` file ot match `package.json` + ## 5.6.0 - 2024-08-02 ### Added diff --git a/README.md b/README.md index 0055af01..2b6b5f55 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ The file `config_helper/config.example.json` is included in this repository as r | APP_TOKEN_AUTH_ENABLED | If set to `true` login page renders initially and app only fully loads if a non expired token exists. STAC API calls made from the app will also send JWT as Bearer Token. **Note:** This approach provides a form of limited client-side authentication for the frontend, which is not fully secure. The STAC API endpoint must also require the JWT to ensure application data securtiy. | Optional | | AUTH_URL | Endpoint used to pass a username and password that returns as JWT that is used for STAC API calls. `APP_TOKEN_AUTH_ENABLED` config value must also be set to `true`. | Optional | | SUPPORTS_AGGREGATIONS | If included and set to `true` aggregation features are disabled and API calls are not made to load the optional aggregations from the STAC API. | Optional | +| EXPORT_ENABLED | If included and set to `true` a simple export button will render and allow for the simple export of search results as a geojson file. | Optional | ### Links diff --git a/config_helper/config.example.json b/config_helper/config.example.json index cc27b5bb..8e1a79c1 100644 --- a/config_helper/config.example.json +++ b/config_helper/config.example.json @@ -195,5 +195,6 @@ "COLLECTIONS": ["naip", "cop-dem-glo-30", "sentinel-2-l2a"], "APP_TOKEN_AUTH_ENABLED": true, "AUTH_URL": "https://sample-auth-service/login", - "SUPPORTS_AGGREGATIONS": false + "SUPPORTS_AGGREGATIONS": false, + "EXPORT_ENABLED": true } diff --git a/package-lock.json b/package-lock.json index 8a0f612f..6b792293 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "filmdrop-ui", - "version": "5.5.0", + "version": "5.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "filmdrop-ui", - "version": "5.5.0", + "version": "5.6.0", "license": "Apache-2.0", "dependencies": { "@emotion/react": "^11.11.4", diff --git a/src/components/ExportButton/ExportButton.css b/src/components/ExportButton/ExportButton.css new file mode 100644 index 00000000..41146e7a --- /dev/null +++ b/src/components/ExportButton/ExportButton.css @@ -0,0 +1,16 @@ +.ExportButton { + margin: 0px 5px 0px 10px; + display: flex; + align-items: center; + justify-content: center; +} + +.downloadButton { + background-color: #4f5768; + color: white; + cursor: pointer; + border: 1px solid #a9b0c1; + border-radius: 5px; + padding: 5px 5px 3px 5px; + height: 33px; +} diff --git a/src/components/ExportButton/ExportButton.jsx b/src/components/ExportButton/ExportButton.jsx new file mode 100644 index 00000000..532a08d4 --- /dev/null +++ b/src/components/ExportButton/ExportButton.jsx @@ -0,0 +1,46 @@ +import { React } from 'react' +import './ExportButton.css' +import { useSelector } from 'react-redux' +import DownloadIcon from '@mui/icons-material/Download' +import { showApplicationAlert } from '../../utils/alertHelper' + +const ExportButton = () => { + const _searchResults = useSelector((state) => state.mainSlice.searchResults) + const _selectedCollection = useSelector( + (state) => state.mainSlice.selectedCollection + ) + const _SearchDateRangeValue = useSelector( + (state) => state.mainSlice.searchDateRangeValue + ) + function onExportClick() { + if (!_searchResults) { + showApplicationAlert('warning', 'no search results', 5000) + return + } + const startDate = _SearchDateRangeValue[0].split('T')[0] + const endDate = _SearchDateRangeValue[1].split('T')[0] + const uniqueFileName = `${_selectedCollection}_${startDate}_${endDate}.geojson` + + const blob = new Blob([JSON.stringify(_searchResults)], { + type: 'application/json' + }) + const url = URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = uniqueFileName + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) + } + + return ( +
+ +
+ ) +} + +export default ExportButton diff --git a/src/components/Layout/Content/RightContent/RightContent.css b/src/components/Layout/Content/RightContent/RightContent.css index c01125ea..05dd1438 100644 --- a/src/components/Layout/Content/RightContent/RightContent.css +++ b/src/components/Layout/Content/RightContent/RightContent.css @@ -97,6 +97,11 @@ cursor: default; } +.actionButtonCTA { + height: 35px; + font-size: 16px; +} + .resultCount { position: absolute; z-index: 2; diff --git a/src/components/Layout/Content/RightContent/RightContent.jsx b/src/components/Layout/Content/RightContent/RightContent.jsx index 73bc90a8..f43d2603 100644 --- a/src/components/Layout/Content/RightContent/RightContent.jsx +++ b/src/components/Layout/Content/RightContent/RightContent.jsx @@ -33,6 +33,7 @@ import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined' import { Tooltip } from 'react-tooltip' import LayersIcon from '@mui/icons-material/Layers' import LayerList from '../../../LayerList/LayerList' +import ExportButton from '../../../ExportButton/ExportButton' const RightContent = () => { const [allScenesLoading, setallScenesLoading] = useState(false) @@ -212,6 +213,7 @@ const RightContent = () => { {_appConfig.ACTION_BUTTON.text} )} + {_appConfig.EXPORT_ENABLED && } {_searchResults?.numberMatched && _searchResults?.searchType !== 'AggregatedResults' &&