Skip to content

Commit

Permalink
OpenConceptLab/ocl_issues#1058 | Recent history component | navigatio…
Browse files Browse the repository at this point in the history
…n back to previous visited pages
  • Loading branch information
snyaggarwal committed Nov 11, 2021
1 parent d108e25 commit 577cc3b
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 5 deletions.
65 changes: 64 additions & 1 deletion src/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import moment from 'moment';
import {
filter, difference, compact, find, reject, intersectionBy, size, keys, omitBy, isEmpty,
get, includes, map, isArray, values, pick, sortBy, zipObject, orderBy, isObject, merge,
uniqBy, cloneDeep
uniqBy, cloneDeep, isEqual, without, capitalize, last
} from 'lodash';
import {
DATE_FORMAT, DATETIME_FORMAT, OCL_SERVERS_GROUP, OCL_FHIR_SERVERS_GROUP, HAPI_FHIR_SERVERS_GROUP,
Expand Down Expand Up @@ -526,3 +526,66 @@ export const getOpenMRSURL = () => {

return OPENMRS_URL.replace('openmrs.', `openmrs.${env}`);
}

export const setUpRecentHistory = history => {
history.listen(location => {
let visits = JSON.parse(get(localStorage, 'visits', '[]'));
let urlParts = compact(location.pathname.split('/'));
let type = '';
let category = '';
let format = false;
if(location.pathname.match('/login') || location.pathname === '/')
return;
if(location.pathname.match('/imports')) {
type = category = 'import';
format = true;
} else if(location.pathname.match('/search/')) {
category = 'search';
const queryParams = new URLSearchParams(location.search);
type = queryParams.get('type');
format = true;
} else if(location.pathname.match('/compare')) {
category = 'compare';
type = 'concepts';
format = true;
} else {
if(urlParts.length <= 3) {
type = category = urlParts[0];
urlParts = without(urlParts, 'orgs', 'users');
}
if(urlParts.length == 4) {
type = category = urlParts[2];
urlParts = without(urlParts, 'orgs', 'users', 'sources', 'collections');
}
if(urlParts.length == 5) {
if(includes(['mappings', 'concepts', 'versions', 'references'], last(urlParts))) {
type = category = last(urlParts);
}
urlParts = without(urlParts, 'orgs', 'users', 'sources', 'collections');
}
if(urlParts.length >= 6) {
if(location.pathname.match('/concepts/')) {
type = category = 'concept';
}
if(location.pathname.match('/mappings/')) {
type = category = 'mapping';
}
if(location.pathname.match('/references')) {
type = category = 'reference';
}
urlParts = without(urlParts, 'orgs', 'users', 'sources', 'collections');
}
}
if(!includes(['concepts', 'mappings'], last(urlParts)))
urlParts = without(urlParts, 'concepts', 'mappings');
let name = format ? map(urlParts, capitalize).join(' / ') : urlParts.join(' / ');
if(category !== type && type)
name += ' / ' + type;
const lastVisit = visits[0];
if(isEqual(get(lastVisit, 'name'), name))
visits.shift();
visits.push({name: name, location: location, type: type || '', category: category || '', at: new Date().getTime()});
visits = orderBy(visits, 'at', 'desc').slice(0, 10);
localStorage.setItem('visits', JSON.stringify(visits));
});
}
8 changes: 5 additions & 3 deletions src/components/app/App.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*eslint no-process-env: 0*/
import React from 'react';
import { Route, Switch } from 'react-router-dom';
import { Route, Switch, withRouter } from 'react-router-dom';
import ReactGA from 'react-ga';
import { get } from 'lodash';
import { isFHIRServer, isLoggedIn } from '../../common/utils';
import { isFHIRServer, isLoggedIn, setUpRecentHistory } from '../../common/utils';
import Search from '../search/Search';
import ConceptHome from '../concepts/ConceptHome';
import MappingHome from '../mappings/MappingHome';
Expand Down Expand Up @@ -41,6 +41,8 @@ const AuthenticationRequiredRoute = ({component: Component, ...rest}) => (
)

const App = props => {
// For recent history
setUpRecentHistory(props.history);
const [menuOpen, setMenuOpen] = React.useState(false);
const setupGA = () => {
/*eslint no-undef: 0*/
Expand Down Expand Up @@ -247,5 +249,5 @@ const App = props => {
);
}

export default App;
export default withRouter(App);

2 changes: 2 additions & 0 deletions src/components/app/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { WHITE, BLACK } from '../../common/constants';
import SearchInput from '../search/SearchInput';
import UserOptions from '../users/UserOptions';
import Favorites from './Favorites';
import RecentHistory from './RecentHistory';
import { OPTIONS, SITE_URL } from './MenuOptions.jsx';
/* import Feedback from '../common/Feedback'; */
import AppsMenu from '../common/AppsMenu';
Expand Down Expand Up @@ -167,6 +168,7 @@ const Header = props => {
{
authenticated ?
<span style={{marginLeft: '20px'}}>
<RecentHistory />
<Favorites />
<AppsMenu/>
<UserOptions />
Expand Down
81 changes: 81 additions & 0 deletions src/components/app/RecentHistory.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';
import { isEmpty, map } from 'lodash';
import {
IconButton, Tooltip,
List, ListItem, ListItemIcon, ListItemText,
ListSubheader, ListItemButton
} from '@mui/material';
import { History as HistoryIcon } from '@mui/icons-material';
import DynamicConfigResourceIcon from '../common/DynamicConfigResourceIcon';
import PopperGrow from '../common/PopperGrow';

const RecentHistory = () => {
const [open, setOpen] = React.useState(false);
const anchorRef = React.useRef(null);
const handleToggle = () => setOpen(!open);

const handleClose = event => {
if (anchorRef.current && anchorRef.current.contains(event.target))
return;
setOpen(false);
};
const visits = JSON.parse(localStorage.getItem('visits') || '[]')
return (
<React.Fragment>
<Tooltip arrow title='Recent History'>
<IconButton
ref={anchorRef}
aria-controls={open ? 'history-menu' : undefined}
aria-expanded={open ? 'true' : undefined}
aria-label="select merge strategy"
aria-haspopup="menu"
onClick={handleToggle}
touch='true'
size="large"
color={open ? 'primary' : 'default'}
>
<HistoryIcon />
</IconButton>
</Tooltip>
<PopperGrow open={open} anchorRef={anchorRef} handleClose={handleClose}>
<div>
<div style={{width: '100%', padding: '5px 10px', justifyContent: 'space-between', background: 'rgba(0, 0, 0, 0.1)'}} className='flex-vertical-center'>
<span style={{textAlign: 'left'}}>
<b>Recent</b> (showing last 10)
</span>
</div>
{
isEmpty(visits) &&
<List dense style={{textAlign: 'left', paddingTop: '0px', paddingBottom: '0px'}} subheader={
<ListSubheader style={{lineHeight: '24px', padding: '0 10px', fontSize: '0.8rem'}} component="div" id="nested-list-subheader">
Nothing here so far.
</ListSubheader>
}/>
}
<List dense style={{paddingTop: '0px', paddingBottom: '0px', textAlign: 'left', display: isEmpty(visits) ? 'none' : 'initial'}}>
{
map(visits, (visit, i) => {
return (
<ListItem disablePadding key={i}>
<ListItemButton role={undefined} href={`#${visit.location.pathname + visit.location.search}`} dense component="a" style={{padding: '0 15px'}}>
<ListItemIcon style={{minWidth: 'auto', marginRight: '10px'}}>
<DynamicConfigResourceIcon
resource={visit.category.toLowerCase()}
fontSize='inherit'
enableColor
/>
</ListItemIcon>
<ListItemText primary={visit.name.replaceAll('- OCL', '')} />
</ListItemButton>
</ListItem>
)
})
}
</List>
</div>
</PopperGrow>
</React.Fragment>
)
}

export default RecentHistory;
10 changes: 9 additions & 1 deletion src/components/common/DynamicConfigResourceIcon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { Icon } from '@mui/material';
import {
List as SourceIcon, Loyalty as CollectionIcon, Person as UserIcon,
Info as InfoIcon, Home as HomeIcon, Link as MappingIcon,
AccountTreeRounded as VersionIcon, LocalOffer as ConceptIcon
AccountTreeRounded as VersionIcon, LocalOffer as ConceptIcon,
Search as SearchIcon, Publish as ImportsIcon,
CompareArrows as CompareIcon
} from '@mui/icons-material';
import { includes, snakeCase } from 'lodash';
import { GREEN, BLUE, ORANGE } from '../../common/constants';
Expand All @@ -30,6 +32,12 @@ const DynamicConfigResourceIcon = ({resource, index, style, icon, enableColor, .
return <HomeIcon style={styles} />;
if(includes(['about', 'text'], resource))
return <InfoIcon style={styles} {...rest} />;
if(includes(['search'], resource))
return <SearchIcon style={{...styles, color: enableColor ? BLUE : ''}} {...rest} />;
if(includes(['import', 'imports'], resource))
return <ImportsIcon color='secondary' {...rest} />;
if(includes(['compare'], resource))
return <CompareIcon color='primary' {...rest} />;

return '';
}
Expand Down
1 change: 1 addition & 0 deletions src/components/users/UserOptions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import PopperGrow from '../common/PopperGrow';
const onLogoutClick = msg => {
localStorage.removeItem('token');
localStorage.removeItem('user');
localStorage.removeItem('visits');
alertifyjs.success(msg || 'You have signed out.')
window.location.hash = '#/'
window.location.reload()
Expand Down

0 comments on commit 577cc3b

Please sign in to comment.