richie-education 3.1.3-dev8 → 3.2.1-dev1
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.
- package/.storybook/__mocks__/utils/context.ts +4 -0
- package/i18n/locales/ar-SA.json +30 -10
- package/i18n/locales/es-ES.json +30 -10
- package/i18n/locales/fa-IR.json +30 -10
- package/i18n/locales/fr-CA.json +31 -11
- package/i18n/locales/fr-FR.json +32 -12
- package/i18n/locales/ko-KR.json +30 -10
- package/i18n/locales/pt-PT.json +30 -10
- package/i18n/locales/ru-RU.json +30 -10
- package/i18n/locales/vi-VN.json +30 -10
- package/js/api/joanie.ts +8 -8
- package/js/components/ContractFrame/OrganizationContractFrame.spec.tsx +11 -19
- package/js/components/ContractFrame/OrganizationContractFrame.tsx +4 -4
- package/js/components/CourseGlimpse/CourseGlimpseFooter.tsx +30 -5
- package/js/components/CourseGlimpse/index.spec.tsx +18 -0
- package/js/components/CourseGlimpse/index.stories.tsx +75 -4
- package/js/components/CourseGlimpse/index.tsx +4 -0
- package/js/components/CourseGlimpse/utils.ts +35 -30
- package/js/components/CourseGlimpseList/utils.ts +2 -2
- package/js/components/PurchaseButton/index.tsx +3 -3
- package/js/components/SaleTunnel/GenericSaleTunnel.tsx +6 -3
- package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +9 -7
- package/js/components/SaleTunnel/index.full-process.spec.tsx +3 -3
- package/js/components/SaleTunnel/index.spec.tsx +131 -64
- package/js/components/SaleTunnel/index.stories.tsx +17 -2
- package/js/components/SaleTunnel/index.tsx +2 -2
- package/js/components/TeacherDashboardCourseList/index.spec.tsx +3 -3
- package/js/components/TeacherDashboardCourseList/index.tsx +2 -2
- package/js/hooks/useContractArchive/index.ts +3 -3
- package/js/hooks/useCourseProductUnion/index.spec.tsx +16 -18
- package/js/hooks/useCourseProductUnion/index.ts +7 -7
- package/js/hooks/useCourseProducts.ts +4 -8
- package/js/hooks/useDefaultOrganizationId/index.tsx +4 -7
- package/js/hooks/useOffering/index.ts +32 -0
- package/js/hooks/useTeacherCoursesSearch/index.tsx +2 -2
- package/js/hooks/useTeacherPendingContractsCount/index.ts +4 -4
- package/js/pages/DashboardCourses/index.spec.tsx +14 -14
- package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.spec.tsx +11 -14
- package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardContracts/index.tsx +4 -9
- package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.spec.tsx +11 -11
- package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.timer.spec.tsx +10 -13
- package/js/pages/TeacherDashboardContractsLayout/components/BulkDownloadContractButton/index.tsx +4 -4
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.spec.tsx +20 -28
- package/js/pages/TeacherDashboardContractsLayout/components/ContractActionsBar/index.tsx +8 -11
- package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.spec.tsx +6 -6
- package/js/pages/TeacherDashboardContractsLayout/components/SignOrganizationContractButton/index.tsx +4 -4
- package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.spec.tsx +7 -7
- package/js/pages/TeacherDashboardContractsLayout/hooks/useCheckContractArchiveExists/index.tsx +5 -5
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.spec.ts +21 -28
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/contractArchiveLocalStorage.ts +13 -17
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.spec.tsx +11 -13
- package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +6 -6
- package/js/pages/TeacherDashboardContractsLayout/hooks/useHasContractToDownload/index.tsx +3 -3
- package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.spec.tsx +16 -16
- package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractFilters/index.tsx +4 -4
- package/js/pages/TeacherDashboardContractsLayout/hooks/useTeacherContractsToSign.tsx +4 -4
- package/js/pages/TeacherDashboardCourseLearnersLayout/hooks/useCourseLearnersFilters/index.spec.tsx +21 -21
- package/js/pages/TeacherDashboardCourseLearnersLayout/hooks/useCourseLearnersFilters/index.ts +5 -10
- package/js/pages/TeacherDashboardCourseLearnersLayout/index.spec.tsx +61 -79
- package/js/pages/TeacherDashboardCourseLearnersLayout/index.tsx +1 -1
- package/js/pages/TeacherDashboardCoursesLoader/index.spec.tsx +11 -11
- package/js/pages/TeacherDashboardOrganizationCourseLoader/index.spec.tsx +11 -11
- package/js/pages/TeacherDashboardTraining/TeacherDashboardTrainingLoader.tsx +7 -7
- package/js/pages/TeacherDashboardTraining/index.spec.tsx +21 -29
- package/js/pages/TeacherDashboardTraining/index.tsx +12 -16
- package/js/settings/index.ts +1 -0
- package/js/settings/settings.prod.ts +1 -0
- package/js/translations/ar-SA.json +1 -1
- package/js/translations/es-ES.json +1 -1
- package/js/translations/fa-IR.json +1 -1
- package/js/translations/fr-CA.json +1 -1
- package/js/translations/fr-FR.json +1 -1
- package/js/translations/ko-KR.json +1 -1
- package/js/translations/pt-PT.json +1 -1
- package/js/translations/ru-RU.json +1 -1
- package/js/translations/vi-VN.json +1 -1
- package/js/types/Course.ts +4 -0
- package/js/types/Joanie.ts +31 -22
- package/js/types/index.ts +6 -2
- package/js/utils/test/factories/joanie.ts +18 -11
- package/js/utils/test/factories/richie.ts +10 -2
- package/js/utils/test/mockCourseProductWithOrder.ts +4 -4
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/DashboardItemEnrollment.tsx +1 -1
- package/js/widgets/Dashboard/components/DashboardItem/Enrollment/ProductCertificateFooter/index.spec.tsx +1 -1
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +3 -3
- package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrderContract.useUnionResource.cache.spec.tsx +1 -1
- package/js/widgets/Dashboard/components/DashboardItem/Order/Installment/index.tsx +4 -4
- package/js/widgets/Dashboard/components/DashboardItem/stories.mock.ts +1 -1
- package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.spec.tsx +23 -28
- package/js/widgets/Dashboard/components/DashboardSidebar/components/ContractNavLink/index.tsx +4 -8
- package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.spec.tsx +17 -24
- package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/index.tsx +18 -21
- package/js/widgets/Dashboard/components/TeacherDashboardCourseSidebar/utils.ts +4 -4
- package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.tsx +3 -7
- package/js/widgets/Dashboard/utils/teacherDashboardPaths.tsx +4 -4
- package/js/widgets/Slider/components/SlidePanel.tsx +9 -0
- package/js/widgets/Slider/index.stories.tsx +53 -0
- package/js/widgets/Slider/index.tsx +21 -2
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/CourseProductItemFooter/index.tsx +10 -14
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/_styles.scss +8 -1
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/CourseRunList.tsx +2 -2
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/components/CourseProductCourseRuns/_styles.scss +9 -0
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +116 -75
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.stories.tsx +6 -4
- package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.tsx +29 -30
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.stories.tsx +81 -0
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.tsx +36 -2
- package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRunCompacted/index.tsx +36 -2
- package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +58 -8
- package/package.json +2 -1
- package/scss/colors/_theme.scss +3 -0
- package/scss/components/templates/richie/slider/_slider.scss +19 -0
- package/scss/objects/_blogpost_glimpses.scss +5 -0
- package/scss/objects/_course_glimpses.scss +16 -0
- package/js/hooks/useCourseProductRelation/index.ts +0 -44
|
@@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
4
4
|
import { RichieContextFactory as mockRichieContextFactory } from 'utils/test/factories/richie';
|
|
5
5
|
import {
|
|
6
6
|
CourseListItemFactory,
|
|
7
|
-
|
|
7
|
+
OfferingFactory,
|
|
8
8
|
OrganizationFactory,
|
|
9
9
|
} from 'utils/test/factories/joanie';
|
|
10
10
|
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
@@ -59,8 +59,8 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
|
|
|
59
59
|
mockPaginatedResponse(CourseListItemFactory().many(15), 15, false),
|
|
60
60
|
);
|
|
61
61
|
fetchMock.get(
|
|
62
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
63
|
-
mockPaginatedResponse(
|
|
62
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?product_type=credential&page=1&page_size=${perPage}`,
|
|
63
|
+
mockPaginatedResponse(OfferingFactory().many(15), 15, false),
|
|
64
64
|
);
|
|
65
65
|
fetchMock.get(
|
|
66
66
|
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?signature_state=half_signed&page=1`,
|
|
@@ -76,7 +76,7 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
|
|
|
76
76
|
await expectNoSpinner('Loading courses...');
|
|
77
77
|
|
|
78
78
|
nbApiCalls += 1; // course api call
|
|
79
|
-
nbApiCalls += 1; //
|
|
79
|
+
nbApiCalls += 1; // offerings api call
|
|
80
80
|
nbApiCalls += 1; // contracts api call
|
|
81
81
|
const calledUrls = fetchMock.calls().map((call) => call[0]);
|
|
82
82
|
expect(calledUrls).toHaveLength(nbApiCalls);
|
|
@@ -84,7 +84,7 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
|
|
|
84
84
|
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/courses/?has_listed_course_runs=true&page=1&page_size=${perPage}`,
|
|
85
85
|
);
|
|
86
86
|
expect(calledUrls).toContain(
|
|
87
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
87
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?product_type=credential&page=1&page_size=${perPage}`,
|
|
88
88
|
);
|
|
89
89
|
await expectNoSpinner('Loading organization...');
|
|
90
90
|
|
|
@@ -117,8 +117,8 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
|
|
|
117
117
|
mockPaginatedResponse(CourseListItemFactory().many(15), 15, false),
|
|
118
118
|
);
|
|
119
119
|
fetchMock.get(
|
|
120
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
121
|
-
mockPaginatedResponse(
|
|
120
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?product_type=credential&page=1&page_size=${perPage}`,
|
|
121
|
+
mockPaginatedResponse(OfferingFactory().many(15), 15, false),
|
|
122
122
|
);
|
|
123
123
|
|
|
124
124
|
render(<TeacherDashboardOrganizationCourseLoader />, {
|
|
@@ -136,22 +136,22 @@ describe('components/TeacherDashboardOrganizationCourseLoader', () => {
|
|
|
136
136
|
mockPaginatedResponse(CourseListItemFactory().many(5), 5, false),
|
|
137
137
|
);
|
|
138
138
|
fetchMock.get(
|
|
139
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
140
|
-
mockPaginatedResponse(
|
|
139
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?query=text+query&product_type=credential&page=1&page_size=${perPage}`,
|
|
140
|
+
mockPaginatedResponse(OfferingFactory().many(5), 5, false),
|
|
141
141
|
);
|
|
142
142
|
const user = userEvent.setup();
|
|
143
143
|
await user.type(screen.getByRole('textbox', { name: /Search/ }), 'text query');
|
|
144
144
|
await user.click(screen.getByRole('button', { name: /Search/ }));
|
|
145
145
|
|
|
146
146
|
nbApiCalls = 1; // course api call
|
|
147
|
-
nbApiCalls += 1; //
|
|
147
|
+
nbApiCalls += 1; // offerings api call
|
|
148
148
|
const calledUrls = fetchMock.calls().map((call) => call[0]);
|
|
149
149
|
expect(calledUrls).toHaveLength(nbApiCalls);
|
|
150
150
|
expect(calledUrls).toContain(
|
|
151
151
|
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/courses/?query=text+query&has_listed_course_runs=true&page=1&page_size=${perPage}`,
|
|
152
152
|
);
|
|
153
153
|
expect(calledUrls).toContain(
|
|
154
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
154
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/?query=text+query&product_type=credential&page=1&page_size=${perPage}`,
|
|
155
155
|
);
|
|
156
156
|
|
|
157
157
|
await waitFor(() => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FormattedMessage, defineMessages } from 'react-intl';
|
|
2
2
|
import { useParams } from 'react-router';
|
|
3
3
|
|
|
4
|
+
import { useOffering } from 'hooks/useOffering';
|
|
4
5
|
import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
|
|
5
6
|
import { TeacherDashboardCourseSidebar } from 'widgets/Dashboard/components/TeacherDashboardCourseSidebar';
|
|
6
7
|
import { Spinner } from 'components/Spinner';
|
|
7
|
-
import { useCourseProductRelation } from 'hooks/useCourseProductRelation';
|
|
8
8
|
import { useBreadcrumbsPlaceholders } from 'hooks/useBreadcrumbsPlaceholders';
|
|
9
9
|
import { TeacherDashboardTraining } from '.';
|
|
10
10
|
|
|
@@ -22,17 +22,17 @@ const messages = defineMessages({
|
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
export const TeacherDashboardTrainingLoader = () => {
|
|
25
|
-
const {
|
|
26
|
-
|
|
25
|
+
const { offeringId, organizationId } = useParams<{
|
|
26
|
+
offeringId: string;
|
|
27
27
|
organizationId?: string;
|
|
28
28
|
}>();
|
|
29
29
|
|
|
30
30
|
const {
|
|
31
|
-
item:
|
|
31
|
+
item: offering,
|
|
32
32
|
states: { fetching },
|
|
33
|
-
} =
|
|
33
|
+
} = useOffering(offeringId, { organization_id: organizationId });
|
|
34
34
|
useBreadcrumbsPlaceholders({
|
|
35
|
-
courseTitle:
|
|
35
|
+
courseTitle: offering?.product.title ?? '',
|
|
36
36
|
});
|
|
37
37
|
return (
|
|
38
38
|
<DashboardLayout sidebar={<TeacherDashboardCourseSidebar />}>
|
|
@@ -48,7 +48,7 @@ export const TeacherDashboardTrainingLoader = () => {
|
|
|
48
48
|
</span>
|
|
49
49
|
</Spinner>
|
|
50
50
|
) : (
|
|
51
|
-
<TeacherDashboardTraining
|
|
51
|
+
<TeacherDashboardTraining offering={offering} />
|
|
52
52
|
)}
|
|
53
53
|
</DashboardLayout>
|
|
54
54
|
);
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
UserFactory,
|
|
12
12
|
} from 'utils/test/factories/richie';
|
|
13
13
|
import JoanieSessionProvider from 'contexts/SessionContext/JoanieSessionProvider';
|
|
14
|
-
import {
|
|
14
|
+
import { OfferingFactory, OrganizationFactory } from 'utils/test/factories/joanie';
|
|
15
15
|
import { createTestQueryClient } from 'utils/test/createTestQueryClient';
|
|
16
16
|
import { expectNoSpinner } from 'utils/test/expectSpinner';
|
|
17
17
|
import { DashboardBreadcrumbsProvider } from 'widgets/Dashboard/contexts/DashboardBreadcrumbsContext';
|
|
@@ -46,15 +46,9 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
it('should render TeacherDashboardTrainingLoader page', async () => {
|
|
49
|
-
const
|
|
50
|
-
fetchMock.get(
|
|
51
|
-
|
|
52
|
-
[],
|
|
53
|
-
);
|
|
54
|
-
fetchMock.get(
|
|
55
|
-
`https://joanie.endpoint/api/v1.0/course-product-relations/${courseProductRelation.id}/`,
|
|
56
|
-
courseProductRelation,
|
|
57
|
-
);
|
|
49
|
+
const offering = OfferingFactory().one();
|
|
50
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/organizations/?offering_id=${offering.id}`, []);
|
|
51
|
+
fetchMock.get(`https://joanie.endpoint/api/v1.0/offerings/${offering.id}/`, offering);
|
|
58
52
|
|
|
59
53
|
const user = UserFactory().one();
|
|
60
54
|
render(
|
|
@@ -67,12 +61,12 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
67
61
|
router={createMemoryRouter(
|
|
68
62
|
[
|
|
69
63
|
{
|
|
70
|
-
path: ':
|
|
64
|
+
path: ':offeringId',
|
|
71
65
|
element: <TeacherDashboardTrainingLoader />,
|
|
72
66
|
},
|
|
73
67
|
],
|
|
74
68
|
{
|
|
75
|
-
initialEntries: [`/${
|
|
69
|
+
initialEntries: [`/${offering.id}`],
|
|
76
70
|
},
|
|
77
71
|
)}
|
|
78
72
|
/>
|
|
@@ -88,12 +82,10 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
88
82
|
await expectNoSpinner('Loading course...');
|
|
89
83
|
|
|
90
84
|
nbApiCalls += 1; // organizations api call
|
|
91
|
-
nbApiCalls += 1; //
|
|
85
|
+
nbApiCalls += 1; // offerings api call
|
|
92
86
|
const calledUrls = fetchMock.calls().map((call) => call[0]);
|
|
93
87
|
expect(calledUrls).toHaveLength(nbApiCalls);
|
|
94
|
-
expect(calledUrls).toContain(
|
|
95
|
-
`https://joanie.endpoint/api/v1.0/course-product-relations/${courseProductRelation.id}/`,
|
|
96
|
-
);
|
|
88
|
+
expect(calledUrls).toContain(`https://joanie.endpoint/api/v1.0/offerings/${offering.id}/`);
|
|
97
89
|
|
|
98
90
|
// main titles
|
|
99
91
|
expect(
|
|
@@ -103,27 +95,27 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
103
95
|
).toBeInTheDocument();
|
|
104
96
|
|
|
105
97
|
expect(
|
|
106
|
-
screen.getAllByRole('heading', { name: capitalize(
|
|
98
|
+
screen.getAllByRole('heading', { name: capitalize(offering.product.title) }),
|
|
107
99
|
).toHaveLength(2);
|
|
108
100
|
|
|
109
|
-
const nbCourseRun =
|
|
101
|
+
const nbCourseRun = offering.product.target_courses.reduce(
|
|
110
102
|
(acc, course) => acc + course.course_runs.length,
|
|
111
103
|
0,
|
|
112
104
|
);
|
|
113
105
|
expect(screen.getAllByRole('link', { name: 'Go to course area' })).toHaveLength(nbCourseRun);
|
|
114
106
|
});
|
|
115
107
|
|
|
116
|
-
it('should fetch
|
|
108
|
+
it('should fetch offering with organization id if there is one in the path', async () => {
|
|
117
109
|
const organization = OrganizationFactory().one();
|
|
118
|
-
const
|
|
110
|
+
const offering = OfferingFactory({
|
|
119
111
|
organizations: [organization],
|
|
120
112
|
}).one();
|
|
121
113
|
fetchMock.get(
|
|
122
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
123
|
-
|
|
114
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/${offering.id}/`,
|
|
115
|
+
offering,
|
|
124
116
|
);
|
|
125
117
|
fetchMock.get(
|
|
126
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?
|
|
118
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/contracts/?offering_id=${offering.id}&signature_state=half_signed&page=1&page_size=25`,
|
|
127
119
|
[],
|
|
128
120
|
);
|
|
129
121
|
|
|
@@ -138,12 +130,12 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
138
130
|
router={createMemoryRouter(
|
|
139
131
|
[
|
|
140
132
|
{
|
|
141
|
-
path: '/:organizationId/:
|
|
133
|
+
path: '/:organizationId/:offeringId',
|
|
142
134
|
element: <TeacherDashboardTrainingLoader />,
|
|
143
135
|
},
|
|
144
136
|
],
|
|
145
137
|
{
|
|
146
|
-
initialEntries: [`/${organization.id}/${
|
|
138
|
+
initialEntries: [`/${organization.id}/${offering.id}`],
|
|
147
139
|
},
|
|
148
140
|
)}
|
|
149
141
|
/>
|
|
@@ -159,11 +151,11 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
159
151
|
await expectNoSpinner('Loading course...');
|
|
160
152
|
|
|
161
153
|
nbApiCalls += 1; // contracts api call
|
|
162
|
-
nbApiCalls += 1; //
|
|
154
|
+
nbApiCalls += 1; // offerings api call
|
|
163
155
|
const calledUrls = fetchMock.calls().map((call) => call[0]);
|
|
164
156
|
expect(calledUrls).toHaveLength(nbApiCalls);
|
|
165
157
|
expect(calledUrls).toContain(
|
|
166
|
-
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/
|
|
158
|
+
`https://joanie.endpoint/api/v1.0/organizations/${organization.id}/offerings/${offering.id}/`,
|
|
167
159
|
);
|
|
168
160
|
|
|
169
161
|
// main titles
|
|
@@ -174,10 +166,10 @@ describe('components/TeacherDashboardTrainingLoader', () => {
|
|
|
174
166
|
).toBeInTheDocument();
|
|
175
167
|
|
|
176
168
|
expect(
|
|
177
|
-
screen.getAllByRole('heading', { name: capitalize(
|
|
169
|
+
screen.getAllByRole('heading', { name: capitalize(offering.product.title) }),
|
|
178
170
|
).toHaveLength(2);
|
|
179
171
|
|
|
180
|
-
const nbCourseRun =
|
|
172
|
+
const nbCourseRun = offering.product.target_courses.reduce(
|
|
181
173
|
(acc, course) => acc + course.course_runs.length,
|
|
182
174
|
0,
|
|
183
175
|
);
|
|
@@ -6,37 +6,33 @@ import { DashboardLayout } from 'widgets/Dashboard/components/DashboardLayout';
|
|
|
6
6
|
import { DashboardCard } from 'widgets/Dashboard/components/DashboardCard';
|
|
7
7
|
import { Icon, IconTypeEnum } from 'components/Icon';
|
|
8
8
|
import Banner, { BannerType } from 'components/Banner';
|
|
9
|
-
import {
|
|
9
|
+
import { Offering } from 'types/Joanie';
|
|
10
10
|
|
|
11
11
|
const messages = defineMessages({
|
|
12
|
-
|
|
12
|
+
errorNoOffering: {
|
|
13
13
|
defaultMessage: "This product doesn't exist",
|
|
14
|
-
description: 'Message displayed when requested
|
|
15
|
-
id: 'components.TeacherDashboardTraining.
|
|
14
|
+
description: 'Message displayed when requested offering is not found',
|
|
15
|
+
id: 'components.TeacherDashboardTraining.errorNoOffering',
|
|
16
16
|
},
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
interface TeacherDashboardTrainingProps {
|
|
20
|
-
|
|
20
|
+
offering: Offering;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export const TeacherDashboardTraining = ({
|
|
24
|
-
courseProductRelation,
|
|
25
|
-
}: TeacherDashboardTrainingProps) => {
|
|
23
|
+
export const TeacherDashboardTraining = ({ offering }: TeacherDashboardTrainingProps) => {
|
|
26
24
|
const intl = useIntl();
|
|
27
|
-
return
|
|
25
|
+
return offering ? (
|
|
28
26
|
<div className="teacher-course-page">
|
|
29
27
|
<DashboardCard
|
|
30
28
|
className="icon-arrow-right-rounded"
|
|
31
29
|
header={
|
|
32
30
|
<div>
|
|
33
31
|
<div className="dashboard__title_container--small">
|
|
34
|
-
<h2 className="dashboard__title--large">
|
|
35
|
-
{capitalize(courseProductRelation.product.title)}
|
|
36
|
-
</h2>
|
|
32
|
+
<h2 className="dashboard__title--large">{capitalize(offering.product.title)}</h2>
|
|
37
33
|
</div>
|
|
38
|
-
{
|
|
39
|
-
<div className="dashboard__quote">{
|
|
34
|
+
{offering.product.description && (
|
|
35
|
+
<div className="dashboard__quote">{offering.product.description}</div>
|
|
40
36
|
)}
|
|
41
37
|
</div>
|
|
42
38
|
}
|
|
@@ -44,7 +40,7 @@ export const TeacherDashboardTraining = ({
|
|
|
44
40
|
fullWidth
|
|
45
41
|
/>
|
|
46
42
|
<DashboardLayout.NestedSection>
|
|
47
|
-
{
|
|
43
|
+
{offering.product.target_courses.map((course) => (
|
|
48
44
|
<DashboardLayout.Section key={`course_target_${course.code}`}>
|
|
49
45
|
<DashboardCard
|
|
50
46
|
className="icon-arrow-right-rounded"
|
|
@@ -67,7 +63,7 @@ export const TeacherDashboardTraining = ({
|
|
|
67
63
|
</div>
|
|
68
64
|
) : (
|
|
69
65
|
<Banner
|
|
70
|
-
message={intl.formatMessage(messages.
|
|
66
|
+
message={intl.formatMessage(messages.errorNoOffering)}
|
|
71
67
|
type={BannerType.ERROR}
|
|
72
68
|
rounded
|
|
73
69
|
/>
|
package/js/settings/index.ts
CHANGED