Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable react/forbid-prop-types */
import React, { useEffect, useState } from 'react';

Check failure on line 2 in src/App.jsx

View workflow job for this annotation

GitHub Actions / build

'useState' is defined but never used
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { FormattedMessage, IntlProvider } from 'react-intl';
Expand Down Expand Up @@ -29,7 +29,6 @@
const { user, dispatchSetOidcUser, dispatchEnrichUser } = props;
const { fullscreen } = useParams();
const location = useLocation();
const [locale, setLocale] = useState(language);

getCookieScripts();
if (config.enableCookies) {
Expand Down Expand Up @@ -73,18 +72,18 @@

let header = null;
if (!fullscreen && !headless) {
header = <Header slim={location.pathname !== '/'} history={history} locale={locale} setLocale={setLocale} />;
header = <Header slim={location.pathname !== '/'} history={history} />;
}
const mainContainerId = 'main-container';
return (
<IntlProvider locale={locale} language={locale} messages={messages[locale] || {}}>
<IntlProvider locale={language} messages={messages[language] || {}}>
<div className={contrastClass}>
{config.enableCookies && !isCookiebotEnabled() && <CookieBar language={locale} />}
{config.enableCookies && !isCookiebotEnabled() && <CookieBar />}
<InternalLink className='skip-to-main-content' destinationId={mainContainerId}>
<FormattedMessage id='skipToMainContent' />
</InternalLink>
<Helmet titleTemplate='%s - Kerrokantasi' link={favlinks} meta={favmeta}>
<html lang={locale} />
<html lang={language} />
{isCookiebotEnabled() && getCookieBotConsentScripts()}
</Helmet>
{header}
Expand All @@ -97,7 +96,7 @@
>
<Routes />
</main>
<Footer language={locale} />
<Footer />
<Toast />
</div>
</IntlProvider>
Expand Down
9 changes: 6 additions & 3 deletions src/components/CookieBar/CookieBar.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React, { useState } from 'react';
import React from 'react';
import { CookieModal } from 'hds-react';

import { getHDSCookieConfig } from '../../utils/cookieUtils';

Check failure on line 4 in src/components/CookieBar/CookieBar.jsx

View workflow job for this annotation

GitHub Actions / build

There should be at least one empty line between import groups
import config from '../../config';
import { useDispatch, useSelector } from 'react-redux';

Check failure on line 5 in src/components/CookieBar/CookieBar.jsx

View workflow job for this annotation

GitHub Actions / build

There should be at least one empty line between import groups

Check failure on line 5 in src/components/CookieBar/CookieBar.jsx

View workflow job for this annotation

GitHub Actions / build

`react-redux` import should occur before import of `../../utils/cookieUtils`
import { setLanguage as setLanguageDispatch } from '../../actions';

function CookieBar() {
const dispatch = useDispatch();
const siteName = document.querySelector("meta[property='og:title']").getAttribute('content');
const [language, setLanguage] = useState(config.activeLanguage);
const language = useSelector(state => state.language)
const setLanguage = (newLocale) => dispatch(setLanguageDispatch(newLocale));
const getCookieModalConfig = () => getHDSCookieConfig(siteName, language, setLanguage);

return <CookieModal contentSource={getCookieModalConfig()} />;
Expand Down
11 changes: 5 additions & 6 deletions src/components/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable import/no-unresolved */
/* eslint-disable react/forbid-prop-types */
import React from 'react';
import { FormattedMessage, injectIntl } from 'react-intl';
import { FormattedMessage, injectIntl, useIntl } from 'react-intl';

Check failure on line 4 in src/components/Footer.jsx

View workflow job for this annotation

GitHub Actions / build

'injectIntl' is defined but never used
import PropTypes from 'prop-types';
import settings from '@city-assets/settings.json';
import { Footer as HDSFooter, Logo } from 'hds-react';
Expand All @@ -17,8 +17,9 @@
import { isAdmin } from '../utils/user';

const Footer = (props) => {
const { language, user, intl } = props;

const { user } = props;
const intl = useIntl();
const language = intl.locale;
const userIsAdmin = isAdmin(user);

const scrollToFn = () => window.scrollTo(0, 0);
Expand Down Expand Up @@ -93,11 +94,9 @@
};

Footer.propTypes = {
language: PropTypes.string,
user: PropTypes.object,
intl: PropTypes.object,
};

export default connect((state) => ({
user: getUser(state),
}))(injectIntl(Footer));
}))(Footer);
12 changes: 7 additions & 5 deletions src/components/Header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import getUser from '../../selectors/user';
import useAuthHook from '../../hooks/useAuth';
import { addToast } from '../../actions/toast';
import { createLocalizedNotificationPayload, NOTIFICATION_TYPES } from '../../utils/notify';
import { setLanguage } from '../../actions';

