Skip to content

Commit 7f2df1f

Browse files
authored
v2 learning resource drawer formats and location (#1826)
* add format info item * display location if format is in_person * add tests * also show location for hybrid courses
1 parent b95a184 commit 7f2df1f

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

frontends/ol-components/src/components/LearningResourceCard/testUtils.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,43 @@ const courses = {
261261
],
262262
}),
263263
},
264+
multipleFormats: makeResource({
265+
resource_type: ResourceTypeEnum.Course,
266+
location: "Earth",
267+
delivery: [
268+
{
269+
code: DeliveryEnum.Online,
270+
name: DeliveryEnumDescriptions.online,
271+
},
272+
{
273+
code: DeliveryEnum.InPerson,
274+
name: DeliveryEnumDescriptions.in_person,
275+
},
276+
],
277+
runs: [
278+
factories.learningResources.run({
279+
delivery: sameDataRun.delivery,
280+
resource_prices: sameDataRun.resource_prices,
281+
location: sameDataRun.location,
282+
}),
283+
],
284+
}),
285+
singleFormat: makeResource({
286+
resource_type: ResourceTypeEnum.Course,
287+
delivery: [
288+
{
289+
code: DeliveryEnum.Online,
290+
name: DeliveryEnumDescriptions.online,
291+
},
292+
],
293+
runs: [
294+
factories.learningResources.run({
295+
delivery: sameDataRun.delivery,
296+
resource_prices: sameDataRun.resource_prices,
297+
location: sameDataRun.location,
298+
}),
299+
],
300+
}),
264301
}
265302

266303
const resourceArgType = {

frontends/ol-components/src/components/LearningResourceExpanded/InfoSectionV2.test.tsx

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,16 @@ describe("Learning resource info section start date", () => {
165165
})
166166
})
167167

168-
test("If data is different, dates and prices are not shown", () => {
168+
test("If data is different then dates, formats, locations and prices are not shown", () => {
169169
const course = courses.multipleRuns.differentData
170170
render(<InfoSectionV2 resource={course} />, {
171171
wrapper: ThemeProvider,
172172
})
173173
const section = screen.getByTestId("drawer-info-items")
174174
expect(within(section).queryByText("Start Date:")).toBeNull()
175175
expect(within(section).queryByText("Price:")).toBeNull()
176+
expect(within(section).queryByText("Format:")).toBeNull()
177+
expect(within(section).queryByText("Location:")).toBeNull()
176178
})
177179

178180
test("Clicking the show more button should show more dates", async () => {
@@ -189,3 +191,34 @@ describe("Learning resource info section start date", () => {
189191
expect(runDates.children.length).toBe(totalRuns + 1)
190192
})
191193
})
194+
195+
describe("Learning resource info section format and location", () => {
196+
test("Multiple formats", () => {
197+
const course = courses.multipleFormats
198+
render(<InfoSectionV2 resource={course} />, {
199+
wrapper: ThemeProvider,
200+
})
201+
202+
const section = screen.getByTestId("drawer-info-items")
203+
within(section).getAllByText((_content, node) => {
204+
// The pipe in this string is followed by a zero width space
205+
return node?.textContent === "Format:Online|​In person" || false
206+
})
207+
within(section).getAllByText((_content, node) => {
208+
return node?.textContent === "Location:Earth" || false
209+
})
210+
})
211+
212+
test("Single format", () => {
213+
const course = courses.singleFormat
214+
render(<InfoSectionV2 resource={course} />, {
215+
wrapper: ThemeProvider,
216+
})
217+
218+
const section = screen.getByTestId("drawer-info-items")
219+
within(section).getAllByText((_content, node) => {
220+
return node?.textContent === "Format:Online" || false
221+
})
222+
expect(within(section).queryByText("In person")).toBeNull()
223+
})
224+
})

frontends/ol-components/src/components/LearningResourceExpanded/InfoSectionV2.tsx

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import {
1414
RiPresentationLine,
1515
RiAwardFill,
1616
RiAwardLine,
17+
RiComputerLine,
18+
RiMapPinLine,
1719
} from "@remixicon/react"
18-
import { LearningResource, ResourceTypeEnum } from "api"
20+
import { DeliveryEnum, LearningResource, ResourceTypeEnum } from "api"
1921
import {
2022
allRunsAreIdentical,
2123
formatDurationClockTime,
@@ -232,6 +234,15 @@ const RunDates: React.FC<{ resource: LearningResource }> = ({ resource }) => {
232234
}
233235
}
234236

237+
const shouldShowFormat = (resource: LearningResource) => {
238+
return (
239+
(resource.resource_type === ResourceTypeEnum.Course ||
240+
resource.resource_type === ResourceTypeEnum.Program) &&
241+
allRunsAreIdentical(resource) &&
242+
resource.delivery
243+
)
244+
}
245+
235246
const INFO_ITEMS: InfoItemConfig = [
236247
{
237248
label: (resource: LearningResource) => {
@@ -248,6 +259,41 @@ const INFO_ITEMS: InfoItemConfig = [
248259
} else return null
249260
},
250261
},
262+
{
263+
label: "Format:",
264+
Icon: RiComputerLine,
265+
selector: (resource: LearningResource) => {
266+
if (shouldShowFormat(resource)) {
267+
const totalFormats = resource.delivery?.length || 0
268+
return resource.delivery.map((format, index) => {
269+
return (
270+
<InfoItemValue
271+
key={`format-${index}`}
272+
label={format.name}
273+
index={index}
274+
total={totalFormats}
275+
/>
276+
)
277+
})
278+
} else return null
279+
},
280+
},
281+
{
282+
label: "Location:",
283+
Icon: RiMapPinLine,
284+
selector: (resource: LearningResource) => {
285+
if (
286+
shouldShowFormat(resource) &&
287+
resource.delivery?.filter(
288+
(d) =>
289+
d.code === DeliveryEnum.InPerson || d.code === DeliveryEnum.Hybrid,
290+
).length > 0 &&
291+
resource.location
292+
) {
293+
return <InfoItemValue label={resource.location} index={1} total={1} />
294+
} else return null
295+
},
296+
},
251297
{
252298
label: "Price:",
253299
Icon: RiPriceTag3Line,

0 commit comments

Comments
 (0)