richie-education 2.33.1-dev1 → 2.33.1-dev10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/jest/setup.ts +7 -0
  2. package/js/api/lms/joanie.ts +1 -1
  3. package/js/components/AddressesManagement/AddressForm/index.spec.tsx +1 -1
  4. package/js/components/AddressesManagement/index.spec.tsx +1 -1
  5. package/js/components/ContractFrame/AbstractContractFrame.spec.tsx +2 -2
  6. package/js/components/CourseGlimpse/CourseLink.tsx +1 -1
  7. package/js/components/CourseGlimpse/index.spec.tsx +1 -1
  8. package/js/components/CourseGlimpse/utils.ts +1 -1
  9. package/js/components/ProtectedRoute/index.spec.tsx +1 -1
  10. package/js/components/ProtectedRoute/index.tsx +1 -1
  11. package/js/components/SaleTunnel/AddressSelector/index.spec.tsx +2 -2
  12. package/js/components/SaleTunnel/SaleTunnelSuccess/index.tsx +1 -1
  13. package/js/components/SaleTunnel/index.full-process.spec.tsx +1 -1
  14. package/js/components/SignContractButton/index.omniscientOrders.spec.tsx +1 -1
  15. package/js/components/SignContractButton/index.spec.tsx +1 -1
  16. package/js/components/SignContractButton/index.tsx +1 -1
  17. package/js/components/Tabs/index.tsx +1 -1
  18. package/js/hooks/useCourseProductUnion/index.spec.tsx +1 -1
  19. package/js/hooks/useDefaultOrganizationId/index.tsx +1 -1
  20. package/js/hooks/useLearnerCoursesSearch/index.tsx +1 -1
  21. package/js/hooks/useTeacherCoursesSearch/index.tsx +1 -1
  22. package/js/pages/DashboardAddressesManagement/DashboardCreateAddress.spec.tsx +2 -2
  23. package/js/pages/DashboardAddressesManagement/DashboardEditAddressLoader.tsx +1 -1
  24. package/js/pages/DashboardCourses/index.spec.tsx +1 -1
  25. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCard.spec.tsx +3 -3
  26. package/js/pages/DashboardCreditCardsManagement/DashboardEditCreditCardLoader.tsx +1 -1
  27. package/js/pages/DashboardOrderLayout/index.tsx +1 -1
  28. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.tsx +1 -1
  29. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.spec.tsx +1 -1
  30. package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.tsx +1 -1
  31. package/js/pages/TeacherDashboardCourseLearnersLayout/hooks/useCourseLearnersFilters/index.ts +1 -1
  32. package/js/pages/TeacherDashboardCourseLearnersLayout/index.tsx +1 -1
  33. package/js/pages/TeacherDashboardCourseLoader/CourseRunList/index.spec.tsx +1 -1
  34. package/js/pages/TeacherDashboardCourseLoader/CourseRunList/utils.spec.tsx +1 -1
  35. package/js/pages/TeacherDashboardCourseLoader/index.tsx +1 -1
  36. package/js/pages/TeacherDashboardOrganizationCourseLoader/index.tsx +1 -1
  37. package/js/pages/TeacherDashboardTraining/TeacherDashboardTrainingLoader.tsx +1 -1
  38. package/js/pages/TeacherDashboardTraining/index.spec.tsx +1 -1
  39. package/js/utils/test/LocationDisplay.tsx +1 -1
  40. package/js/utils/test/render.tsx +1 -1
  41. package/js/utils/test/wrappers/RouterWrapper.tsx +1 -1
  42. package/js/widgets/Dashboard/components/DashboardBreadcrumbs/index.stories.tsx +1 -1
  43. package/js/widgets/Dashboard/components/DashboardBreadcrumbs/index.tsx +1 -1
  44. package/js/widgets/Dashboard/components/DashboardItem/CourseEnrolling/index.stories.tsx +1 -1
  45. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +1 -1
  46. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderReadonly.stories.tsx +1 -1
  47. package/js/widgets/Dashboard/components/DashboardLayout/index.tsx +1 -1
  48. package/js/widgets/Dashboard/components/DashboardLayoutRoute/index.tsx +1 -1
  49. package/js/widgets/Dashboard/components/DashboardOrderLoader/index.tsx +1 -1
  50. package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.tsx +1 -1
  51. package/js/widgets/Dashboard/components/DashboardSidebar/components/MenuNavLink/index.tsx +1 -1
  52. package/js/widgets/Dashboard/components/DashboardSidebar/components/NavigationSelect.tsx +1 -1
  53. package/js/widgets/Dashboard/components/DashboardSidebar/index.stories.tsx +1 -1
  54. package/js/widgets/Dashboard/components/DashboardSidebar/utils.ts +1 -1
  55. package/js/widgets/Dashboard/components/DashboardTest/index.tsx +1 -1
  56. package/js/widgets/Dashboard/components/LearnerDashboardSidebar/index.stories.tsx +1 -1
  57. package/js/widgets/Dashboard/components/LearnerDashboardSidebar/index.tsx +1 -1
  58. package/js/widgets/Dashboard/components/NavigateWithParams/index.spec.tsx +1 -1
  59. package/js/widgets/Dashboard/components/NavigateWithParams/index.tsx +1 -1
  60. package/js/widgets/Dashboard/components/ProtectedOutlet/ProtectedOutlet.tsx +1 -1
  61. package/js/widgets/Dashboard/components/RouterButton/index.spec.tsx +1 -1
  62. package/js/widgets/Dashboard/components/RouterButton/index.tsx +1 -1
  63. package/js/widgets/Dashboard/components/SearchBar/index.tsx +1 -1
  64. package/js/widgets/Dashboard/components/SearchResultsCount/index.tsx +1 -1
  65. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.spec.tsx +1 -1
  66. package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.tsx +1 -1
  67. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.stories.tsx +1 -1
  68. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.tsx +1 -1
  69. package/js/widgets/Dashboard/components/TeacherDashboardProfileSidebar/components/OrganizationLinks/index.tsx +1 -1
  70. package/js/widgets/Dashboard/components/TeacherDashboardProfileSidebar/index.stories.tsx +1 -1
  71. package/js/widgets/Dashboard/components/TeacherDashboardProfileSidebar/index.tsx +1 -1
  72. package/js/widgets/Dashboard/hooks/useDashboardRouter/index.tsx +1 -1
  73. package/js/widgets/Dashboard/hooks/useRouteInfo/index.ts +1 -1
  74. package/js/widgets/Dashboard/index.tsx +1 -1
  75. package/js/widgets/Dashboard/utils/dashboardRoutes.tsx +1 -1
  76. package/js/widgets/Dashboard/utils/learnerRoutes.tsx +1 -1
  77. package/js/widgets/Dashboard/utils/teacherRoutes.tsx +1 -1
  78. package/js/widgets/SyllabusCourseRunsList/components/CourseRunItemWithEnrollment/index.tsx +1 -1
  79. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.tsx +16 -1
  80. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRunCompacted/index.tsx +16 -1
  81. package/package.json +39 -39
  82. package/scss/components/_header.scss +7 -1
  83. package/webpack.config.js +10 -1
