Skip to content

Commit

Permalink
Merge pull request #1764 from bjoernricks/timezone-in-usermenu
Browse files Browse the repository at this point in the history
Timezone in usermenu
  • Loading branch information
swaterkamp authored Nov 8, 2019
2 parents e764a55 + 73b9f28 commit b94a306
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 90 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [9.0.1] - unreleased

### Added
- Display timezone for session timeout in user menu [#1764](https://github.com/greenbone/gsa/pull/1764)

### Changed
- Fix react-scripts dependency because it broke tooltips [#1760](https://github.com/greenbone/gsa/pull/1760)
Expand Down
20 changes: 8 additions & 12 deletions gsa/src/web/components/date/datetime.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import {connect} from 'react-redux';

import {dateTimeWithTimeZone, ensureDate} from 'gmp/locale/date';

import {isDefined} from 'gmp/utils/identity';

import {getTimezone} from 'web/store/usersettings/selectors';
import {isDefined, hasValue} from 'gmp/utils/identity';

import PropTypes from 'web/utils/proptypes';
import useUserTimezone from 'web/utils/useUserTimezone';

const DateTime = ({formatter = dateTimeWithTimeZone, timezone, date}) => {
date = ensureDate(date);

const userTimezone = useUserTimezone();

if (!hasValue(timezone)) {
timezone = userTimezone;
}
return !isDefined(date) || !date.isValid() ? null : formatter(date, timezone);
};

Expand All @@ -38,10 +40,4 @@ DateTime.propTypes = {
timezone: PropTypes.string,
};

const mapStateToProps = (rootState, ownProps) => ({
timezone: isDefined(ownProps.timezone)
? ownProps.timezone
: getTimezone(rootState),
});

export default connect(mapStateToProps)(DateTime);
export default DateTime;
131 changes: 53 additions & 78 deletions gsa/src/web/components/menu/usermenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
*/
import React from 'react';

import {connect} from 'react-redux';

import {withRouter} from 'react-router-dom';
import {useHistory} from 'react-router-dom';

import styled, {keyframes} from 'styled-components';

import _ from 'gmp/locale';
import {longDate} from 'gmp/locale/date';
import {dateTimeWithTimeZone} from 'gmp/locale/date';

import LogoutIcon from 'web/components/icon/logouticon';
import MySettingsIcon from 'web/components/icon/mysettingsicon';
Expand All @@ -35,12 +33,11 @@ import UserIcon from 'web/components/icon/usericon';
import Divider from 'web/components/layout/divider';
import Link from 'web/components/link/link';

import compose from 'web/utils/compose';
import PropTypes from 'web/utils/proptypes';
import Theme from 'web/utils/theme';
import withGmp from 'web/utils/withGmp';

import {getUsername, getSessionTimeout} from 'web/store/usersettings/selectors';
import useGmp from 'web/utils/useGmp';
import useUserName from 'web/utils/useUserName';
import useUserSessionTimeout from 'web/utils/useUserSessionTimeout';
import useUserTimezone from 'web/utils/useUserTimezone';

const UserMenu = styled.span`
display: inline-flex;
Expand Down Expand Up @@ -131,84 +128,62 @@ const StyledLink = styled(Link)`
}
`;

class UserMenuContainer extends React.Component {
constructor(...args) {
super(...args);
this.handleLogout = this.handleLogout.bind(this);
}

handleLogout(event) {
const {gmp, history} = this.props;
const UserMenuContainer = () => {
const sessionTimeout = useUserSessionTimeout();
const userTimezone = useUserTimezone();
const userName = useUserName();
const gmp = useGmp();
const history = useHistory();

const handleLogout = event => {
event.preventDefault();

gmp.doLogout().then(() => {
history.push('/login?type=logout');
});
}
render() {
const {sessionTimeout, userName} = this.props;

return (
<UserMenu data-testid="usermenu">
<StyledUserIcon size="medium" />
<Div>
<List>
<Entry title={_('Logged in as: {{userName}}', {userName})}>
};

return (
<UserMenu data-testid="usermenu">
<StyledUserIcon size="medium" />
<Div>
<List>
<Entry title={_('Logged in as: {{userName}}', {userName})}>
<Divider>
<UserIcon />
<span>{userName}</span>
</Divider>
</Entry>
<Entry>
<Divider>
<ScheduleIcon />
<span>
{_('Session timeout: {{date}}', {
date: dateTimeWithTimeZone(sessionTimeout, userTimezone),
})}
</span>
</Divider>
</Entry>
<Entry>
<StyledLink to="usersettings" data-testid="usermenu-settings">
<Divider>
<UserIcon />
<span>{userName}</span>
<MySettingsIcon />
<span>{_('My Settings')}</span>
</Divider>
</Entry>
<Entry>
<Divider>
<ScheduleIcon />
<span>
{_('Session timeout: {{date}}', {
date: longDate(sessionTimeout),
})}
</span>
</Divider>
</Entry>
<Entry>
<StyledLink to="usersettings" data-testid="usermenu-settings">
<Divider>
<MySettingsIcon />
<span>{_('My Settings')}</span>
</Divider>
</StyledLink>
</Entry>
<Entry
data-testid="usermenu-logout"
onClick={event => this.handleLogout(event)}
>
<Divider>
<LogoutIcon />
<span>{_('Log Out')}</span>
</Divider>
</Entry>
</List>
</Div>
</UserMenu>
);
}
}

UserMenuContainer.propTypes = {
gmp: PropTypes.gmp.isRequired,
history: PropTypes.object.isRequired,
icon: PropTypes.element,
sessionTimeout: PropTypes.date,
userName: PropTypes.string,
</StyledLink>
</Entry>
<Entry data-testid="usermenu-logout" onClick={handleLogout}>
<Divider>
<LogoutIcon />
<span>{_('Log Out')}</span>
</Divider>
</Entry>
</List>
</Div>
</UserMenu>
);
};

export default compose(
withGmp,
withRouter,
connect(rootState => ({
sessionTimeout: getSessionTimeout(rootState),
userName: getUsername(rootState),
})),
)(UserMenuContainer);
export default UserMenuContainer;

// vim: set ts=2 sw=2 tw=80:
42 changes: 42 additions & 0 deletions gsa/src/web/utils/__tests__/useGmp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* Copyright (C) 2019 Greenbone Networks GmbH
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import React from 'react';

import {rendererWith} from '../testing';

import useGmp from '../useGmp';

const TestUseGmp = () => {
const gmp = useGmp();
return <span>{gmp.foo()}</span>;
};

describe('useGmp tests', () => {
test('should return the current gmp object', () => {
const foo = jest.fn().mockReturnValue('foo');
const gmp = {foo};

const {render} = rendererWith({gmp});

const {element} = render(<TestUseGmp />);

expect(foo).toHaveBeenCalled();
expect(element).toHaveTextContent(/^foo$/);
});
});
39 changes: 39 additions & 0 deletions gsa/src/web/utils/__tests__/useUserName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright (C) 2019 Greenbone Networks GmbH
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import React from 'react';

import {setUsername} from 'web/store/usersettings/actions';

import {rendererWith} from '../testing';

import useUserName from '../useUserName';

const TestUserName = () => <span>{useUserName()}</span>;

describe('useUserName tests', () => {
test('should return the users name', () => {
const {render, store} = rendererWith({store: true});

store.dispatch(setUsername('foo'));

const {element} = render(<TestUserName />);

expect(element).toHaveTextContent(/^foo$/);
});
});
46 changes: 46 additions & 0 deletions gsa/src/web/utils/__tests__/useUserSessionTimeout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* Copyright (C) 2019 Greenbone Networks GmbH
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import React from 'react';

import {dateFormat} from 'gmp/locale/date';
import date from 'gmp/models/date';

import {setSessionTimeout} from 'web/store/usersettings/actions';

import {rendererWith} from '../testing';

import useUserSessionTimeout from '../useUserSessionTimeout';

const TestUserSessionTimeout = () => (
<span>{dateFormat(useUserSessionTimeout(), 'DD-MM-YY')}</span>
);

describe('useUserSessionTimeout tests', () => {
test('should return the users session timeout', () => {
const {render, store} = rendererWith({store: true});

const timeout = date('2019-10-10');

store.dispatch(setSessionTimeout(timeout));

const {element} = render(<TestUserSessionTimeout />);

expect(element).toHaveTextContent(/^10-10-19$/);
});
});
39 changes: 39 additions & 0 deletions gsa/src/web/utils/__tests__/useUserTimezone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright (C) 2019 Greenbone Networks GmbH
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import React from 'react';

import {setTimezone} from 'web/store/usersettings/actions';

import {rendererWith} from '../testing';

import useUserTimezone from '../useUserTimezone';

const TestUserTimezone = () => <span>{useUserTimezone()}</span>;

describe('useUserTimezone tests', () => {
test('should return the users timezone', () => {
const {render, store} = rendererWith({store: true});

store.dispatch(setTimezone('CET'));

const {element} = render(<TestUserTimezone />);

expect(element).toHaveTextContent(/^CET$/);
});
});
Loading

0 comments on commit b94a306

Please sign in to comment.