Skip to content

Commit

Permalink
Merge pull request #378 from City-of-Helsinki/fix-broken-layout-HAUKI…
Browse files Browse the repository at this point in the history
…-618

fix: broken layout hauki 618 and translate header and footer hauki 610
  • Loading branch information
timwessman authored Feb 20, 2024
2 parents 798b6e6 + d70d803 commit fe1e1f7
Show file tree
Hide file tree
Showing 22 changed files with 2,531 additions and 2,008 deletions.
30 changes: 12 additions & 18 deletions cypress/integration/App.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@ describe('Open aukiolot app', () => {
cy.get('[data-test=resource-info]', { timeout: 5000 }).should('be.visible');

cy.wait(1000); // Wait for HDS spinner cleanup.
cy.checkA11y(
{},
{
rules: {
'duplicate-id-aria': { enabled: false }, // TODO: HAUKI-185
'duplicate-id': { enabled: false },
},
}
);
cy.checkA11y(undefined, {
rules: {
'duplicate-id-aria': { enabled: false }, // TODO: HAUKI-185
'duplicate-id': { enabled: false },
},
});
});

it('Has no detectable a11y violations on add new opening period page', () => {
Expand All @@ -38,14 +35,11 @@ describe('Open aukiolot app', () => {
}).should('be.visible');

cy.wait(1000); // Wait for HDS spinner cleanup.
cy.checkA11y(
{},
{
rules: {
'duplicate-id-aria': { enabled: false }, // TODO: HAUKI-185
'duplicate-id': { enabled: false },
},
}
);
cy.checkA11y(undefined, {
rules: {
'duplicate-id-aria': { enabled: false }, // TODO: HAUKI-185
'duplicate-id': { enabled: false },
},
});
});
});
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
"date-holidays": "^3.16.1",
"enzyme": "^3.11.0",
"eslint-config-airbnb-typescript-prettier": "^5.0.0",
"hds-core": "^3.4.0",
"hds-design-tokens": "^3.4.0",
"hds-react": "^3.4.0",
"hds-core": "^3.5.0",
"hds-design-tokens": "^3.5.0",
"hds-react": "^3.5.0",
"i18next": "23.7.11",
"lodash": "^4.17.21",
"prettier": "^2.1.1",
Expand Down
8 changes: 7 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,13 @@ const App = (): JSX.Element => {
removeTokens();
}, [setAuthTokens]);

const [language, setLanguage] = useState(Language.FI);
const langStringFromUrl = searchParams?.lang as string;
const langFromUrl =
langStringFromUrl && langStringFromUrl.toUpperCase() in Language
? (langStringFromUrl.toLowerCase() as Language)
: Language.FI;