package/jest/setup.ts CHANGED
@@ -8,6 +8,13 @@ import { FactoryConfig } from 'utils/test/factories/factories';
8
8
  global.Request = Request as any;
9
9
  global.Response = Response as any;
10
10
 
11
+ // https://github.com/remix-run/react-router/issues/12363#issuecomment-2496226528
12
+ if (!globalThis.TextEncoder || !globalThis.TextDecoder) {
13
+ const { TextDecoder, TextEncoder } = require('node:util');
14
+ globalThis.TextEncoder = TextEncoder;
15
+ globalThis.TextDecoder = TextDecoder;
16
+ }
17
+
11
18
  /*
12
19
  * A little trick to prevent so package to be reset when using `jest.resetModules()`.
13
20
  * https://github.com/facebook/jest/issues/8987#issuecomment-584898030
@@ -1,4 +1,4 @@
1
- import { matchPath, PathMatch } from 'react-router-dom';
1
+ import { matchPath, PathMatch } from 'react-router';
2
2
  import JoanieApi from 'api/joanie';
3
3
  import { LMSBackend } from 'types/commonDataProps';
4
4
  import { APIBackend, APILms } from 'types/api';
@@ -153,5 +153,5 @@ describe('AddressForm', () => {
153
153
  expect(
154
154
  getByText($countryInput.closest('.c__field')!, /This field is required./),
155
155
  ).toBeInTheDocument();
156
- });
156
+ }, 15000);
157
157
  });
@@ -177,7 +177,7 @@ describe('AddressesManagement', () => {
177
177
  ...address,
178
178
  is_main: true,
179
179
  });
180
- }, 10000);
180
+ }, 15000);
181
181
 
182
182
  it('renders a form to edit an address when user selects an address to edit', async () => {
183
183
  const address = AddressFactory().one();
@@ -169,7 +169,7 @@ describe('<AbstractContractFrame />', () => {
169
169
  await user.click(button);
170
170
 
171
171
  expect(mockOnClose).toHaveBeenCalledTimes(1);
172
- });
172
+ }, 25000);
173
173
 
174
174
  it('retrieves invitation link but fails during signature checking', async () => {
175
175
  const user = userEvent.setup();
@@ -231,7 +231,7 @@ describe('<AbstractContractFrame />', () => {
231
231
  await user.click(button);
232
232
 
233
233
  expect(mockOnClose).toHaveBeenCalledTimes(1);
234
- });
234
+ }, 25000);
235
235
 
236
236
  it('retrieves invitation link but exceeds polling max attemps', async () => {
237
237
  const user = userEvent.setup();
@@ -1,4 +1,4 @@
1
- import { Link } from 'react-router-dom';
1
+ import { Link } from 'react-router';
2
2
  import { FunctionComponent, ReactElement } from 'react';
3
3
 
4
4
  interface CourseLinkProps {
@@ -1,6 +1,6 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import { IntlProvider } from 'react-intl';
3
- import { MemoryRouter } from 'react-router-dom';
3
+ import { MemoryRouter } from 'react-router';
4
4
  import { CommonDataProps } from 'types/commonDataProps';
5
5
  import { RichieContextFactory } from 'utils/test/factories/richie';
6
6
  import { CourseStateTextEnum } from 'types';
@@ -1,5 +1,5 @@
1
1
  import { IntlShape } from 'react-intl';
2
- import { generatePath } from 'react-router-dom';
2
+ import { generatePath } from 'react-router';
3
3
  import { Course as RichieCourse, isRichieCourse } from 'types/Course';
4
4
  import {
5
5
  CourseListItem as JoanieCourse,
@@ -1,6 +1,6 @@
1
1
  import { screen } from '@testing-library/dom';
2
2
  import userEvent from '@testing-library/user-event';
3
- import { Link, RouteObject } from 'react-router-dom';
3
+ import { Link, RouteObject } from 'react-router';
4
4
  import { render } from 'utils/test/render';
5
5
  import { RouterWrapper } from 'utils/test/wrappers/RouterWrapper';
6
6
  import ProtectedRoute from '.';
@@ -1,4 +1,4 @@
1
- import { Navigate, Outlet } from 'react-router-dom';
1
+ import { Navigate, Outlet } from 'react-router';
2
2
 
3
3
  interface ProtectedRouteProps {
4
4
  isAllowed: boolean;
@@ -133,7 +133,7 @@ describe('AddressSelector', () => {
133
133
  'Billing address' + getAddressLabel(address) + 'closearrow_drop_down',
134
134
  );
135
135
  });
136
- });
136
+ }, 15000);
137
137
  it('has an existing main billing address and choose another', async () => {
138
138
  const address = AddressFactory({
139
139
  is_main: true,
@@ -268,5 +268,5 @@ describe('AddressSelector', () => {
268
268
  'Billing address' + getAddressLabel(newAddress) + 'closearrow_drop_down',
269
269
  ),
270
270
  );
271
- });
271
+ }, 15000);
272
272
  });
@@ -1,6 +1,6 @@
1
1
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
2
2
  import { Button } from '@openfun/cunningham-react';
3
- import { generatePath } from 'react-router-dom';
3
+ import { generatePath } from 'react-router';
4
4
  import { SuccessIcon } from 'components/SuccessIcon';
5
5
  import { getDashboardBasename } from 'widgets/Dashboard/hooks/useDashboardRouter/getDashboardBasename';
6
6
  import { useSaleTunnelContext } from 'components/SaleTunnel/GenericSaleTunnel';
@@ -381,5 +381,5 @@ describe('SaleTunnel', () => {
381
381
  // This way we make sure the cache is updated.
382
382
  await screen.findByText('Purchased');
383
383
  expect(screen.queryByRole('button', { name: product.call_to_action })).not.toBeInTheDocument();
384
- }, 10000);
384
+ }, 15000);
385
385
  });
@@ -1,7 +1,7 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { render, screen, within } from '@testing-library/react';
3
3
  import { IntlProvider } from 'react-intl';
4
- import { MemoryRouter } from 'react-router-dom';
4
+ import { MemoryRouter } from 'react-router';
5
5
  import userEvent from '@testing-library/user-event';
6
6
  import { QueryClientProvider } from '@tanstack/react-query';
7
7
  import fetchMock from 'fetch-mock';
@@ -1,7 +1,7 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { IntlProvider } from 'react-intl';
4
- import { MemoryRouter } from 'react-router-dom';
4
+ import { MemoryRouter } from 'react-router';
5
5
  import userEvent from '@testing-library/user-event';
6
6
  import { QueryClientProvider } from '@tanstack/react-query';
7
7
  import { faker } from '@faker-js/faker';
@@ -1,7 +1,7 @@
1
1
  import { Button } from '@openfun/cunningham-react';
2
2
  import { FormattedMessage, defineMessages } from 'react-intl';
3
3
  import { useState } from 'react';
4
- import { generatePath } from 'react-router-dom';
4
+ import { generatePath } from 'react-router';
5
5
  import { LearnerContractFrame } from 'components/ContractFrame';
6
6
  import {
7
7
  Contract,
@@ -9,7 +9,7 @@ import {
9
9
  cloneElement,
10
10
  useState,
11
11
  } from 'react';
12
- import { useNavigate } from 'react-router-dom';
12
+ import { useNavigate } from 'react-router';
13
13
  import { noop } from 'utils';
14
14
 
15
15
  interface TabProps extends PropsWithChildren {
@@ -82,7 +82,7 @@ describe('useCourseProductUnion', () => {
82
82
  `${coursesUrl}?has_listed_course_runs=true&page=1&page_size=${PER_PAGE}`,
83
83
  );
84
84
  expect(calledUrls).toContain(`${courseProductRelationsUrl}?page=1&page_size=${PER_PAGE}`);
85
- });
85
+ }, 25000);
86
86
 
87
87
  it('should call organization courses and organization coursesProductRelation endpoints', async () => {
88
88
  const organizationId = 'DUMMY_ORGANIZATION_ID';
@@ -1,4 +1,4 @@
1
- import { useParams, useSearchParams } from 'react-router-dom';
1
+ import { useParams, useSearchParams } from 'react-router';
2
2
  import { useOrganizations } from 'hooks/useOrganizations';
3
3
  import { CourseProductRelation, Organization } from 'types/Joanie';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState } from 'react';
2
- import { useSearchParams } from 'react-router-dom';
2
+ import { useSearchParams } from 'react-router';
3
3
  import { Enrollment, CredentialOrder, OrderState, ProductType } from 'types/Joanie';
4
4
  import { Maybe, Nullable } from 'types/utils';
5
5
  import { useOrdersEnrollments } from 'pages/DashboardCourses/useOrdersEnrollments';
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useState } from 'react';
2
- import { useParams, useSearchParams } from 'react-router-dom';
2
+ import { useParams, useSearchParams } from 'react-router';
3
3
  import { useCourseProductUnion } from 'hooks/useCourseProductUnion';
4
4
  import { CourseListItem, CourseProductRelationLight, ProductType } from 'types/Joanie';
5
5
  import { Maybe, Nullable } from 'types/utils';
@@ -170,7 +170,7 @@ describe('<DashboardCreateAddress/>', () => {
170
170
  await waitFor(() => {
171
171
  expect(screen.getByText('Billing addresses')).toBeInTheDocument();
172
172
  });
173
- });
173
+ }, 15000);
174
174
 
175
175
  it('shows an error in case of API error', async () => {
176
176
  fetchMock.get('https://joanie.endpoint/api/v1.0/addresses/', []);
@@ -210,5 +210,5 @@ describe('<DashboardCreateAddress/>', () => {
210
210
  ).toBe(true);
211
211
 
212
212
  await expectBannerError('An error occurred while creating the address. Please retry later.');
213
- });
213
+ }, 15000);
214
214
  });
@@ -1,4 +1,4 @@
1
- import { useParams } from 'react-router-dom';
1
+ import { useParams } from 'react-router';
2
2
  import Banner, { BannerType } from 'components/Banner';
3
3
  import { Spinner } from 'components/Spinner';
4
4
  import { useAddress } from 'hooks/useAddresses';
@@ -231,7 +231,7 @@ describe('<DashboardCourses/>', () => {
231
231
  await waitFor(() => expectList(entities.slice(0, perPage * 3), relations), { timeout: 30000 });
232
232
  loadMoreButton = await screen.findByRole('button', { name: 'Load more' });
233
233
  expect(loadMoreButton).toBeEnabled();
234
- });
234
+ }, 15000);
235
235
 
236
236
  it('shows an error', async () => {
237
237
  jest.spyOn(console, 'error').mockImplementation(noop);
@@ -1,7 +1,7 @@
1
1
  import { getByText, queryByText, screen, waitFor } from '@testing-library/react';
2
2
  import fetchMock from 'fetch-mock';
3
3
  import userEvent from '@testing-library/user-event';
4
- import { Outlet, generatePath } from 'react-router-dom';
4
+ import { Outlet, generatePath } from 'react-router';
5
5
  import {
6
6
  UserFactory,
7
7
  RichieContextFactory as mockRichieContextFactory,
@@ -267,7 +267,7 @@ describe('<DahsboardEditCreditCard/>', () => {
267
267
  );
268
268
 
269
269
  // Redirected to the list route.
270
- screen.getByText('Credit cards');
270
+ await screen.findByText('Credit cards');
271
271
  const creditCardsContainers = await screen.findAllByTestId(/dashboard-credit-card__/);
272
272
  expect(creditCardsContainers.length).toEqual(6);
273
273
 
@@ -333,7 +333,7 @@ describe('<DahsboardEditCreditCard/>', () => {
333
333
  expect(screen.queryByText('An error occurred', { exact: false })).toBeNull();
334
334
 
335
335
  // Redirected to the list route.
336
- screen.getByText('Credit cards');
336
+ await screen.findByText('Credit cards');
337
337
 
338
338
  await waitFor(() => {
339
339
  // Assert that other credit cards appear in the list.
@@ -1,4 +1,4 @@
1
- import { useParams } from 'react-router-dom';
1
+ import { useParams } from 'react-router';
2
2
  import { useDashboardNavigate } from 'widgets/Dashboard/hooks/useDashboardRouter';
3
3
  import { useCreditCard } from 'hooks/useCreditCards';
4
4
  import { Spinner } from 'components/Spinner';
@@ -1,4 +1,4 @@
1
- import { generatePath, Outlet, useParams } from 'react-router-dom';
1
+ import { generatePath, Outlet, useParams } from 'react-router';
2
2
  import { useIntl } from 'react-intl';
3
3
  import { useMemo } from 'react';
4
4
  import { getDashboardRouteLabel } from 'widgets/Dashboard/utils/dashboardRoutes';
@@ -2,7 +2,7 @@ import { defineMessages, useIntl } from 'react-intl';
2
2
 
3
3
  import { DataGrid, usePagination } from '@openfun/cunningham-react';
4
4
  import { useEffect, useMemo } from 'react';
5
- import { useParams, useSearchParams } from 'react-router-dom';
5
+ import { useParams, useSearchParams } from 'react-router';
6
6
  import { ContractHelper, ContractStatePoV } from 'utils/ContractHelper';
7
7
  import { useOrganizationContracts } from 'hooks/useContracts';
8
8
  import Banner, { BannerType } from 'components/Banner';
@@ -3,7 +3,7 @@ import { PropsWithChildren } from 'react';
3
3
  import { IntlProvider } from 'react-intl';
4
4
  import { QueryClientProvider } from '@tanstack/react-query';
5
5
  import { renderHook, waitFor, act } from '@testing-library/react';
6
- import { MemoryRouter, Route, Routes } from 'react-router-dom';
6
+ import { MemoryRouter, Route, Routes } from 'react-router';
7
7
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
8
8
  import { createTestQueryClient } from 'utils/test/createTestQueryClient';
9
9
  import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo, useState } from 'react';
2
- import { useParams, useSearchParams } from 'react-router-dom';
2
+ import { useParams, useSearchParams } from 'react-router';
3
3
  import useDefaultOrganizationId from 'hooks/useDefaultOrganizationId';
4
4
  import { ContractResourceQuery, ContractState } from 'types/Joanie';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { useEffect, useMemo, useState } from 'react';
2
- import { useParams, useSearchParams } from 'react-router-dom';
2
+ import { useParams, useSearchParams } from 'react-router';
3
3
  import useDefaultOrganizationId from 'hooks/useDefaultOrganizationId';
4
4
  import {
5
5
  CourseListItem,
@@ -1,6 +1,6 @@
1
1
  import { FormattedMessage, defineMessages } from 'react-intl';
2
2
 
3
- import { useParams, useSearchParams } from 'react-router-dom';
3
+ import { useParams, useSearchParams } from 'react-router';
4
4
  import { SortModel, usePagination } from '@openfun/cunningham-react';
5
5
  import { useEffect, useMemo, useState } from 'react';
6
6
  import { TeacherDashboardCourseSidebar } from 'widgets/Dashboard/components/TeacherDashboardCourseSidebar';
@@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
2
2
  import { IntlProvider } from 'react-intl';
3
3
  import { CunninghamProvider } from '@openfun/cunningham-react';
4
4
  import { capitalize } from 'lodash-es';
5
- import { MemoryRouter } from 'react-router-dom';
5
+ import { MemoryRouter } from 'react-router';
6
6
  import { CourseRunFactory } from 'utils/test/factories/joanie';
7
7
  import CourseRunList from '.';
8
8
 
@@ -1,7 +1,7 @@
1
1
  import { IntlProvider, createIntl } from 'react-intl';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { capitalize } from 'lodash-es';
4
- import { MemoryRouter } from 'react-router-dom';
4
+ import { MemoryRouter } from 'react-router';
5
5
  import { CourseRunFactory } from 'utils/test/factories/joanie';
6
6
  import { buildCourseRunData, messages } from './utils';
7
7
 
@@ -1,5 +1,5 @@
1
1
  import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
2
- import { useParams } from 'react-router-dom';
2
+ import { useParams } from 'react-router';
3
3
 
4
4
  import { capitalize } from 'lodash-es';
5
5
  import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
@@ -1,5 +1,5 @@
1
1
  import { defineMessages, FormattedMessage } from 'react-intl';
2
- import { useParams } from 'react-router-dom';
2
+ import { useParams } from 'react-router';
3
3
  import { Spinner } from 'components/Spinner';
4
4
  import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
5
5
  import { TeacherDashboardOrganizationSidebar } from 'widgets/Dashboard/components/TeacherDashboardOrganizationSidebar';
@@ -1,5 +1,5 @@
1
1
  import { FormattedMessage, defineMessages } from 'react-intl';
2
- import { useParams } from 'react-router-dom';
2
+ import { useParams } from 'react-router';
3
3
 
4
4
  import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
5
5
  import { TeacherDashboardCourseSidebar } from 'widgets/Dashboard/components/TeacherDashboardCourseSidebar';
@@ -1,4 +1,4 @@
1
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
1
+ import { createMemoryRouter, RouterProvider } from 'react-router';
2
2
  import { QueryClientProvider } from '@tanstack/react-query';
3
3
  import { render, screen } from '@testing-library/react';
4
4
  import fetchMock from 'fetch-mock';
@@ -1,4 +1,4 @@
1
- import { useLocation } from 'react-router-dom';
1
+ import { useLocation } from 'react-router';
2
2
 
3
3
  const LocationDisplay = () => {
4
4
  const location = useLocation();
@@ -27,7 +27,7 @@ type RenderFunction = (
27
27
  * the same contexts.
28
28
  *
29
29
  * The provided {@param element} is to be wrapped in :
30
- * - react router (react-router-dom)
30
+ * - react router (react-router)
31
31
  * - react i18n context (react-intl)
32
32
  * - query context (react-query)
33
33
  *
@@ -1,5 +1,5 @@
1
1
  import { PropsWithChildren } from 'react';
2
- import { RouteObject, RouterProvider, createMemoryRouter } from 'react-router-dom';
2
+ import { RouteObject, RouterProvider, createMemoryRouter } from 'react-router';
3
3
  import { Maybe } from 'types/utils';
4
4
 
5
5
  export interface RouterWrapperProps extends PropsWithChildren {
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, Outlet, RouteObject, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, Outlet, RouteObject, RouterProvider } from 'react-router';
3
3
  import { defineMessages } from 'react-intl';
4
4
  import { DashboardBreadcrumbsProvider } from 'widgets/Dashboard/contexts/DashboardBreadcrumbsContext';
5
5
  import { useBreadcrumbsPlaceholders } from 'hooks/useBreadcrumbsPlaceholders';
@@ -1,5 +1,5 @@
1
1
  import { useContext, useMemo } from 'react';
2
- import { useMatches } from 'react-router-dom';
2
+ import { useMatches } from 'react-router';
3
3
  import { defineMessages, FormattedMessage, MessageDescriptor, useIntl } from 'react-intl';
4
4
  import { IntlHelper } from 'utils/IntlHelper';
5
5
  import { DashboardBreadcrumbsContext } from 'widgets/Dashboard/contexts/DashboardBreadcrumbsContext';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, RouterProvider } from 'react-router';
3
3
  import { faker } from '@faker-js/faker';
4
4
  import { TargetCourseFactory } from 'utils/test/factories/joanie';
5
5
  import { StorybookHelper } from 'utils/StorybookHelper';
@@ -1,5 +1,5 @@
1
1
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
2
- import { generatePath } from 'react-router-dom';
2
+ import { generatePath } from 'react-router';
3
3
  import { CredentialOrder, OrderState } from 'types/Joanie';
4
4
  import { Icon, IconTypeEnum } from 'components/Icon';
5
5
  import { CoursesHelper } from 'utils/CoursesHelper';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, RouterProvider } from 'react-router';
3
3
  import { CredentialOrder, OrderState, Product, TargetCourse } from 'types/Joanie';
4
4
  import {
5
5
  CredentialOrderFactory,
@@ -1,5 +1,5 @@
1
1
  import { PropsWithChildren, ReactNode } from 'react';
2
- import { useLocation } from 'react-router-dom';
2
+ import { useLocation } from 'react-router';
3
3
  import c from 'classnames';
4
4
  import { LearnerDashboardSidebar } from 'widgets/Dashboard/components/LearnerDashboardSidebar';
5
5
  import { DashboardBreadcrumbs } from 'widgets/Dashboard/components/DashboardBreadcrumbs';
@@ -1,4 +1,4 @@
1
- import { Outlet, useMatches } from 'react-router-dom';
1
+ import { Outlet, useMatches } from 'react-router';
2
2
  import { DashboardRouteHandle } from 'widgets/Dashboard/hooks/useDashboardRouter';
3
3
  import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
4
4
  import { DashboardBreadcrumbsProvider } from 'widgets/Dashboard/contexts/DashboardBreadcrumbsContext';
@@ -1,4 +1,4 @@
1
- import { useParams } from 'react-router-dom';
1
+ import { useParams } from 'react-router';
2
2
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
3
3
  import { useMemo } from 'react';
4
4
  import { useOmniscientOrder } from 'hooks/useOrders';
@@ -1,4 +1,4 @@
1
- import { createSearchParams } from 'react-router-dom';
1
+ import { createSearchParams } from 'react-router';
2
2
  import { useMemo } from 'react';
3
3
  import { MenuLink } from 'widgets/Dashboard/components/DashboardSidebar';
4
4
  import { ContractState, CourseProductRelation, Organization } from 'types/Joanie';
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import { NavLink, useLocation } from 'react-router-dom';
2
+ import { NavLink, useLocation } from 'react-router';
3
3
  import Badge from 'components/Badge';
4
4
  import { MenuLink } from '../..';
5
5
  import { isMenuLinkActive } from '../../utils';
@@ -1,7 +1,7 @@
1
1
  import { Select, SelectHandle } from '@openfun/cunningham-react';
2
2
  import { useMemo, useRef } from 'react';
3
3
  import { defineMessages, useIntl } from 'react-intl';
4
- import { matchPath, useLocation, useNavigate } from 'react-router-dom';
4
+ import { matchPath, useLocation, useNavigate } from 'react-router';
5
5
  import { MenuLink } from 'widgets/Dashboard/components/DashboardSidebar';
6
6
 
7
7
  const messages = defineMessages({
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, RouterProvider } from 'react-router';
3
3
  import { UserFactory } from 'utils/test/factories/richie';
4
4
  import { StorybookHelper } from 'utils/StorybookHelper';
5
5
  import MenuNavLink from './components/MenuNavLink';
@@ -1,4 +1,4 @@
1
- import { Location, matchPath, resolvePath } from 'react-router-dom';
1
+ import { Location, matchPath, resolvePath } from 'react-router';
2
2
 
3
3
  export const isMenuLinkActive = (to: string, location: Location) => {
4
4
  const path = resolvePath(to).pathname;
@@ -1,4 +1,4 @@
1
- import { createMemoryRouter } from 'react-router-dom';
1
+ import { createMemoryRouter } from 'react-router';
2
2
  import Dashboard from 'widgets/Dashboard';
3
3
  import { getDashboardRoutes } from 'widgets/Dashboard/utils/dashboardRoutes';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, RouterProvider } from 'react-router';
3
3
  import { UserFactory } from 'utils/test/factories/richie';
4
4
  import { LearnerDashboardSidebar } from 'widgets/Dashboard/components/LearnerDashboardSidebar';
5
5
  import { StorybookHelper } from 'utils/StorybookHelper';
@@ -1,6 +1,6 @@
1
1
  import { defineMessages, useIntl } from 'react-intl';
2
2
  import { useMemo } from 'react';
3
- import { generatePath } from 'react-router-dom';
3
+ import { generatePath } from 'react-router';
4
4
  import { getDashboardRouteLabel } from 'widgets/Dashboard/utils/dashboardRoutes';
5
5
  import {
6
6
  DashboardSidebar,
@@ -1,5 +1,5 @@
1
1
  import { screen } from '@testing-library/react';
2
- import { Outlet } from 'react-router-dom';
2
+ import { Outlet } from 'react-router';
3
3
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
4
4
  import LocationDisplay from 'utils/test/LocationDisplay';
5
5
  import { render } from 'utils/test/render';
@@ -1,4 +1,4 @@
1
- import { generatePath, Navigate, NavigateProps, useParams } from 'react-router-dom';
1
+ import { generatePath, Navigate, NavigateProps, useParams } from 'react-router';
2
2
 
3
3
  interface NavigateWithParamsProps extends NavigateProps {
4
4
  to: string;
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from 'react';
2
- import { Outlet } from 'react-router-dom';
2
+ import { Outlet } from 'react-router';
3
3
  import { location } from 'utils/indirection/window';
4
4
 
5
5
  export interface ProtectedOutletProps {
@@ -1,4 +1,4 @@
1
- import { RouteObject } from 'react-router-dom';
1
+ import { RouteObject } from 'react-router';
2
2
  import { act, fireEvent, screen } from '@testing-library/react';
3
3
  import { location } from 'utils/indirection/window';
4
4
  import { render } from 'utils/test/render';
@@ -1,5 +1,5 @@
1
1
  import { MouseEvent, useRef } from 'react';
2
- import { useHref, useNavigate } from 'react-router-dom';
2
+ import { useHref, useNavigate } from 'react-router';
3
3
  import { Button, ButtonProps } from '@openfun/cunningham-react';
4
4
  import { location } from 'utils/indirection/window';
5
5
  import isTestEnv from 'utils/test/isTestEnv';
@@ -1,7 +1,7 @@
1
1
  import { Button, Input } from '@openfun/cunningham-react';
2
2
  import { MouseEvent, PropsWithChildren, useRef, useState } from 'react';
3
3
  import { defineMessages, useIntl } from 'react-intl';
4
- import { useSearchParams } from 'react-router-dom';
4
+ import { useSearchParams } from 'react-router';
5
5
  import { Nullable } from 'types/utils';
6
6
 
7
7
  const messages = defineMessages({
@@ -1,6 +1,6 @@
1
1
  import classNames from 'classnames';
2
2
  import { FormattedMessage, defineMessages } from 'react-intl';
3
- import { useSearchParams } from 'react-router-dom';
3
+ import { useSearchParams } from 'react-router';
4
4
 
5
5
  const messages = defineMessages({
6
6
  searchCountText: {
@@ -1,7 +1,7 @@
1
1
  import fetchMock from 'fetch-mock';
2
2
  import { screen } from '@testing-library/react';
3
3
  import { createIntl } from 'react-intl';
4
- import { generatePath } from 'react-router-dom';
4
+ import { generatePath } from 'react-router';
5
5
  import { CourseListItem } from 'types/Joanie';
6
6
  import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
7
7
  import {
@@ -1,5 +1,5 @@
1
1
  import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
2
- import { generatePath, useParams } from 'react-router-dom';
2
+ import { generatePath, useParams } from 'react-router';
3
3
  import { useMemo } from 'react';
4
4
  import { capitalize } from 'lodash-es';
5
5
  import { DashboardSidebar, MenuLink } from 'widgets/Dashboard/components/DashboardSidebar';
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, RouterProvider } from 'react-router';
3
3
  import fetchMock from 'fetch-mock';
4
4
  import { UserFactory } from 'utils/test/factories/richie';
5
5
  import { TeacherDashboardOrganizationSidebar } from 'widgets/Dashboard/components/TeacherDashboardOrganizationSidebar';
@@ -1,5 +1,5 @@
1
1
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
2
- import { generatePath, useParams } from 'react-router-dom';
2
+ import { generatePath, useParams } from 'react-router';
3
3
  import { Spinner } from 'components/Spinner';
4
4
  import { useOrganization } from 'hooks/useOrganizations';
5
5
  import { DashboardSidebar, MenuLink } from 'widgets/Dashboard/components/DashboardSidebar';
@@ -1,5 +1,5 @@
1
1
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
2
- import { generatePath, Link } from 'react-router-dom';
2
+ import { generatePath, Link } from 'react-router';
3
3
  import { Organization } from 'types/Joanie';
4
4
  import { StringHelper } from 'utils/StringHelper';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
2
+ import { createMemoryRouter, RouterProvider } from 'react-router';
3
3
  import { UserFactory } from 'utils/test/factories/richie';
4
4
  import { TeacherDashboardProfileSidebar } from 'widgets/Dashboard/components/TeacherDashboardProfileSidebar';
5
5
  import { StorybookHelper } from 'utils/StorybookHelper';
@@ -1,6 +1,6 @@
1
1
  import { defineMessages, useIntl } from 'react-intl';
2
2
  import { useMemo } from 'react';
3
- import { generatePath } from 'react-router-dom';
3
+ import { generatePath } from 'react-router';
4
4
  import { DashboardSidebar } from 'widgets/Dashboard/components/DashboardSidebar';
5
5
  import { getDashboardRouteLabel } from 'widgets/Dashboard/utils/dashboardRoutes';
6
6
  import { useSession } from 'contexts/SessionContext';
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
2
  import { MessageDescriptor, useIntl } from 'react-intl';
3
- import { createBrowserRouter, generatePath, NavigateOptions, useNavigate } from 'react-router-dom';
3
+ import { createBrowserRouter, generatePath, NavigateOptions, useNavigate } from 'react-router';
4
4
  import { getDashboardRoutes } from 'widgets/Dashboard/utils/dashboardRoutes';
5
5
  import { TeacherDashboardPaths } from 'widgets/Dashboard/utils/teacherDashboardPaths';
6
6
  import { LearnerDashboardPaths } from 'widgets/Dashboard/utils/learnerRoutesPaths';
@@ -1,4 +1,4 @@
1
- import { useLocation, useMatches } from 'react-router-dom';
1
+ import { useLocation, useMatches } from 'react-router';
2
2
 
3
3
  /**
4
4
  * Retrieve route information
@@ -1,4 +1,4 @@
1
- import { RouterProvider, RouterProviderProps } from 'react-router-dom';
1
+ import { RouterProvider, RouterProviderProps } from 'react-router';
2
2
  import { useEffect } from 'react';
3
3
  import { location } from 'utils/indirection/window';
4
4
  import { useSession } from 'contexts/SessionContext';
@@ -4,7 +4,7 @@ import type {
4
4
  Options as IntlMessageFormatOptions,
5
5
  PrimitiveType,
6
6
  } from 'intl-messageformat';
7
- import { generatePath, Navigate, RouteObject } from 'react-router-dom';
7
+ import { generatePath, Navigate, RouteObject } from 'react-router';
8
8
  import DashboardPageNotFound from 'pages/DashboardPageNotFound';
9
9
  import { DashboardLayoutRoute } from 'widgets/Dashboard/components/DashboardLayoutRoute';
10
10
  import { getLearnerDashboardRoutes } from 'widgets/Dashboard/utils/learnerRoutes';
@@ -1,5 +1,5 @@
1
1
  import { MessageDescriptor, useIntl } from 'react-intl';
2
- import { Navigate, Outlet, RouteObject } from 'react-router-dom';
2
+ import { Navigate, Outlet, RouteObject } from 'react-router';
3
3
  import RouteInfo from 'widgets/Dashboard/components/RouteInfo';
4
4
  import { DashboardCreateAddressLoader } from 'pages/DashboardAddressesManagement/DashboardCreateAddressLoader';
5
5
  import { DashboardEditAddressLoader } from 'pages/DashboardAddressesManagement/DashboardEditAddressLoader';
@@ -1,4 +1,4 @@
1
- import { Navigate, RouteObject } from 'react-router-dom';
1
+ import { Navigate, RouteObject } from 'react-router';
2
2
  import {
3
3
  TeacherDashboardCourseContractsLayout,
4
4
  TeacherDashboardOrganizationContractsLayout,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
3
- import { generatePath } from 'react-router-dom';
3
+ import { generatePath } from 'react-router';
4
4
  import { CourseRun } from 'types';
5
5
  import useCourseEnrollment from 'widgets/SyllabusCourseRunsList/hooks/useCourseEnrollment';
6
6
  import CourseRunItem from 'widgets/SyllabusCourseRunsList/components/CourseRunItem';
@@ -11,6 +11,16 @@ import CourseRunEnrollment from '../CourseRunEnrollment';
11
11
  import CourseProductItem from '../CourseProductItem';
12
12
 
13
13
  const messages = defineMessages({
14
+ enrollNow: {
15
+ id: 'components.SyllabusCourseRun.enrollNow',
16
+ description: 'CTA for users to enroll on ongoing of future open course.',
17
+ defaultMessage: 'Enroll now',
18
+ },
19
+ studyNow: {
20
+ id: 'components.SyllabusCourseRun.studyNow',
21
+ description: 'CTA for users to enroll on archived course.',
22
+ defaultMessage: 'Study now',
23
+ },
14
24
  enrollment: {
15
25
  id: 'components.SyllabusCourseRun.enrollment',
16
26
  description: 'Title of the enrollment dates section of an opened course run block',
@@ -94,7 +104,12 @@ const OpenedCourseRun = ({
94
104
  <CourseRunEnrollment courseRun={courseRun} />
95
105
  ) : (
96
106
  <Button className="course-run-enrollment__cta" href={courseRun.resource_link} fullWidth>
97
- {StringHelper.capitalizeFirst(courseRun.state.call_to_action)}
107
+ {courseRun.state.call_to_action === 'enroll now' ? (
108
+ <FormattedMessage {...messages.enrollNow} />
109
+ ) : null}
110
+ {courseRun.state.call_to_action === 'study now' ? (
111
+ <FormattedMessage {...messages.studyNow} />
112
+ ) : null}
98
113
  </Button>
99
114
  )}
100
115
  </>
@@ -11,6 +11,16 @@ import CourseRunEnrollment from '../CourseRunEnrollment';
11
11
  import CourseProductItem from '../CourseProductItem';
12
12
 
13
13
  const messages = defineMessages({
14
+ enrollNow: {
15
+ id: 'components.SyllabusCourseRunCompacted.enrollNow',
16
+ description: 'CTA for users to enroll on ongoing of future open course.',
17
+ defaultMessage: 'Enroll now',
18
+ },
19
+ studyNow: {
20
+ id: 'components.SyllabusCourseRunCompacted.studyNow',
21
+ description: 'CTA for users to enroll on archived course.',
22
+ defaultMessage: 'Study now',
23
+ },
14
24
  course: {
15
25
  id: 'components.SyllabusCourseRunCompacted.course',
16
26
  description: 'Title of the course dates section of an opened course run block',
@@ -78,7 +88,12 @@ const OpenedSelfPacedCourseRun = ({
78
88
  <CourseRunEnrollment courseRun={courseRun} />
79
89
  ) : (
80
90
  <Button className="course-run-enrollment__cta" href={courseRun.resource_link} fullWidth>
81
- {StringHelper.capitalizeFirst(courseRun.state.call_to_action)}
91
+ {courseRun.state.call_to_action === 'enroll now' ? (
92
+ <FormattedMessage {...messages.enrollNow} />
93
+ ) : null}
94
+ {courseRun.state.call_to_action === 'study now' ? (
95
+ <FormattedMessage {...messages.studyNow} />
96
+ ) : null}
82
97
  </Button>
83
98
  )}
84
99
  </>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "richie-education",
3
- "version": "2.33.1-dev1",
3
+ "version": "2.33.1-dev10",
4
4
  "description": "A CMS to build learning portals for Open Education",
5
5
  "main": "sandbox/manage.py",
6
6
  "scripts": {
@@ -44,29 +44,29 @@
44
44
  "@babel/preset-env": "7.26.0",
45
45
  "@babel/preset-react": "7.25.9",
46
46
  "@babel/preset-typescript": "7.26.0",
47
- "@faker-js/faker": "9.1.0",
48
- "@formatjs/cli": "6.3.5",
49
- "@formatjs/intl-relativetimeformat": "11.4.1",
50
- "@hookform/resolvers": "3.9.0",
47
+ "@faker-js/faker": "9.2.0",
48
+ "@formatjs/cli": "6.3.11",
49
+ "@formatjs/intl-relativetimeformat": "11.4.5",
50
+ "@hookform/resolvers": "3.9.1",
51
51
  "@lyracom/embedded-form-glue": "1.4.2",
52
52
  "@openfun/cunningham-react": "2.9.4",
53
53
  "@openfun/cunningham-tokens": "2.1.1",
54
- "@sentry/browser": "8.35.0",
55
- "@sentry/types": "8.35.0",
56
- "@storybook/addon-actions": "8.3.6",
57
- "@storybook/addon-essentials": "8.3.6",
58
- "@storybook/addon-interactions": "8.3.6",
59
- "@storybook/addon-links": "8.3.6",
60
- "@storybook/react": "8.3.6",
61
- "@storybook/react-webpack5": "8.3.6",
62
- "@storybook/test": "8.3.6",
63
- "@tanstack/query-core": "5.59.16",
64
- "@tanstack/query-sync-storage-persister": "5.59.16",
65
- "@tanstack/react-query": "5.59.16",
66
- "@tanstack/react-query-devtools": "5.59.16",
67
- "@tanstack/react-query-persist-client": "5.59.16",
54
+ "@sentry/browser": "8.42.0",
55
+ "@sentry/types": "8.42.0",
56
+ "@storybook/addon-actions": "8.4.6",
57
+ "@storybook/addon-essentials": "8.4.6",
58
+ "@storybook/addon-interactions": "8.4.6",
59
+ "@storybook/addon-links": "8.4.6",
60
+ "@storybook/react": "8.4.6",
61
+ "@storybook/react-webpack5": "8.4.6",
62
+ "@storybook/test": "8.4.6",
63
+ "@tanstack/query-core": "5.62.1",
64
+ "@tanstack/query-sync-storage-persister": "5.62.1",
65
+ "@tanstack/react-query": "5.62.1",
66
+ "@tanstack/react-query-devtools": "5.62.1",
67
+ "@tanstack/react-query-persist-client": "5.62.1",
68
68
  "@testing-library/dom": "10.4.0",
69
- "@testing-library/jest-dom": "6.6.2",
69
+ "@testing-library/jest-dom": "6.6.3",
70
70
  "@testing-library/react": "16.0.1",
71
71
  "@testing-library/user-event": "14.5.2",
72
72
  "@types/fetch-mock": "7.3.8",
@@ -74,21 +74,21 @@
74
74
  "@types/jest": "29.5.14",
75
75
  "@types/js-cookie": "3.0.6",
76
76
  "@types/lodash-es": "4.17.12",
77
- "@types/node-fetch": "2.6.11",
77
+ "@types/node-fetch": "2.6.12",
78
78
  "@types/query-string": "6.3.0",
79
79
  "@types/react": "18.3.12",
80
80
  "@types/react-autosuggest": "10.1.11",
81
81
  "@types/react-dom": "18.3.1",
82
82
  "@types/react-modal": "3.16.3",
83
- "@typescript-eslint/eslint-plugin": "8.11.0",
84
- "@typescript-eslint/parser": "8.11.0",
83
+ "@typescript-eslint/eslint-plugin": "8.17.0",
84
+ "@typescript-eslint/parser": "8.17.0",
85
85
  "babel-jest": "29.7.0",
86
86
  "babel-loader": "9.2.1",
87
87
  "babel-plugin-react-intl": "8.2.25",
88
88
  "bootstrap": ">=4.6.0 <5",
89
89
  "classnames": "2.5.1",
90
90
  "cljs-merge": "1.1.1",
91
- "core-js": "3.38.1",
91
+ "core-js": "3.39.0",
92
92
  "downshift": "9.0.8",
93
93
  "eslint": ">=8.57.0 <9",
94
94
  "eslint-config-airbnb": "19.0.4",
@@ -96,17 +96,17 @@
96
96
  "eslint-config-prettier": "9.1.0",
97
97
  "eslint-import-resolver-webpack": "0.13.9",
98
98
  "eslint-plugin-compat": "6.0.1",
99
- "eslint-plugin-formatjs": "5.1.5",
99
+ "eslint-plugin-formatjs": "5.2.5",
100
100
  "eslint-plugin-import": "2.31.0",
101
101
  "eslint-plugin-jsx-a11y": "6.10.2",
102
102
  "eslint-plugin-prettier": "5.2.1",
103
103
  "eslint-plugin-react": "7.37.2",
104
104
  "eslint-plugin-react-hooks": "5.0.0",
105
- "eslint-plugin-storybook": "0.10.1",
105
+ "eslint-plugin-storybook": "0.11.1",
106
106
  "fetch-mock": "<10",
107
107
  "file-loader": "6.2.0",
108
108
  "glob": "11.0.0",
109
- "i18n-iso-countries": "7.12.0",
109
+ "i18n-iso-countries": "7.13.0",
110
110
  "iframe-resizer": "<5",
111
111
  "intl-pluralrules": "2.0.1",
112
112
  "jest": "29.7.0",
@@ -114,25 +114,25 @@
114
114
  "js-cookie": "3.0.5",
115
115
  "lodash-es": "4.17.21",
116
116
  "mdn-polyfills": "5.20.0",
117
- "msw": "2.5.2",
117
+ "msw": "2.6.6",
118
118
  "node-fetch": ">2.6.6 <3",
119
119
  "nodemon": "3.1.7",
120
- "prettier": "3.3.3",
120
+ "prettier": "3.4.1",
121
121
  "query-string": "9.1.1",
122
122
  "react": "18.3.1",
123
123
  "react-autosuggest": "10.1.0",
124
124
  "react-dom": "18.3.1",
125
- "react-hook-form": "7.53.1",
126
- "react-intl": "6.8.4",
125
+ "react-hook-form": "7.53.2",
126
+ "react-intl": "7.0.1",
127
127
  "react-modal": "3.16.1",
128
- "react-router-dom": "6.27.0",
129
- "sass": "1.80.4",
128
+ "react-router": "7.0.1",
129
+ "sass": "1.81.0",
130
130
  "source-map-loader": "5.0.0",
131
- "storybook": "8.3.6",
132
- "tsconfig-paths-webpack-plugin": "4.1.0",
133
- "typescript": "5.6.3",
134
- "uuid": "11.0.2",
135
- "webpack": "5.96.0",
131
+ "storybook": "8.4.6",
132
+ "tsconfig-paths-webpack-plugin": "4.2.0",
133
+ "typescript": "5.7.2",
134
+ "uuid": "11.0.3",
135
+ "webpack": "5.96.1",
136
136
  "webpack-cli": "5.1.4",
137
137
  "whatwg-fetch": "3.6.20",
138
138
  "xhr-mock": "2.5.1",
@@ -152,7 +152,7 @@
152
152
  "yarn": "1.22.22"
153
153
  },
154
154
  "devDependencies": {
155
- "@storybook/addon-mdx-gfm": "8.3.6",
155
+ "@storybook/addon-mdx-gfm": "8.4.6",
156
156
  "@storybook/addon-webpack5-compiler-babel": "3.0.3"
157
157
  }
158
158
  }
@@ -208,6 +208,11 @@
208
208
  @include sv-flex(0, 0, auto);
209
209
  }
210
210
 
211
+ // Define color variable for default item color on hover then available variants
212
+ @if r-theme-val(topbar, item-hover-color) {
213
+ --r--menu--item--hover--color: #{r-theme-val(topbar, item-hover-color)};
214
+ }
215
+
211
216
  & > a {
212
217
  @include sv-flex(1, 0, 100%);
213
218
  display: flex;
@@ -228,6 +233,7 @@
228
233
  @include media-breakpoint-up($r-topbar-breakpoint) {
229
234
  position: relative;
230
235
 
236
+ // If there is no default hover color we assume there is also no variant
231
237
  @if r-theme-val(topbar, item-hover-color) {
232
238
  &::after {
233
239
  content: '';
@@ -236,7 +242,7 @@
236
242
  left: 0;
237
243
  right: 0;
238
244
  height: 8px;
239
- background-color: r-theme-val(topbar, item-hover-color);
245
+ background-color: var(--r--menu--item--hover--color);
240
246
  border-top-left-radius: 0.2rem;
241
247
  border-top-right-radius: 0.2rem;
242
248
  }
package/webpack.config.js CHANGED
@@ -99,7 +99,16 @@ module.exports = (env) => {
99
99
  },
100
100
  },
101
101
  // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
102
- { enforce: 'pre', test: /\.js$/, loader: 'source-map-loader' },
102
+ {
103
+ enforce: 'pre',
104
+ test: /\.js$/,
105
+ loader: 'source-map-loader',
106
+ options: {
107
+ filterSourceMappingUrl: (url, resourcePath) => {
108
+ return !/@formatjs\/fast-memoize/i.test(resourcePath);
109
+ },
110
+ },
111
+ },
103
112
  ],
104
113
  },
105
114