diff --git a/src/app/components/change-request/change-requests-view.jsx b/src/app/components/change-request/change-requests-view.jsx index e39d882102..e7a48bd02f 100755 --- a/src/app/components/change-request/change-requests-view.jsx +++ b/src/app/components/change-request/change-requests-view.jsx @@ -1,20 +1,12 @@ import React, { useContext, useEffect, useState } from 'react'; import { + Box, Button, - ButtonGroup, Card, CardContent, CardHeader, - CircularProgress, MenuItem, MenuList, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, - Typography, makeStyles, } from '@material-ui/core'; import VisibilityIcon from '@material-ui/icons/Visibility'; @@ -28,68 +20,43 @@ import ChplChangeRequestsDownload from './change-requests-download'; import { useFetchChangeRequests } from 'api/change-requests'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; import { ChplAvatar, ChplLink, + ChplLoadingCards, ChplPagination, - ChplSortableHeaders, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, } from 'components/util'; import { eventTrack } from 'services/analytics.service'; import { getDisplayDateFormat } from 'services/date-util'; import { useSessionStorage as useStorage } from 'services/storage.service'; import { UserContext, useAnalyticsContext } from 'shared/contexts'; -import { palette, theme, utilStyles } from 'themes'; +import { palette, utilStyles } from 'themes'; const useStyles = makeStyles({ ...utilStyles, - container: { - maxHeight: '64vh', + card: { + overflow: 'visible', }, - tableResultsHeaderContainer: { - display: 'grid', - gap: '8px', - margin: '16px 32px', - gridTemplateColumns: '1fr', - alignItems: 'center', - justifyContent: 'space-between', - [theme.breakpoints.up('sm')]: { - gridTemplateColumns: 'auto auto', - }, - }, - resultsContainer: { - display: 'grid', - gap: '8px', - justifyContent: 'start', - gridTemplateColumns: 'auto auto', - alignItems: 'center', - }, - wrap: { - flexFlow: 'wrap', - }, - tableFirstColumn: { - position: 'sticky', - left: 0, - boxShadow: 'rgba(149, 157, 165, 0.1) 0px 4px 8px', - backgroundColor: palette.white, - }, - tableDeveloperCell: { + developerTitle: { display: 'flex', alignItems: 'center', gap: '8px', }, - developerName: { - fontWeight: '600', - }, noResultsContainer: { padding: '16px 32px', }, }); -function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embedded = false }) { +function ChplChangeRequestsView({ + disallowedFilters, bonusQuery, dispatch, embedded = false, +}) { const storageKey = 'storageKey-changeRequestsView'; const { analytics } = useAnalyticsContext(); const { hasAnyRole } = useContext(UserContext); @@ -128,20 +95,17 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed } }, [data, isLoading, isSuccess]); - /* eslint object-curly-newline: ["error", { "minProperties": 5, "consistent": true }] */ - const headers = hasAnyRole(['chpl-developer']) ? [ - { property: 'change_request_type', text: 'Request Type', sortable: true }, - { property: 'change_request_status', text: 'Request Status', sortable: true }, - { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', sortable: true, reverseDefault: true }, - { text: 'Actions', invisible: true }, + const isDeveloper = hasAnyRole(['chpl-developer']); + const sortOptions = isDeveloper ? [ + { property: 'change_request_type', text: 'Request Type' }, + { property: 'change_request_status', text: 'Request Status' }, + { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', reverseDefault: true }, ] : [ - { property: 'developer', text: 'Developer', sortable: true }, - { property: 'change_request_type', text: 'Request Type', sortable: true }, - { property: 'submitted_date_time', text: 'Creation Date', sortable: true, reverseDefault: true }, - { property: 'change_request_status', text: 'Request Status', sortable: true }, - { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', sortable: true, reverseDefault: true }, - { text: 'Associated ONC-ACBs' }, - { text: 'Actions', invisible: true }, + { property: 'developer', text: 'Developer' }, + { property: 'change_request_type', text: 'Request Type' }, + { property: 'submitted_date_time', text: 'Creation Date', reverseDefault: true }, + { property: 'change_request_status', text: 'Request Status' }, + { property: 'current_status_change_date_time', text: 'Time Since Last Status Change', reverseDefault: true }, ]; const handleDispatch = (action, payload) => { @@ -156,7 +120,7 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed } }; - const handleTableSort = (event, property, orderDirection) => { + const handleSort = (property, orderDirection) => { eventTrack({ ...analytics, event: 'Sort Column', @@ -187,21 +151,19 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed const pageStart = (pageNumber * pageSize) + 1; const pageEnd = Math.min((pageNumber + 1) * pageSize, data?.recordCount); + const recordCount = data?.recordCount ?? 0; const content = ( <> - - { isLoading - && ( -
- -
- )} - { !isLoading + + { isLoading && ()} + { !isLoading && ( <> { isError @@ -217,84 +179,60 @@ function ChplChangeRequestsView({ disallowedFilters, bonusQuery, dispatch, embed )} - { isSuccess + { !isError && ( <> -
-
- Search Results: - { changeRequests.length === 0 - && ( - <> - No results found - - )} - { changeRequests.length > 0 - && ( - - {`(${pageStart}-${pageEnd} of ${data?.recordCount} Results)`} - - )} -
+ + { changeRequests.length > 0 && ( - - - + )} -
+ { changeRequests.length > 0 && ( <> - - - - - {changeRequests - .map((item) => ( - - { !hasAnyRole(['chpl-developer']) - && ( - -
-
- -
-
- -
-
-
- )} - {item.changeRequestType.name} - { !hasAnyRole(['chpl-developer']) - && {getDisplayDateFormat(item.submittedDateTime)}} - {item.currentStatus.name} - + + { changeRequests.map((item) => ( + + + + + )} + fieldGroups={isDeveloper ? [ + [ + { label: 'Request Type', value: item.changeRequestType.name }, + { label: 'Request Status', value: item.currentStatus.name }, + { + label: 'Time Since Last Status Change', + value: ( {item.currentStatus.statusChangeDateTime} - - { !hasAnyRole(['chpl-developer']) - && ( - - { item.certificationBodies.length === 0 - ? ( - <> - None - - ) : ( - <> - { item.certificationBodies.map((acb) => acb.name).join('; ') } - - )} - - )} - - - -
- ))} -
-
-
+ {item.currentStatus.statusChangeDateTime} + + ), + }, + { + label: 'Associated ONC-ACBs', + value: item.certificationBodies.length === 0 + ? 'None' + : item.certificationBodies.map((acb) => acb.name).join('; '), + }, + ], + ]} + actions={( + + )} + /> + ))} + )} +
); return ( - + { bonusQuery && ( diff --git a/src/app/components/filter/filter-chips.jsx b/src/app/components/filter/filter-chips.jsx index e820acd2d4..5a6081d6e1 100755 --- a/src/app/components/filter/filter-chips.jsx +++ b/src/app/components/filter/filter-chips.jsx @@ -1,6 +1,8 @@ import React, { useEffect, useState } from 'react'; import { Button, + Card, + CardContent, Chip, FormControlLabel, Switch, @@ -13,48 +15,53 @@ import { useFilterContext } from './filter-context'; import { ChplTooltip } from 'components/util'; import { eventTrack } from 'services/analytics.service'; import { getStatusIcon } from 'services/listing.service'; -import theme from 'themes/theme'; import { palette } from 'themes'; -const useStyles = makeStyles(() => ({ +const useStyles = makeStyles({ filterContainer: { display: 'flex', - padding: '16px 32px', - marginTop: '-4px', - position: 'relative', - zIndex: 1, - backgroundColor: palette.white, - borderBottom: `1px solid ${palette.greyBorder}`, - flexWrap: 'wrap', - flexFlow: 'column', + flexDirection: 'column', alignItems: 'flex-start', - [theme.breakpoints.up('sm')]: { - flexWrap: 'wrap', - }, + gap: '16px', + width: '100%', }, filterSelectedContainer: { display: 'flex', + flexDirection: 'column', gap: '4px', - alignItems: 'center', + alignItems: 'flex-start', justifyContent: 'flex-start', - flexWrap: 'wrap', + width: '100%', }, filterChipsContainer: { display: 'flex', - gap: '8px', + gap: '16px', alignContent: 'flex-start', - flexWrap: 'wrap', - flexDirection: 'row', - alignItems: 'center', + flexDirection: 'column', + alignItems: 'flex-start', + width: '100%', }, chip: { border: `1px solid ${palette.primary}`, backgroundColor: palette.white, + maxWidth: '100%', + }, + chipDeleteIcon: { + order: -2, + marginLeft: '5px', + marginRight: '-4px', + }, + chipLabel: { + alignItems: 'center', + display: 'inline-flex', + gap: '4px', }, - chipAvatar: { - backgroundColor: 'transparent !important', + card: { + width: '100%', + maxHeight: '50vh', + overflowY: 'auto', }, -})); +}); const truncate = (str, n, useWordBoundary) => { if (str.length <= n) { return str; } @@ -127,91 +134,105 @@ function ChplFilterChips() { filterContext.dispatch('toggleShowAll', f); }; + if (filters.length === 0) { return null; } + + const getChipLabel = (f, labelText, iconName) => { + if (f.key !== 'certificationStatuses') { return labelText; } + return ( + + { labelText } + { getStatusIcon({ name: iconName }) } + + ); + }; + return ( - Filters Applied: -
- { filters.map((f) => ( - - - - {f.getFilterDisplay(f)} - - - { f.operatorKey - && ( - toggleOperator(f)} - /> - )} - label={f.operator === 'and' ? 'All' : 'Any'} - /> - )} - { f.developersListingsCriteriaOptionKey - && ( - toggleDevelopersListingsCriteriaOption(f)} - /> - )} - label={f.developersListingsCriteriaOption === 'active' ? 'Active Listings' : 'All Listings'} - /> - )} - {f.values - .filter((v, idx) => f.showAll || idx < DISPLAY_MAX) - .map((v) => ( - - { f.getValueDisplay(v).length > maxLengthForChip - ? ( - - removeChip(f, v)} - variant="outlined" - disabled={f.required && f.values.length === 1} - classes={{ avatar: classes.chipAvatar, root: classes.chip }} - /> - - ) : ( - removeChip(f, v)} - variant="outlined" - disabled={f.required && f.values.length === 1} - classes={{ avatar: classes.chipAvatar, root: classes.chip }} + + + Filters Applied: +
+ { filters.map((f) => ( + + + + {f.getFilterDisplay(f)} + + + { f.operatorKey + && ( + toggleOperator(f)} + /> + )} + label={f.operator === 'and' ? 'All' : 'Any'} + /> + )} + { f.developersListingsCriteriaOptionKey + && ( + toggleDevelopersListingsCriteriaOption(f)} /> )} - - ))} - { f.values.length > DISPLAY_MAX - && ( - - )} - - ))} -
+ label={f.developersListingsCriteriaOption === 'active' ? 'Active Listings' : 'All Listings'} + /> + )} + {f.values + .filter((v, idx) => f.showAll || idx < DISPLAY_MAX) + .map((v) => ( + + { f.getValueDisplay(v).length > maxLengthForChip + ? ( + + removeChip(f, v)} + variant="outlined" + disabled={f.required && f.values.length === 1} + classes={{ root: classes.chip, deleteIcon: classes.chipDeleteIcon }} + /> + + ) : ( + removeChip(f, v)} + variant="outlined" + disabled={f.required && f.values.length === 1} + classes={{ root: classes.chip, deleteIcon: classes.chipDeleteIcon }} + /> + )} + + ))} + { f.values.length > DISPLAY_MAX + && ( + + )} +
+ ))} +
+ +
); } diff --git a/src/app/components/filter/filter-layout.jsx b/src/app/components/filter/filter-layout.jsx new file mode 100644 index 0000000000..b259794ffd --- /dev/null +++ b/src/app/components/filter/filter-layout.jsx @@ -0,0 +1,165 @@ +import React, { useEffect, useState } from 'react'; +import { + Box, + Button, + Card, + CardContent, + Collapse, + Typography, + makeStyles, + useMediaQuery, +} from '@material-ui/core'; +import FilterListIcon from '@material-ui/icons/FilterList'; +import LabelOffIcon from '@material-ui/icons/LabelOff'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import ExpandLessIcon from '@material-ui/icons/ExpandLess'; +import { bool, node } from 'prop-types'; + +import ChplFilterChips from './filter-chips'; +import { useFilterContext } from './filter-context'; + +import { palette, theme } from 'themes'; + +const useStyles = makeStyles({ + layoutContainer: { + display: 'grid', + gridTemplateColumns: '1fr', + gap: '16px', + alignItems: 'start', + margin: '16px 0', + [theme.breakpoints.up('md')]: { + gridTemplateColumns: '260px 1fr', + gap: '24px', + }, + }, + layoutContainerMobileOnly: { + display: 'grid', + gridTemplateColumns: '1fr', + gap: '16px', + alignItems: 'start', + margin: '16px 0', + }, + sidebar: { + display: 'flex', + flexDirection: 'column', + gap: '8px', + [theme.breakpoints.up('md')]: { + position: 'sticky', + top: '190px', + }, + }, + sidebarMobileOnly: { + display: 'flex', + flexDirection: 'column', + gap: '8px', + }, + sidebarToggle: { + justifyContent: 'space-between', + color: palette.black, + [theme.breakpoints.up('md')]: { + display: 'none', + }, + }, + sidebarToggleMobileOnly: { + justifyContent: 'space-between', + color: palette.black, + }, + sidebarToggleLabel: { + display: 'flex', + alignItems: 'center', + gap: '8px', + }, + emptyCard: { + width: '100%', + }, + emptyContent: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + textAlign: 'center', + gap: '8px', + }, + emptyIcon: { + fontSize: '2rem', + }, + content: { + minWidth: 0, + }, +}); + +function ChplFilterLayout({ children, mobileOnly }) { + const classes = useStyles(); + const filterContext = useFilterContext(); + const isDesktopWidth = useMediaQuery(theme.breakpoints.up('md')); + const isDesktop = isDesktopWidth && !mobileOnly; + const [expanded, setExpanded] = useState(false); + + const hasAppliedFilters = filterContext.filters + .some((filter) => filter.values?.some((v) => v.selected)); + + useEffect(() => { + if (isDesktop) { setExpanded(false); } + }, [isDesktop]); + + if (!hasAppliedFilters) { + return ( +
+ + + + + + No filters applied. Please use the advanced search to apply filters and view results. + + + + +
+ {children} +
+
+ ); + } + + return ( +
+ + + {isDesktop + ? + : ( + + + + )} + +
+ {children} +
+
+ ); +} + +export default ChplFilterLayout; + +ChplFilterLayout.propTypes = { + children: node, + mobileOnly: bool, +}; + +ChplFilterLayout.defaultProps = { + children: undefined, + mobileOnly: false, +}; diff --git a/src/app/components/filter/filter-panel.jsx b/src/app/components/filter/filter-panel.jsx index 4176d42d7f..d660019e75 100755 --- a/src/app/components/filter/filter-panel.jsx +++ b/src/app/components/filter/filter-panel.jsx @@ -34,6 +34,12 @@ const useStyles = makeStyles({ gridTemplateColumns: '1fr 1fr', }, }, + filterPanelFooter: { + display: 'flex', + justifyContent: 'flex-end', + padding: '8px 16px', + borderTop: `1px solid ${palette.primaryBorder}`, + }, filterPanelPrimary: { padding: '16px', }, @@ -50,14 +56,14 @@ const useStyles = makeStyles({ }, filterContainer: { display: 'grid', - gridTemplateColumns: 'repeat(auto-fit, minmax(225px, 1fr))', + gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', justifyItems: 'start', alignItems: 'start', gap: '16px', padding: '0 8px', marginTop: '16px', [theme.breakpoints.up('xl')]: { - gridTemplateColumns: 'repeat(auto-fit, minmax(275px, 1fr))', + gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', }, }, filterHeaderContainer: { @@ -240,15 +246,15 @@ function ChplFilterPanel() { TransitionProps={{ onExited: () => setAnchor(null) }} anchorOrigin={{ vertical: 'bottom', - horizontal: 'center', + horizontal: 'right', }} transformOrigin={{ vertical: 'top', - horizontal: 'center', + horizontal: 'right', }} PaperProps={{ style: { - width: panelWidth ? `${panelWidth}px` : 'calc(100vw - 32px)', + width: panelWidth ? `${panelWidth - 284}px` : 'calc(100vw - 32px - 284px)', maxWidth: 'calc(100vw - 32px)', alignItems: 'center', borderRadius: '0 0 8px 8px', @@ -405,6 +411,16 @@ function ChplFilterPanel() { )} +
+ +
); diff --git a/src/app/components/filter/filter-search-bar.jsx b/src/app/components/filter/filter-search-bar.jsx index e0dde54a00..2ed25e5431 100755 --- a/src/app/components/filter/filter-search-bar.jsx +++ b/src/app/components/filter/filter-search-bar.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { Box, makeStyles, @@ -48,19 +48,55 @@ const useStyles = makeStyles({ }, }, }, + sticky: { + position: 'sticky', + top: '100px', + zIndex: 3, + }, + stuck: { + '&::before': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + bottom: '100%', + height: '100px', + background: ({ fadeBackground }) => `linear-gradient(to top, ${fadeBackground} 55%, transparent)`, + pointerEvents: 'none', + }, + }, }); function ChplFilterSearchBar({ + fadeBackground = palette.backgroundPage, hideAdvancedSearch = false, hideSearchTerm = false, placeholder = 'Search by Developer, Product, or CHPL ID...', + sticky = false, toggleMultipleFilters = undefined, }) { const { filters } = useFilterContext(); - const classes = useStyles(); + const classes = useStyles({ fadeBackground }); + const sentinelRef = useRef(null); + const [isStuck, setIsStuck] = useState(false); - return ( -
+ useEffect(() => { + if (!sticky) { return undefined; } + const sentinel = sentinelRef.current; + if (!sentinel) { return undefined; } + const observer = new IntersectionObserver( + ([entry]) => setIsStuck(!entry.isIntersecting), + { rootMargin: '-100px 0px 0px 0px', threshold: 0 }, + ); + observer.observe(sentinel); + return () => observer.disconnect(); + }, [sticky]); + + const searchBar = ( +
{ !hideSearchTerm && (
); + + if (!sticky) { + return searchBar; + } + + return ( + <> +
+ {searchBar} + + ); } export default ChplFilterSearchBar; ChplFilterSearchBar.propTypes = { + fadeBackground: string, hideAdvancedSearch: bool, hideSearchTerm: bool, placeholder: string, + sticky: bool, toggleMultipleFilters: arrayOf(object), }; diff --git a/src/app/components/filter/filters/certification-statuses.jsx b/src/app/components/filter/filters/certification-statuses.jsx index f3ce4c83c9..42d4af26e0 100755 --- a/src/app/components/filter/filters/certification-statuses.jsx +++ b/src/app/components/filter/filters/certification-statuses.jsx @@ -32,13 +32,14 @@ const getCertificationStatusValueEntry = ({ filter, handleFilterToggle }) => fil style={{ display: 'flex', alignItems: 'center', + gap: '4px', }} > - {getStatusIcon({ name: filter.getLongValueDisplay(value) })} - {filter.getLongValueDisplay(value)} + {getStatusIcon({ name: filter.getLongValueDisplay(value) })} + ); }); diff --git a/src/app/components/filter/index.js b/src/app/components/filter/index.js index 26e24ae9c1..2aab1c3614 100755 --- a/src/app/components/filter/index.js +++ b/src/app/components/filter/index.js @@ -3,6 +3,7 @@ import ChplFilterPanel from './filter-panel'; import ChplFilterQuickFilters from './filter-quick-filters'; import ChplFilterSearchBar from './filter-search-bar'; import ChplFilterSearchTerm from './filter-search-term'; +import ChplFilterLayout from './filter-layout'; import { FilterProvider, defaultFilter, @@ -18,6 +19,7 @@ export { ChplFilterQuickFilters, ChplFilterSearchBar, ChplFilterSearchTerm, + ChplFilterLayout, FilterProvider, defaultFilter, getDateDisplay, diff --git a/src/app/components/products/products-view.jsx b/src/app/components/products/products-view.jsx index ae8f39489a..737bffcccd 100755 --- a/src/app/components/products/products-view.jsx +++ b/src/app/components/products/products-view.jsx @@ -11,7 +11,7 @@ import { arrayOf, func } from 'prop-types'; import ChplProductView from './product-view'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -125,19 +125,17 @@ function ChplProductsView({ products = [], dispatch }) { -
- -
-
-
- Search Results: - { displayedProducts.length === 0 + +
+
+ Search Results: + { displayedProducts.length === 0 && ( <> No results found )} - { displayedProducts.length > 0 + { displayedProducts.length > 0 && ( { displayedProducts.length } @@ -146,18 +144,19 @@ function ChplProductsView({ products = [], dispatch }) { { displayedProducts.length === 1 ? '' : 's' } )} +
-
- { displayedProducts - .sort((a, b) => sortProducts(a, b)) - .map((product) => ( - - ))} + { displayedProducts + .sort((a, b) => sortProducts(a, b)) + .map((product) => ( + + ))} + ); diff --git a/src/app/components/surveillance/complaints/complaints-view.jsx b/src/app/components/surveillance/complaints/complaints-view.jsx index fbab7970f4..78d695b483 100755 --- a/src/app/components/surveillance/complaints/complaints-view.jsx +++ b/src/app/components/surveillance/complaints/complaints-view.jsx @@ -25,7 +25,7 @@ import ChplComplaint from './complaint'; import { useFetchComplaints, usePostReportRequest } from 'api/complaints'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -281,14 +281,12 @@ function ChplComplaintsView(props) { -
- -
- { isLoading + + { isLoading && ( )} - { !isLoading + { !isLoading && ( <>
@@ -375,6 +373,7 @@ function ChplComplaintsView(props) { )} )} + ); diff --git a/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx b/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx index d0ed75d682..d629acbaaa 100755 --- a/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx +++ b/src/app/components/system-maintenance/certification-criterion/certification-criteria-view.jsx @@ -1,21 +1,24 @@ import React, { useEffect, useState } from 'react'; import { Box, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf } from 'prop-types'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; -import { ChplLink, ChplSearchResultCard, ChplSortControls } from 'components/util'; +import { + ChplLink, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, +} from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { getDisplayDateFormat } from 'services/date-util'; import { criterion as criterionPropType } from 'shared/prop-types'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'number', text: 'Number' }, @@ -24,10 +27,6 @@ const sortOptions = [ { property: 'endDay', text: 'End Date' }, ]; -const useStyles = makeStyles({ - ...utilStyles, -}); - const getDisplay = (key) => { switch (key) { case 'additionalSoftware': return 'Additional Software'; @@ -63,7 +62,6 @@ function ChplCertificationCriteriaView({ certificationCriteria: initialCertifica const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('number'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setCertificationCriteria(initialCertificationCriteria @@ -96,74 +94,70 @@ function ChplCertificationCriteriaView({ certificationCriteria: initialCertifica <> -
- -
- - - - Search Results - - - {`(${certificationCriteria.length} Result${certificationCriteria.length !== 1 ? 's' : ''})`} - - - + + 0 ? 1 : 0} + pageEnd={certificationCriteria.length} + fadeBackground={palette.white} + > + + + {certificationCriteria + .map((item) => ( + + ) : 'N/A', + }, + { + label: 'Attributes', + value: item.displayAttributes.length > 0 ? item.displayAttributes : 'N/A', + }, + ], + ]} + /> + ))} - - - {certificationCriteria - .map((item) => ( - - ) : 'N/A', - }, - { - label: 'Attributes', - value: item.displayAttributes.length > 0 ? item.displayAttributes : 'N/A', - }, - ], - ]} - /> - ))} - + ); } diff --git a/src/app/components/system-maintenance/certification-criterion/certification-criteria.jsx b/src/app/components/system-maintenance/certification-criterion/certification-criteria.jsx index ba4c88ab56..33658dee6f 100755 --- a/src/app/components/system-maintenance/certification-criterion/certification-criteria.jsx +++ b/src/app/components/system-maintenance/certification-criterion/certification-criteria.jsx @@ -106,7 +106,7 @@ function ChplCertificationCriteria() { filters={filters} storageKey="storageKey-certificationCriteriaManagement" > - + )} /> - + diff --git a/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx b/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx index 1e9e2b5d75..d41596fbe8 100755 --- a/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx +++ b/src/app/components/system-maintenance/functionality-tested/functionalities-tested-view.jsx @@ -3,8 +3,6 @@ import { Box, Button, IconButton, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf, func } from 'prop-types'; import AddIcon from '@material-ui/icons/Add'; @@ -14,19 +12,23 @@ import InfoIcon from '@material-ui/icons/Info'; import { useFetchFunctionalitiesTestedActivity } from 'api/activity'; import ChplSystemMaintenanceActivity from 'components/activity/system-maintenance-activity'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; import { - ChplSearchResultCard, ChplSortControls, ChplTooltip, ChplUpdateIndicator, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, + ChplTooltip, + ChplUpdateIndicator, } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { sortCriteria } from 'services/criteria.service'; import { getDisplayDateFormat } from 'services/date-util'; import { UserContext } from 'shared/contexts'; import { functionalityTested as functionalityTestedPropType } from 'shared/prop-types'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'value', text: 'Value' }, @@ -37,17 +39,12 @@ const sortOptions = [ { property: 'endDay', text: 'End Date' }, ]; -const useStyles = makeStyles({ - ...utilStyles, -}); - function ChplFunctionalitiesTestedView({ dispatch, functionalitiesTested: initialFunctionalitiesTested }) { const { hasAnyRole } = useContext(UserContext); const [functionalitiesTested, setFunctionalitiesTested] = useState([]); const [order, setOrder] = useState('desc'); const [orderBy, setOrderBy] = useState('value'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setFunctionalitiesTested(initialFunctionalitiesTested @@ -79,20 +76,16 @@ function ChplFunctionalitiesTestedView({ dispatch, functionalitiesTested: initia <> -
- -
- - - - Search Results - - - {`(${functionalitiesTested.length} Result${functionalitiesTested.length !== 1 ? 's' : ''})`} - - - + + 0 ? 1 : 0} + pageEnd={functionalitiesTested.length} + fadeBackground={palette.white} + > )} - - - - {functionalitiesTested - .map((item) => ( - + + + {functionalitiesTested + .map((item) => ( + )} - fieldGroups={[ - [ - { - label: 'Regulatory Text Citation', - value: item.regulatoryTextCitation || 'N/A', - iconButton: ( - - - - - - ), - }, - { - label: 'Rule', - value: item.rule?.name || 'N/A', - }, - { - label: 'Practice Type', - value: item.practiceType?.name || 'N/A', - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - [ - { - label: 'Start Date', - value: getDisplayDateFormat(item.startDay) || 'N/A', - }, - { - label: 'End Date', - value: getDisplayDateFormat(item.endDay) || 'N/A', - }, - { - label: 'Required Date', - value: getDisplayDateFormat(item.requiredDay) || 'N/A', - }, - { - label: 'Extension End Date', - value: getDisplayDateFormat(item.extensionEndDay) || 'N/A', - }, - ], - ]} - actions={ + fieldGroups={[ + [ + { + label: 'Regulatory Text Citation', + value: item.regulatoryTextCitation || 'N/A', + iconButton: ( + + + + + + ), + }, + { + label: 'Rule', + value: item.rule?.name || 'N/A', + }, + { + label: 'Practice Type', + value: item.practiceType?.name || 'N/A', + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + [ + { + label: 'Start Date', + value: getDisplayDateFormat(item.startDay) || 'N/A', + }, + { + label: 'End Date', + value: getDisplayDateFormat(item.endDay) || 'N/A', + }, + { + label: 'Required Date', + value: getDisplayDateFormat(item.requiredDay) || 'N/A', + }, + { + label: 'Extension End Date', + value: getDisplayDateFormat(item.extensionEndDay) || 'N/A', + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/system-maintenance/functionality-tested/functionalities-tested.jsx b/src/app/components/system-maintenance/functionality-tested/functionalities-tested.jsx index 69692a8dc2..5645ce09ca 100755 --- a/src/app/components/system-maintenance/functionality-tested/functionalities-tested.jsx +++ b/src/app/components/system-maintenance/functionality-tested/functionalities-tested.jsx @@ -257,7 +257,7 @@ function ChplFunctionalitiesTested() { filters={filters} storageKey="storageKey-functionalitiesTestedManagement" > - + )} /> - + { (deleteFunctionalityTested.isLoading || postFunctionalityTested.isLoading || putFunctionalityTested.isLoading) && ( diff --git a/src/app/components/system-maintenance/g1g2/g1g2-view.jsx b/src/app/components/system-maintenance/g1g2/g1g2-view.jsx index f729b86e0f..b3ff833032 100755 --- a/src/app/components/system-maintenance/g1g2/g1g2-view.jsx +++ b/src/app/components/system-maintenance/g1g2/g1g2-view.jsx @@ -2,21 +2,24 @@ import React, { useEffect, useState } from 'react'; import { Box, IconButton, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf, shape, string } from 'prop-types'; import InfoIcon from '@material-ui/icons/Info'; -import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; +import { + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, + ChplTooltip, +} from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; import { sortCriteria } from 'services/criteria.service'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'abbreviation', text: 'Abbreviation' }, @@ -24,16 +27,11 @@ const sortOptions = [ { property: 'name', text: 'Name' }, ]; -const useStyles = makeStyles({ - ...utilStyles, -}); - function ChplG1g2View({ g1g2: initialG1g2 }) { const [g1g2, setG1g2] = useState([]); const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('abbreviation'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setG1g2(initialG1g2 @@ -66,70 +64,68 @@ function ChplG1g2View({ g1g2: initialG1g2 }) { <> -
- -
- - - Search Results - - {`(${g1g2.length} Result${g1g2.length !== 1 ? 's' : ''})`} - - - + + 0 ? 1 : 0} + pageEnd={g1g2.length} + fadeBackground={palette.white} + > + + + { g1g2 + .map((item) => ( + + + + + + ), + }, + { + label: 'Domain', + value: item.domainDisplay || 'N/A', + iconButton: ( + + + + + + ), + }, + { + label: 'Required Test', + value: `${item.removed ? 'Removed | ' : ''}${item.requiredTest || 'N/A'}`, + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + /> + ))} - - - { g1g2 - .map((item) => ( - - - - - - ), - }, - { - label: 'Domain', - value: item.domainDisplay || 'N/A', - iconButton: ( - - - - - - ), - }, - { - label: 'Required Test', - value: `${item.removed ? 'Removed | ' : ''}${item.requiredTest || 'N/A'}`, - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - /> - ))} - + ); } diff --git a/src/app/components/system-maintenance/g1g2/g1g2.jsx b/src/app/components/system-maintenance/g1g2/g1g2.jsx index cf097b22f6..b9cdf0ef21 100755 --- a/src/app/components/system-maintenance/g1g2/g1g2.jsx +++ b/src/app/components/system-maintenance/g1g2/g1g2.jsx @@ -77,7 +77,7 @@ function ChplG1g2() { filters={filters} storageKey="storageKey-g1g2Management" > - + )} /> - + diff --git a/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx b/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx index f43c51eb4d..2147449629 100755 --- a/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx +++ b/src/app/components/system-maintenance/optional-standard/optional-standards-view.jsx @@ -11,7 +11,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -63,58 +63,57 @@ function ChplOptionalStandardsView({ optionalStandards: initialOptionalStandards -
- -
- - - Search Results - - {`(${optionalStandards.length} Result${optionalStandards.length !== 1 ? 's' : ''})`} - + + + + Search Results + + {`(${optionalStandards.length} Result${optionalStandards.length !== 1 ? 's' : ''})`} + + + + + - - + + { optionalStandards + .map((item) => ( + + + + + + ), + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + /> + ))} - - - { optionalStandards - .map((item) => ( - - - - - - ), - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - /> - ))} - + ); } diff --git a/src/app/components/system-maintenance/standard/standards-view.jsx b/src/app/components/system-maintenance/standard/standards-view.jsx index af99a95016..18d88f82ed 100755 --- a/src/app/components/system-maintenance/standard/standards-view.jsx +++ b/src/app/components/system-maintenance/standard/standards-view.jsx @@ -3,8 +3,6 @@ import { Box, Button, IconButton, - Typography, - makeStyles, } from '@material-ui/core'; import { arrayOf, func } from 'prop-types'; import AddIcon from '@material-ui/icons/Add'; @@ -14,12 +12,13 @@ import InfoIcon from '@material-ui/icons/Info'; import { useFetchStandardsActivity } from 'api/activity'; import ChplSystemMaintenanceActivity from 'components/activity/system-maintenance-activity'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; import { ChplSearchResultCard, + ChplSearchResultControls, ChplSortControls, ChplUpdateIndicator, ChplTooltip, @@ -29,7 +28,7 @@ import { sortCriteria } from 'services/criteria.service'; import { getDisplayDateFormat } from 'services/date-util'; import { UserContext } from 'shared/contexts'; import { standard as standardPropType } from 'shared/prop-types'; -import { utilStyles } from 'themes'; +import { palette } from 'themes'; const sortOptions = [ { property: 'value', text: 'Value' }, @@ -40,21 +39,12 @@ const sortOptions = [ { property: 'endDay', text: 'End Date' }, ]; -const useStyles = makeStyles({ - ...utilStyles, - tableResultsHeaderContainer: { - display: 'flex', - justifyContent: 'flex-end', - }, -}); - function ChplStandardsView({ dispatch, standards: initialStandards }) { const [standards, setStandards] = useState([]); const { hasAnyRole } = useContext(UserContext); const [order, setOrder] = useState('asc'); const [orderBy, setOrderBy] = useState('value'); const filterContext = useFilterContext(); - const classes = useStyles(); useEffect(() => { setStandards(initialStandards @@ -86,18 +76,16 @@ function ChplStandardsView({ dispatch, standards: initialStandards }) { <> -
- -
- - - Search Results - - {`(${standards.length} Result${standards.length !== 1 ? 's' : ''})`} - - - + + 0 ? 1 : 0} + pageEnd={standards.length} + fadeBackground={palette.white} + > )} - - - - { standards - .map((item) => ( - + + + { standards + .map((item) => ( + )} - fieldGroups={[ - [ - { - label: 'Regulatory Text Citation', - value: item.regulatoryTextCitation || 'N/A', - iconButton: ( - - - - - - ), - }, - { - label: 'Rule', - value: item.rule?.name ?? 'N/A', - }, - { - label: 'Group', - value: item.groupName ?? 'N/A', - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - [ - { - label: 'Start Date', - value: getDisplayDateFormat(item.startDay), - }, - { - label: 'Required Date', - value: getDisplayDateFormat(item.requiredDay), - }, - { - label: 'Extension End Date', - value: getDisplayDateFormat(item.extensionEndDay), - }, - { - label: 'End Date', - value: getDisplayDateFormat(item.endDay), - }, - ], - ]} - actions={ + fieldGroups={[ + [ + { + label: 'Regulatory Text Citation', + value: item.regulatoryTextCitation || 'N/A', + iconButton: ( + + + + + + ), + }, + { + label: 'Rule', + value: item.rule?.name ?? 'N/A', + }, + { + label: 'Group', + value: item.groupName ?? 'N/A', + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + [ + { + label: 'Start Date', + value: getDisplayDateFormat(item.startDay), + }, + { + label: 'Required Date', + value: getDisplayDateFormat(item.requiredDay), + }, + { + label: 'Extension End Date', + value: getDisplayDateFormat(item.extensionEndDay), + }, + { + label: 'End Date', + value: getDisplayDateFormat(item.endDay), + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/system-maintenance/standard/standards.jsx b/src/app/components/system-maintenance/standard/standards.jsx index 5b8e603959..7ee58a0247 100755 --- a/src/app/components/system-maintenance/standard/standards.jsx +++ b/src/app/components/system-maintenance/standard/standards.jsx @@ -256,7 +256,7 @@ function ChplStandards() { filters={filters} storageKey="storageKey-standardsManagement" > - + )} /> - + { (deleteStandard.isLoading || postStandard.isLoading || putStandard.isLoading) && ( diff --git a/src/app/components/system-maintenance/svap/svaps-view.jsx b/src/app/components/system-maintenance/svap/svaps-view.jsx index b6059eb792..df22de09e2 100755 --- a/src/app/components/system-maintenance/svap/svaps-view.jsx +++ b/src/app/components/system-maintenance/svap/svaps-view.jsx @@ -14,7 +14,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { useFetchSvapsActivity } from 'api/activity'; import ChplSystemMaintenanceActivity from 'components/activity/system-maintenance-activity'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -76,28 +76,26 @@ function ChplSvapsView({ dispatch, svaps: initialSvaps }) { -
- -
- - - Search Results - - {`(${svaps.length} Result${svaps.length !== 1 ? 's' : ''})`} - - - - - - { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + + + + Search Results + + {`(${svaps.length} Result${svaps.length !== 1 ? 's' : ''})`} + + + + + + { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} + )} + - - - { svaps - .map((item) => ( - - - - - - ), - }, + + { svaps + .map((item) => ( + + + + + + ), + }, - { - label: 'Replaced', - value: item.replaced ? 'Yes' : 'No', - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - actions={ + { + label: 'Replaced', + value: item.replaced ? 'Yes' : 'No', + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/system-maintenance/test-tool/test-tools-view.jsx b/src/app/components/system-maintenance/test-tool/test-tools-view.jsx index 1e7b361f0c..2e1876cfe7 100755 --- a/src/app/components/system-maintenance/test-tool/test-tools-view.jsx +++ b/src/app/components/system-maintenance/test-tool/test-tools-view.jsx @@ -14,7 +14,7 @@ import InfoIcon from '@material-ui/icons/Info'; import { ChplSearchResultCard, ChplSortControls, ChplTooltip } from 'components/util'; import { sortComparator } from 'components/util/sortable-headers'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -70,24 +70,22 @@ function ChplTestToolsView({ dispatch, testTools: initialTestTools }) { -
- -
- - - Search Results - - {`(${testTools.length} Result${testTools.length !== 1 ? 's' : ''})`} - - - - - { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( + + + + Search Results + + {`(${testTools.length} Result${testTools.length !== 1 ? 's' : ''})`} + + + + + { hasAnyRole(['chpl-admin', 'chpl-onc']) && ( - )} + )} + - - - { testTools - .map((item) => ( - - - - - + + { testTools + .map((item) => ( + + + + + )} - fieldGroups={[ - [ - { - label: 'Start Date', - value: getDisplayDateFormat(item.startDay), - }, - { - label: 'End Date', - value: getDisplayDateFormat(item.endDay), - }, - { - label: 'Applicable Criteria', - value: item.criteriaDisplay || 'N/A', - }, - ], - ]} - actions={ + fieldGroups={[ + [ + { + label: 'Start Date', + value: getDisplayDateFormat(item.startDay), + }, + { + label: 'End Date', + value: getDisplayDateFormat(item.endDay), + }, + { + label: 'Applicable Criteria', + value: item.criteriaDisplay || 'N/A', + }, + ], + ]} + actions={ hasAnyRole(['chpl-admin', 'chpl-onc']) && ( ) } - /> - ))} - + /> + ))} + + ); } diff --git a/src/app/components/util/chpl-search-result-controls.jsx b/src/app/components/util/chpl-search-result-controls.jsx index 556ad87d8b..6135459254 100644 --- a/src/app/components/util/chpl-search-result-controls.jsx +++ b/src/app/components/util/chpl-search-result-controls.jsx @@ -4,7 +4,7 @@ import { Typography, makeStyles, } from '@material-ui/core'; -import { node, number } from 'prop-types'; +import { node, number, string } from 'prop-types'; import { palette, theme } from 'themes'; @@ -14,14 +14,29 @@ const useStyles = makeStyles({ flexDirection: 'column', gap: '4px', marginBottom: '16px', + position: 'sticky', + top: '190px', + zIndex: 2, alignItems: 'flex-start', justifyContent: 'space-between', flexWrap: 'wrap', padding: '16px 32px', backgroundColor: palette.white, borderRadius: '0px 0px 8px 8px', - borderTop: `1px solid ${palette.greyBorder}`, - boxShadow: `0px 2px 4px -1px ${theme.palette.grey[300]}, 0px 4px 5px 0px ${theme.palette.grey[300]}, 0px 1px 10px 0px ${theme.palette.grey[300]}`, + borderRight: `1px solid ${palette.divider}`, + borderBottom: `1px solid ${palette.divider}`, + borderLeft: `1px solid ${palette.divider}`, + boxShadow: `0px 6px 8px -4px ${theme.palette.grey[300]}`, + '&::before': { + content: '""', + position: 'absolute', + left: 0, + right: 0, + bottom: '100%', + height: '90px', + background: ({ fadeBackground }) => `linear-gradient(to top, ${fadeBackground} 40%, transparent)`, + pointerEvents: 'none', + }, [theme.breakpoints.down('sm')]: { gap: '12px', padding: '16px', @@ -63,8 +78,9 @@ function ChplSearchResultControls({ pageStart, pageEnd, children = undefined, + fadeBackground = palette.backgroundPage, }) { - const classes = useStyles(); + const classes = useStyles({ fadeBackground }); return (
@@ -100,4 +116,5 @@ ChplSearchResultControls.propTypes = { pageStart: number.isRequired, pageEnd: number.isRequired, children: node, + fadeBackground: string, }; diff --git a/src/app/components/util/chpl-sort-controls.jsx b/src/app/components/util/chpl-sort-controls.jsx index c18bd2a4d3..1ae25db867 100644 --- a/src/app/components/util/chpl-sort-controls.jsx +++ b/src/app/components/util/chpl-sort-controls.jsx @@ -3,6 +3,7 @@ import { Box, Button, ButtonGroup, + Card, Menu, MenuItem, makeStyles, @@ -19,11 +20,14 @@ import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward'; import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward'; import SortIcon from '@material-ui/icons/Sort'; -import { theme } from 'themes'; +import { theme, palette } from 'themes'; const useStyles = makeStyles({ container: { marginRight: '16px', + display: 'flex', + border: `1px solid ${theme.palette.divider}`, + alignItems: 'center', [theme.breakpoints.down('sm')]: { width: '100%', marginRight: 0, @@ -83,7 +87,7 @@ function ChplSortControls({ }; return ( - +
-
- -
- { isLoading - && ( - - )} - { !isLoading + + { isLoading && ()} + { !isLoading && ( <> -
-
- Search Results: - { activities.length === 0 - && ( - - No results found - - )} - { activities.length > 0 - && ( - - {`(${pageStart}-${pageEnd} of ${recordCount} Results)`} - - )} -
-
+ + + { activities.length > 0 && ( <> - - - + { activities.map((item) => ( + } /> - - { activities - .map((item) => ( - - { item.username } - { item.concept } - { getDisplayDateFormat(item.activityDate) } - { item.description } - { item.reason } - { getLink(item) } - - - - - ))} - -
-
+ ))} + )} +
); diff --git a/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx b/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx index cac626caec..f5d391c39b 100755 --- a/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx +++ b/src/app/pages/reports/questionable-activity/questionable-activity-view.jsx @@ -1,12 +1,7 @@ import React, { useEffect, useState } from 'react'; import { + Box, Button, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableRow, Typography, makeStyles, } from '@material-ui/core'; @@ -16,12 +11,14 @@ import { useFetchQuestionableActivity } from 'api/questionable-activity'; import ChplQuestionableActivityDetails from 'components/activity/questionable-activity-details'; import { ChplLink, + ChplLoadingCards, ChplPagination, - ChplLoadingTable, - ChplSortableHeaders, + ChplSearchResultCard, + ChplSearchResultControls, + ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -30,15 +27,11 @@ import { getDisplayDateFormat } from 'services/date-util'; import { eventTrack } from 'services/analytics.service'; import { useSessionStorage as useStorage } from 'services/storage.service'; import { useAnalyticsContext } from 'shared/contexts'; -import { theme } from 'themes'; const useStyles = makeStyles({ fixFooterSpacing: { minHeight: 'calc(100vh - 188px)', }, - linkWrap: { - overflowWrap: 'anywhere', - }, pageHeader: { padding: '32px', backgroundColor: '#ffffff', @@ -50,46 +43,8 @@ const useStyles = makeStyles({ padding: '16px 32px', backgroundColor: '#f9f9f9', }, - pageContent: { - display: 'grid', - gridTemplateRows: '3fr 1fr', - }, - stickyColumn: { - position: 'sticky', - left: 0, - boxShadow: 'rgba(149, 157, 165, 0.1) 0px 4px 8px', - backgroundColor: '#ffffff', - overflowWrap: 'anywhere', - [theme.breakpoints.up('sm')]: { - minWidth: '275px', - }, - }, - tableContainer: { - overflowWrap: 'normal', - border: '.5px solid #c2c6ca', - margin: '0px 32px', - width: 'auto', - }, - tableResultsHeaderContainer: { - display: 'grid', - gap: '8px', - margin: '16px 32px', - gridTemplateColumns: '1fr', - alignItems: 'center', - justifyContent: 'space-between', - [theme.breakpoints.up('sm')]: { - gridTemplateColumns: 'auto auto', - }, - }, resultsContainer: { - display: 'grid', - gap: '8px', - justifyContent: 'start', - gridTemplateColumns: 'auto auto', - alignItems: 'center', - }, - wrap: { - flexFlow: 'wrap', + padding: '0 32px', }, }); @@ -139,15 +94,12 @@ function ChplQuestionableActivityView() { }, [API, authService]); /* eslint object-curly-newline: ["error", { "minProperties": 5, "consistent": true }] */ - const headers = [ - { property: 'developer', text: 'Developer', sortable: true }, - { property: 'product', text: 'Product', sortable: true }, - { property: 'version', text: 'Version', sortable: true }, - { property: 'chpl_product_number', text: 'CHPL ID', sortable: true }, - { text: 'Activity' }, - { property: 'activity_date', text: 'Activity Date', sortable: true }, - { text: 'Reason' }, - { text: 'Actions', invisible: true }, + const sortOptions = [ + { property: 'developer', text: 'Developer' }, + { property: 'product', text: 'Product' }, + { property: 'version', text: 'Version' }, + { property: 'chpl_product_number', text: 'CHPL ID' }, + { property: 'activity_date', text: 'Activity Date', reverseDefault: true }, ]; const handleClick = () => { @@ -158,7 +110,7 @@ function ChplQuestionableActivityView() { window.open(`${downloadLink}&${filterContext.queryString()}`); }; - const handleTableSort = (event, property, orderDirection) => { + const handleSort = (property, orderDirection) => { eventTrack({ ...analytics, event: 'Sort Column', @@ -183,33 +135,23 @@ function ChplQuestionableActivityView() {
- -
- -
- { isLoading - && ( - - )} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> -
-
- Search Results: - { activities.length === 0 - && ( - - No results found - - )} - { activities.length > 0 - && ( - - {`(${pageStart}-${pageEnd} of ${recordCount} Results)`} - - )} -
+ + { activities.length > 0 && (
+ { activities.length > 0 && ( <> - - - - - { activities - .map((item) => ( - - - { item.developerId - && ( - - )} - - {item.productName} - {item.versionName} - - { item.listingId - && ( + + { activities.map((item) => ( + + ) + : item.developerName || 'N/A'} + fieldGroups={[ + [ + { label: 'Product', value: item.productName }, + { label: 'Version', value: item.versionName }, + { + label: 'CHPL ID', + style: { flex: '2 1 320px' }, + value: item.listingId + ? ( - )} - - {item.triggerName} - { getDisplayDateFormat(item.activityDate) } - - { item.reason - && ( - - {item.reason} - - )} - { item.certificationStatusChangeReason - && ( - - {item.certificationStatusChangeReason} - - )} - - - - - - ))} - -
-
+ ) + : item.chplProductNumber, + }, + ], + [ + { label: 'Activity', value: item.triggerName }, + { label: 'Activity Date', value: getDisplayDateFormat(item.activityDate) }, + { + label: 'Reason', + style: { flex: '2 1 320px' }, + value: item.reason || item.certificationStatusChangeReason || 'N/A', + }, + ], + ]} + actions={} + /> + ))} + )} +
); } diff --git a/src/app/pages/search/api-documentation/api-documentation-view.jsx b/src/app/pages/search/api-documentation/api-documentation-view.jsx index 4f8d76829a..b53a76a340 100755 --- a/src/app/pages/search/api-documentation/api-documentation-view.jsx +++ b/src/app/pages/search/api-documentation/api-documentation-view.jsx @@ -20,7 +20,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -170,10 +170,10 @@ function ChplApiDocumentationSearchView({ displayCriteria }) { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> @@ -282,6 +286,7 @@ function ChplApiDocumentationSearchView({ displayCriteria }) { }, { label: 'Mandatory Disclosures URL', + style: { fontSize: '0.85em' }, value: item.mandatoryDisclosures ? ( )} + ); diff --git a/src/app/pages/search/banned-developers/banned-developers-view.jsx b/src/app/pages/search/banned-developers/banned-developers-view.jsx index a1401db6e7..32f5dc6ad4 100755 --- a/src/app/pages/search/banned-developers/banned-developers-view.jsx +++ b/src/app/pages/search/banned-developers/banned-developers-view.jsx @@ -18,7 +18,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -122,17 +122,18 @@ function ChplBannedDevelopersSearchView() { inline /> . - + )} /> - - {isLoading && ()} - {!isLoading + + {isLoading && ()} + {!isLoading && ( <> )} + ); diff --git a/src/app/pages/search/corrective-action/corrective-action-view.jsx b/src/app/pages/search/corrective-action/corrective-action-view.jsx index 34e350bf10..bdbb93792e 100755 --- a/src/app/pages/search/corrective-action/corrective-action-view.jsx +++ b/src/app/pages/search/corrective-action/corrective-action-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -139,10 +139,10 @@ function ChplCorrectiveActionSearchView() { { directReviewsAvailable && ( <> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + )} diff --git a/src/app/pages/search/decertified-products/decertified-products-view.jsx b/src/app/pages/search/decertified-products/decertified-products-view.jsx index 1774622761..ff209550d3 100755 --- a/src/app/pages/search/decertified-products/decertified-products-view.jsx +++ b/src/app/pages/search/decertified-products/decertified-products-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -124,10 +124,10 @@ function ChplDecertifiedProductsSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx b/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx index 531b2bae64..6fd1bf91b2 100644 --- a/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx +++ b/src/app/pages/search/decision-support-interventions/decision-support-interventions-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -110,10 +110,10 @@ function ChplDecisionSupportInterventionsSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx b/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx index 4084783299..b94d0774b5 100755 --- a/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx +++ b/src/app/pages/search/inactive-certificates/inactive-certificates-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -127,10 +127,10 @@ function ChplInactiveCertificatesSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/listings/listings-view.jsx b/src/app/pages/search/listings/listings-view.jsx index 91bf06107f..9a308ee5d3 100755 --- a/src/app/pages/search/listings/listings-view.jsx +++ b/src/app/pages/search/listings/listings-view.jsx @@ -24,7 +24,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -138,10 +138,10 @@ function ChplListingsView() { subtitle="Please note that only active and suspended listings are shown by default. Use the Certification Status filter to display retired, withdrawn, or terminated listings." /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/real-world-testing/real-world-testing-view.jsx b/src/app/pages/search/real-world-testing/real-world-testing-view.jsx index 4cd01b33c6..265d79c329 100755 --- a/src/app/pages/search/real-world-testing/real-world-testing-view.jsx +++ b/src/app/pages/search/real-world-testing/real-world-testing-view.jsx @@ -19,7 +19,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -155,10 +155,10 @@ function ChplRealWorldTestingSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/sed/sed-view.jsx b/src/app/pages/search/sed/sed-view.jsx index b5b35de25b..2c7dea9d81 100755 --- a/src/app/pages/search/sed/sed-view.jsx +++ b/src/app/pages/search/sed/sed-view.jsx @@ -20,7 +20,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -124,10 +124,10 @@ function ChplSedSearchView() { )} /> - - - { isLoading && ()} - { !isLoading + + + { isLoading && ()} + { !isLoading && ( <> )} + ); diff --git a/src/app/pages/search/svap/svap-view.jsx b/src/app/pages/search/svap/svap-view.jsx index b045185163..d67817d656 100755 --- a/src/app/pages/search/svap/svap-view.jsx +++ b/src/app/pages/search/svap/svap-view.jsx @@ -20,7 +20,7 @@ import { ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -232,10 +232,10 @@ function ChplSvapSearchView() { )} /> - - - {isLoading && ()} - {!isLoading + + + {isLoading && ()} + {!isLoading && ( <> )} + ); diff --git a/src/app/pages/subscriptions/manage-subscriptions-view.jsx b/src/app/pages/subscriptions/manage-subscriptions-view.jsx index e6ebdbf705..a690943265 100755 --- a/src/app/pages/subscriptions/manage-subscriptions-view.jsx +++ b/src/app/pages/subscriptions/manage-subscriptions-view.jsx @@ -4,10 +4,8 @@ import { Button, Card, CardHeader, - CircularProgress, List, ListItem, - Typography, makeStyles, } from '@material-ui/core'; import { shape, string } from 'prop-types'; @@ -17,12 +15,14 @@ import { NotificationsOutlined, SubscriptionsOutlined } from '@material-ui/icons import { useFetchAllSubscriptions, usePostGetDeliveredNotifications } from 'api/subscriptions'; import { ChplLink, + ChplLoadingCards, ChplPagination, ChplSearchResultCard, + ChplSearchResultControls, ChplSortControls, } from 'components/util'; import { - ChplFilterChips, + ChplFilterLayout, ChplFilterSearchBar, useFilterContext, } from 'components/filter'; @@ -38,6 +38,9 @@ const sortOptions = [ ]; const useStyles = makeStyles({ + card: { + overflow: 'visible', + }, linkWrap: { overflowWrap: 'anywhere', }, @@ -84,14 +87,7 @@ const useStyles = makeStyles({ }, }, resultsContainer: { - display: 'grid', - gap: '8px', - justifyContent: 'start', - gridTemplateColumns: 'auto auto', - alignItems: 'center', - }, - wrap: { - flexFlow: 'wrap', + padding: '0 32px', }, listContainer: { fontSize: 'smaller', @@ -173,7 +169,7 @@ function ChplManageSubscriptionsView({ analytics }) { const pageEnd = Math.min((pageNumber + 1) * pageSize, recordCount); return ( - +
-
- -
- { isLoading - && ( - - )} - { !isLoading + + { isLoading && ()} + { !isLoading && ( <> -
-
- Search Results: - { subscriptions.length === 0 - && ( - - No results found - - )} - { subscriptions.length > 0 - && ( - - {`(${pageStart}-${pageEnd} of ${recordCount} Results)`} - - )} -
+ { subscriptions.length > 0 && ( )} -
+ { subscriptions.length > 0 && ( <> - + { subscriptions.map((item) => ( )} +
);