diff --git a/packages/query-bar/README.md b/packages/query-bar/README.md index e6c825864..c6c0c3c22 100644 --- a/packages/query-bar/README.md +++ b/packages/query-bar/README.md @@ -144,4 +144,4 @@ This component, which is generated by the provided generator, accepts the follow /> ``` -> **Warning**: The `statusReducer` prop requires the dashboard API data merged with the `facetsConfig` property. Please see the example in the demo implementation [here](https://github.com/CBIIT/bento-frontend/blob/7efd62cd3da0c29326e523055d30118244dc2f2f/packages/bento-frontend/src/pages/dashTemplate/filterQueryBar/QueryBarView.js#LL20C14-L20C14). +> **Warning**: The `statusReducer` prop requires the dashboard API data merged with the `facetsConfig` property. Please see the example in the demo implementation [here](https://github.com/CBIIT/bento-frontend/blob/7efd62cd3da0c29326e523055d30118244dc2f2f/packages/bento-frontend/src/pages/dashTemplate/filterQueryBar/QueryBarView.js#LL20C14-L20C14). \ No newline at end of file diff --git a/packages/query-bar/src/assets/CopyIcon.svg b/packages/query-bar/src/assets/CopyIcon.svg new file mode 100644 index 000000000..aee2eb79f --- /dev/null +++ b/packages/query-bar/src/assets/CopyIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/query-bar/src/components/QueryUrl.js b/packages/query-bar/src/components/QueryUrl.js new file mode 100644 index 000000000..c3f3981e6 --- /dev/null +++ b/packages/query-bar/src/components/QueryUrl.js @@ -0,0 +1,163 @@ +import React, { useState, useRef } from 'react'; +import clsx from 'clsx'; +import { + Button, + IconButton, + Tooltip, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + withStyles, +} from '@material-ui/core'; +import CopyIcon from '../assets/CopyIcon.svg'; + +const QueryUrl = ({ + classes, + filterItems, + localFind = {}, + rootPath, +}) => { + const [display, setDisplay] = useState(false); + const toggleDisplay = () => setDisplay(!display); + + const [open, toggleOpen] = useState(false); + + const pathFilterParams = filterItems.reduce((acc, item) => { + const { datafield, items = [] } = item; + acc[datafield] = items; + return acc; + }, {}); + + const query = JSON.stringify({ + ...pathFilterParams, + ...localFind, + }); + const url = encodeURI(rootPath.concat(query)); + + const copyUrl = async () => { + toggleOpen(!open); + await navigator.clipboard.writeText(url); + }; + + const queryRef = useRef(null); + + return ( + <> +
+ + { + (display) && ( + <> +
+ {url} +
+ + + copy icon + + + + ) + } +
+ toggleOpen(!open)} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + className={clsx(classes.dialogBox, 'dialogBox')} + > + + + Your query URL has been copied! + + + + + + + + ); +}; + +const styles = () => ({ + urlContainer: { + display: 'flex', + marginTop: '3px', + minHeight: '10px', + }, + viewLink: { + overflow: 'hidden', + textOverflow: 'ellipsis', + fontFamily: 'Nunito', + fontSize: '12px', + fontWeight: '500', + lineHeight: '16px', + letterSpacing: '0em', + padding: '2px 5px', + borderRadius: '5px', + float: 'left', + color: '#1D79A8', + backgroundColor: '#fff', + margin: '0', + whiteSpace: 'nowrap', + wordBreak: 'break-all', + '@media (max-width: 2560px)': { + maxWidth: '1800px', + }, + '@media (max-width: 2000px)': { + maxWidth: '1500px', + }, + '@media (max-width: 1600px)': { + maxWidth: '1100px', + }, + '@media (max-width: 1300px)': { + maxWidth: '900px', + }, + }, + urlViewBtn: { + cursor: 'pointer', + }, + viewLinkToggleBtn: { + padding: '5px 10px 5px 10px', + height: '20px', + fontFamily: 'Nunito', + fontSize: '12px', + fontWeight: '500', + lineHeight: '16px', + letterSpacing: '0em', + textAlign: 'left', + backgroundColor: '#1D79A8', + textTransform: 'none', + color: '#fff', + float: 'left', + margin: '0px 10px 0px 0px', + whiteSpace: 'nowrap', + '&:hover': { + backgroundColor: '#1D79A8', + color: '#fff', + }, + }, + copyIconBtn: { + padding: '0px', + height: '20px', + marginLeft: '10px', + float: 'left', + }, +}); + +export default withStyles(styles)(QueryUrl); diff --git a/packages/query-bar/src/generators/QueryBarGenerator.js b/packages/query-bar/src/generators/QueryBarGenerator.js index 8f262258f..e5f10306d 100644 --- a/packages/query-bar/src/generators/QueryBarGenerator.js +++ b/packages/query-bar/src/generators/QueryBarGenerator.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import { Filter } from '../components/FilterMap'; import DEFAULT_STYLES from './styles'; import DEFAULT_CONFIG from './config'; +import QueryUrl from '../components/QueryUrl'; /** * Generate a pre-configured Explore Query Bar component @@ -23,6 +24,14 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => { ? config.maxItems : DEFAULT_CONFIG.config.maxItems; + const queryURLRootPath = config && typeof config.rootPath === 'string' + ? config.rootPath + : DEFAULT_CONFIG.config.rootPath; + + const viewQueryURL = config && typeof config.viewQueryURL === 'boolean' + ? config.viewQueryURL + : DEFAULT_CONFIG.config.viewQueryURL; + const clearAll = functions && typeof functions.clearAll === 'function' ? functions.clearAll : DEFAULT_CONFIG.functions.clearAll; @@ -91,7 +100,7 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => { variant="outlined" onClick={clearAll} > - Clear Query + Clear @@ -117,7 +126,7 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => { className={clsx(classes.filterName, classes.localFindBackground)} onClick={clearAutocomplete} > - Case IDs + Case ID {' '} {' '} @@ -178,7 +187,6 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => { ) : null} - {/* Facet Sidebar Selections */} {((autocomplete.length || upload.length) && mappedInputs.length) ? AND @@ -201,6 +209,16 @@ export const QueryBarGenerator = (uiConfig = DEFAULT_CONFIG) => { ))} + { + (viewQueryURL && queryURLRootPath) && ( + + ) + } ); }), diff --git a/packages/query-bar/src/generators/config.js b/packages/query-bar/src/generators/config.js index 2ff233086..2dc9de3de 100644 --- a/packages/query-bar/src/generators/config.js +++ b/packages/query-bar/src/generators/config.js @@ -12,6 +12,7 @@ export default { * @var {boolean} */ displayAllActiveFilters: false, + viewQueryURL: false, }, /* Component Helper Functions */ diff --git a/packages/query-bar/src/generators/styles.js b/packages/query-bar/src/generators/styles.js index c3f8dc1ea..4edcb865c 100644 --- a/packages/query-bar/src/generators/styles.js +++ b/packages/query-bar/src/generators/styles.js @@ -3,7 +3,7 @@ */ export default () => ({ queryWrapper: { - height: '120px', + minHeight: '77px', backgroundColor: '#f1f1f1', padding: '14px 14px 0px 35px', overflowY: 'auto',