const [language, setLanguage] = useState(langFromUrl);
const appContextValue = useMemo(
() => ({
hasOpenerWindow,
Expand Down
15 changes: 8 additions & 7 deletions src/common/utils/date-time/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,37 @@
import { Language } from '../../lib/types';
import { formatDateRange, createWeekdaysStringFromIndices } from './format';

jest.clearAllMocks();
jest.mock('i18next', () => ({ t: (str: string) => str }));

describe('format', () => {
describe('formatDateRange', () => {
it('should return formatted date range', () => {
expect(
formatDateRange({ startDate: '18.12.2020', endDate: '31.12.2020' })
).toEqual('Voimassa 18.12.2020 - 31.12.2020');
).toEqual('ResourcePage.OpeningPeriodsSection.ValidBetweenDates');
});

it('should return formatted startDate when endDate is missing', () => {
expect(
formatDateRange({ startDate: '18.12.2020', endDate: null })
).toEqual('Voimassa 18.12.2020 alkaen');
).toEqual('ResourcePage.OpeningPeriodsSection.ValidFromDate');
});

it('should return formatted endDate when startDate is missing', () => {
expect(
formatDateRange({ startDate: null, endDate: '31.12.2020' })
).toEqual('Voimassa 31.12.2020 asti');
).toEqual('ResourcePage.OpeningPeriodsSection.ValidUntilDate');
});

it('should return valid under further notice when both endDate and startDate are missing', () => {
expect(formatDateRange({ startDate: null, endDate: null })).toEqual(
'Voimassa toistaiseksi'
'ResourcePage.OpeningPeriodsSection.ValidUntilFurtherNotice'
);
});

it('should return formatted start date when startDate is same as endDate', () => {
expect(
formatDateRange({ startDate: '31.12.2020', endDate: '31.12.2020' })
).toEqual('Voimassa 31.12.2020');
).toEqual('ResourcePage.OpeningPeriodsSection.ValidOnDate');
});
});

Expand Down
20 changes: 15 additions & 5 deletions src/common/utils/date-time/format.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import parse from 'date-fns/parse';
import format from 'date-fns/format';
import { getDay } from 'date-fns';
import { t as _t } from 'i18next';
import { Language, Weekdays, WeekdayTypes } from '../../lib/types';

export const dateApiFormat = 'yyyy-MM-dd';
Expand All @@ -23,22 +24,31 @@ export const formatDateRange = ({
endDate: string | null;
}): string => {
if (!startDate && !endDate) {
return 'Voimassa toistaiseksi';
return _t('ResourcePage.OpeningPeriodsSection.ValidUntilFurtherNotice');
}

if (startDate === endDate) {
return `Voimassa ${startDate}`;
return _t('ResourcePage.OpeningPeriodsSection.ValidOnDate', {
startDate,
});
}

if (!endDate) {
return `Voimassa ${startDate} alkaen`;
return _t('ResourcePage.OpeningPeriodsSection.ValidFromDate', {
startDate,
});
}

if (!startDate) {
return `Voimassa ${endDate} asti`;
return _t('ResourcePage.OpeningPeriodsSection.ValidUntilDate', {
endDate,
});
}

return `Voimassa ${startDate} - ${endDate}`;
return _t('ResourcePage.OpeningPeriodsSection.ValidBetweenDates', {
startDate,
endDate,
});
};

export const transformDateToApiFormat = (formDate: string): string =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const ExceptionOpeningHoursValidity = (): JSX.Element => {
openButtonAriaLabel="Valitse alkupäivämäärä"
required
value={value}
crossOrigin={undefined}
/>
)}
rules={{
Expand Down Expand Up @@ -91,6 +92,7 @@ const ExceptionOpeningHoursValidity = (): JSX.Element => {
openButtonAriaLabel="Valitse loppupäivämäärä"
required
value={value}
crossOrigin={undefined}
/>
)}
rules={{
Expand Down
71 changes: 42 additions & 29 deletions src/components/footer/HaukiFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
import React from 'react';
import { Footer, logoFi, Logo } from 'hds-react';
import { Footer, logoFi, logoSv, Logo } from 'hds-react';
import { useTranslation } from 'react-i18next';
import { useAppContext } from '../../App-context';
import './HaukiFooter.scss';

const HaukiFooter = (): JSX.Element => (
<>
<div className="footer-top-padding" />
<Footer
className="page-footer"
title="Aukiolot"
theme={{
'--footer-background': 'var(--hauki-footer-background-color)',
}}>
<Footer.Base
copyrightHolder="Helsingin Kaupunki"
copyrightText="Kaikki oikeudet pidätetään."
logo={<Logo src={logoFi} size="medium" alt="Helsingin kaupunki" />}
backToTopLabel="Takaisin ylös">
<Footer.Link
href="https://kaupunkialustana.hel.fi/aukiolosovelluksen-saavutettavuusseloste/"
target="_blank"
label="Saavutettavuusseloste"
/>
<Footer.Link
href="/content-license.txt"
target="_blank"
label="Sisältölisenssi CC BY 4.0"
/>
</Footer.Base>
</Footer>
</>
);
const HaukiFooter = (): JSX.Element => {
const { language } = useAppContext();
const { t } = useTranslation();

return (
<>
<div className="footer-top-padding" />
<Footer
className="page-footer"
title="Aukiolot"
theme={{
'--footer-background': 'var(--hauki-footer-background-color)',
}}>
<Footer.Base
copyrightHolder={t('Footer.CopyrightHolder')}
copyrightText={t('Footer.CopyrightText')}
logo={
<Logo
src={language === 'sv' ? logoSv : logoFi}
size="medium"
alt={t('Footer.LogoAlt')}
/>
}
backToTopLabel={t('Footer.BackToTopLabel')}>
<Footer.Link
href={t('Footer.AccessibilityStatementLinkUrl')}
target="_blank"
label={t('Footer.AccessibilityStatementLink')}
/>
<Footer.Link
href="/content-license.txt"
target="_blank"
label={t('Footer.ContentLicenseLink')}
/>
</Footer.Base>
</Footer>
</>
);
};

export default HaukiFooter;
2 changes: 2 additions & 0 deletions src/components/header/HaukiHeader.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
@import '~hds-design-tokens/lib/all.scss';

.header {
flex-shrink: 0;

--nav-link-font-color: var(--color-black-90) !important;

@media screen and (max-width: $breakpoint-l) {
Expand Down
4 changes: 3 additions & 1 deletion src/components/header/HaukiHeader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ describe('<HaukiHeader>', () => {

userEvent.click(authButton);

const closeButton = await screen.findByRole('link', { name: 'Sulje' });
const closeButton = await screen.findByRole('link', {
name: 'Header.Close',
});

userEvent.click(closeButton);

Expand Down
47 changes: 31 additions & 16 deletions src/components/header/HaukiHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
IconUser,
Header,
logoFiDark,
logoSvDark,
Logo,
Link,
} from 'hds-react';
Expand All @@ -19,9 +20,10 @@ import { Language } from '../../common/lib/types';
import { languageOptions } from '../../constants';

const HaukiHeader = (): JSX.Element => {
const { hasOpenerWindow, closeAppWindow, setLanguage } = useAppContext();
const { hasOpenerWindow, closeAppWindow, language, setLanguage } =
useAppContext();
const authProps: Partial<AuthContextProps> = useAuth();
const { i18n } = useTranslation();
const { i18n, t } = useTranslation();
const { authTokens, clearAuth } = authProps;
const history = useHistory();
const isAuthenticated = !!authTokens;
Expand All @@ -41,14 +43,12 @@ const HaukiHeader = (): JSX.Element => {
}
history.push('/');
} else {
showSignOutErrorNotification('Uloskirjautuminen hylättiin.');
showSignOutErrorNotification(t('Header.SignOutRejected'));
}
} catch (e) {
// eslint-disable-next-line no-console
console.error('Sign out failed:', (e as Error).message);
showSignOutErrorNotification(
`Uloskirjautuminen epäonnistui. Yritä myöhemmin uudestaan. Virhe: ${e}`
);
showSignOutErrorNotification(t('Header.SignOutFailed') + e);
}
};

Expand All @@ -72,42 +72,57 @@ const HaukiHeader = (): JSX.Element => {
}}
className="header"
languages={languageOptions}
onDidChangeLanguage={(language) => {
i18n.changeLanguage(language);
defaultLanguage={language}
onDidChangeLanguage={(lang) => {
i18n.changeLanguage(lang);
if (setLanguage) {
const newLanguage =
Language[language.toUpperCase() as keyof typeof Language];
Language[lang.toUpperCase() as keyof typeof Language];

setLanguage(newLanguage);

const urlSearchParams = new URLSearchParams(window.location.search);
urlSearchParams.set('lang', newLanguage);

history.push({
pathname: window.location.pathname,
search: urlSearchParams.toString(),
});
}
}}>
<Header.SkipLink skipTo="#main" label="Siirry pääsisältöön" />
<Header.SkipLink skipTo="#main" label={t('Header.SkipLink')} />
<Header.ActionBar
title="Aukiolot"
title={t('Header.Title')}
titleHref={`/resource/${id}`}
frontPageLabel="Etusivu"
menuButtonAriaLabel="Menu"
logo={<Logo src={logoFiDark} alt="Helsingin kaupunki" />}>
frontPageLabel={t('Header.FrontPage')}
menuButtonAriaLabel={t('Header.Menu')}
logo={
<Logo
src={language === 'sv' ? logoSvDark : logoFiDark}
alt={t('Header.LogoAlt')}
/>
}>
<Header.LanguageSelector />
{isAuthenticated && (
<Header.ActionBarItem
fixedRightPosition
id="action-bar-user"
label={authTokens?.[TokenKeys.usernameKey]}
closeLabel={t('Header.Close')}
icon={<IconUser aria-hidden />}>
<Link
className="closeLink"
data-testid="close-app-button"
href="#"
onClick={onCloseButtonClick}>
<IconCrossCircleFill aria-hidden /> Sulje
<IconCrossCircleFill aria-hidden /> {t('Header.Close')}
</Link>
</Header.ActionBarItem>
)}
</Header.ActionBar>
<Header.NavigationMenu>
<Header.Link
label="Ohje"
label={t('Header.Help')}
href="https://kaupunkialustana.hel.fi/aukiolosovellus-ohje/"
target="_blank"
rel="noreferrer"
Expand Down
4 changes: 4 additions & 0 deletions src/components/holidays-table/HolidaysTable.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@
text-align: right;
}

.holidays-table-checkbox {
width: $spacing-m;
}

@media screen and (min-width: $breakpoint-m) {
.holidays-table__cell--date {
text-align: left;
Expand Down
1 change: 1 addition & 0 deletions src/components/holidays-table/HolidaysTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ const HolidaysTable = ({
onChange={() => {
toggleChecked(holidayDatePeriod);
}}
className="holidays-table-checkbox"
/>
)}
{datePeriodSelectState === DatePeriodSelectState.ACTIVE ? (
Expand Down
Loading

0 comments on commit fe1e1f7

Please sign in to comment.