const Header = ({ user, locale, setLocale }) => {
const Header = ({ user }) => {
const { authenticated, login, logout } = useAuthHook();
const location = useLocation();
const dispatch = useDispatch();
Expand All @@ -24,6 +25,10 @@ const Header = ({ user, locale, setLocale }) => {

const language = intl.locale;

const setLocale = (newLocale) => {
dispatch(setLanguage(newLocale));
};

const doLogin = async () => {
if (config.maintenanceDisableLogin) {
dispatch(addToast(createLocalizedNotificationPayload(NOTIFICATION_TYPES.error, 'maintenanceNotificationText')));
Expand Down Expand Up @@ -53,7 +58,7 @@ const Header = ({ user, locale, setLocale }) => {
useEffect(() => {
const langParam = searchParams.get('lang');

if (langParam && langParam !== locale) {
if (langParam && langParam !== language) {
setLocale(langParam);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -142,11 +147,8 @@ const Header = ({ user, locale, setLocale }) => {

Header.propTypes = {
user: PropTypes.object,
locale: PropTypes.string,
setLocale: PropTypes.func,
};

export default connect((state) => ({
user: getUser(state),
language: state.language,
}))(Header);
21 changes: 10 additions & 11 deletions src/components/Header/__tests__/Header.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Header from '../Header';
import renderWithProviders from '../../../utils/renderWithProviders';
import { mockUser } from '../../../../test-utils';
import * as useAuthMock from '../../../hooks/useAuth';
import * as actionsMock from '../../../actions';

const middlewares = [thunk];
const mockStore = configureStore(middlewares);
Expand All @@ -20,8 +21,14 @@ const defaultState = {
language: defaultLocale,
user: { data: { ...mockUser } },
};
const stateWithoutUser = {
language: 'fi',
user: { data: null },
};

const renderComponent = (storeOverride, authMock = {}) => {
jest.spyOn(actionsMock, 'setLanguage').mockImplementation(() => (jest.fn()));

jest.spyOn(useAuthMock, 'default').mockImplementation(() => ({
authenticated: authMock.authenticated ?? false,
login: authMock.login ?? jest.fn(),
Expand All @@ -44,10 +51,6 @@ describe('<Header />', () => {
});

it('displays login button when user is not logged in', async () => {
const stateWithoutUser = {
language: 'fi',
user: { data: null },
};

const store = mockStore(stateWithoutUser);

Expand All @@ -59,11 +62,6 @@ describe('<Header />', () => {
it('calls login function when login button is clicked', async () => {
const user = userEvent.setup();

const stateWithoutUser = {
language: 'fi',
user: { data: null },
};

const mockLogin = jest.fn();

const store = mockStore(stateWithoutUser);
Expand All @@ -90,10 +88,11 @@ describe('<Header />', () => {
it('changes language when language selector is used', async () => {
const user = userEvent.setup();

renderComponent();
const store = mockStore(stateWithoutUser)
renderComponent(store);

await user.click(await screen.findByRole('button', { name: 'English' }));

expect(mockSetLocale).toHaveBeenCalled();
expect(actionsMock.setLanguage).toHaveBeenCalled();
});
});
16 changes: 11 additions & 5 deletions src/getRoot.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,36 @@ import { Provider } from 'react-redux';
import { isIE } from 'react-device-detect';
import { LoginProvider } from 'hds-react';
import { BrowserRouter } from 'react-router-dom';
import { IntlProvider } from 'react-intl';

import { history } from './createStore';
import App from './App';
import ScrollToTop from './scrollToTop';
import BrowserWarning from './views/BrowserWarning';
import { userOidcConfig, apiTokenClientConfig } from './utils/oidcConfig';
import messages from './i18n';

const loginProviderProps = {
userManagerSettings: userOidcConfig,
apiTokensClientSettings: apiTokenClientConfig,
sessionPollerSettings: { pollIntervalInMs: 10000 },
};

const locale = 'fi';

export default function getRoot(store) {
return isIE ? (
<BrowserWarning />
) : (
<LoginProvider {...loginProviderProps}>
<Provider store={store}>
<BrowserRouter history={history}>
<ScrollToTop>
<App history={history} />
</ScrollToTop>
</BrowserRouter>
<IntlProvider locale={locale} language={locale} messages={messages[locale] || {}}>
<BrowserRouter history={history}>
<ScrollToTop>
<App history={history} />
</ScrollToTop>
</BrowserRouter>
</IntlProvider>
</Provider>
</LoginProvider>
);
Expand Down
5 changes: 4 additions & 1 deletion src/hooks/useAuth.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useOidcClient } from "hds-react"
import { useSelector } from "react-redux";

export const useAuth = () => {
const { isAuthenticated, getUser, login, logout } = useOidcClient();
const locale = useSelector(state => state.language);

const handleLogin = async () => {
login();
console.debug('Logging in with locale', locale);

Check warning on line 9 in src/hooks/useAuth.js

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
login({language: locale, state: {returnUrl: window.location.pathname}});
}
const handleLogout = async () => {
logout();
Expand Down
Loading