Skip to content

Commit 12c6955

Browse files
committed
Merge branch 'main' into jk/5920-prefetch-homepage
2 parents c8cde78 + 1a2b98e commit 12c6955

30 files changed

+1040
-130
lines changed

docker-compose.opensearch.base.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
opensearch:
3-
image: opensearchproject/opensearch:2.17.1
3+
image: opensearchproject/opensearch:2.18.0
44
environment:
55
- "cluster.name=opensearch-cluster"
66
- "bootstrap.memory_lock=true" # along with the memlock settings below, disables swapping

frontends/api/src/generated/v1/api.ts

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18233,6 +18233,45 @@ export const LearningpathsApiAxiosParamCreator = function (
1823318233
options: localVarRequestOptions,
1823418234
}
1823518235
},
18236+
/**
18237+
* Get a list of all learning path items
18238+
* @summary List
18239+
* @param {*} [options] Override http request option.
18240+
* @throws {RequiredError}
18241+
*/
18242+
learningpathsMembershipList: async (
18243+
options: RawAxiosRequestConfig = {},
18244+
): Promise<RequestArgs> => {
18245+
const localVarPath = `/api/v1/learningpaths/membership/`
18246+
// use dummy base URL string because the URL constructor only accepts absolute URLs.
18247+
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL)
18248+
let baseOptions
18249+
if (configuration) {
18250+
baseOptions = configuration.baseOptions
18251+
}
18252+
18253+
const localVarRequestOptions = {
18254+
method: "GET",
18255+
...baseOptions,
18256+
...options,
18257+
}
18258+
const localVarHeaderParameter = {} as any
18259+
const localVarQueryParameter = {} as any
18260+
18261+
setSearchParams(localVarUrlObj, localVarQueryParameter)
18262+
let headersFromBaseOptions =
18263+
baseOptions && baseOptions.headers ? baseOptions.headers : {}
18264+
localVarRequestOptions.headers = {
18265+
...localVarHeaderParameter,
18266+
...headersFromBaseOptions,
18267+
...options.headers,
18268+
}
18269+
18270+
return {
18271+
url: toPathString(localVarUrlObj),
18272+
options: localVarRequestOptions,
18273+
}
18274+
},
1823618275
/**
1823718276
* Update individual fields of a learning path
1823818277
* @summary Update
@@ -18672,6 +18711,35 @@ export const LearningpathsApiFp = function (configuration?: Configuration) {
1867218711
configuration,
1867318712
)(axios, operationBasePath || basePath)
1867418713
},
18714+
/**
18715+
* Get a list of all learning path items
18716+
* @summary List
18717+
* @param {*} [options] Override http request option.
18718+
* @throws {RequiredError}
18719+
*/
18720+
async learningpathsMembershipList(
18721+
options?: RawAxiosRequestConfig,
18722+
): Promise<
18723+
(
18724+
axios?: AxiosInstance,
18725+
basePath?: string,
18726+
) => AxiosPromise<Array<MicroLearningPathRelationship>>
18727+
> {
18728+
const localVarAxiosArgs =
18729+
await localVarAxiosParamCreator.learningpathsMembershipList(options)
18730+
const index = configuration?.serverIndex ?? 0
18731+
const operationBasePath =
18732+
operationServerMap["LearningpathsApi.learningpathsMembershipList"]?.[
18733+
index
18734+
]?.url
18735+
return (axios, basePath) =>
18736+
createRequestFunction(
18737+
localVarAxiosArgs,
18738+
globalAxios,
18739+
BASE_PATH,
18740+
configuration,
18741+
)(axios, operationBasePath || basePath)
18742+
},
1867518743
/**
1867618744
* Update individual fields of a learning path
1867718745
* @summary Update
@@ -18917,6 +18985,19 @@ export const LearningpathsApiFactory = function (
1891718985
)
1891818986
.then((request) => request(axios, basePath))
1891918987
},
18988+
/**
18989+
* Get a list of all learning path items
18990+
* @summary List
18991+
* @param {*} [options] Override http request option.
18992+
* @throws {RequiredError}
18993+
*/
18994+
learningpathsMembershipList(
18995+
options?: RawAxiosRequestConfig,
18996+
): AxiosPromise<Array<MicroLearningPathRelationship>> {
18997+
return localVarFp
18998+
.learningpathsMembershipList(options)
18999+
.then((request) => request(axios, basePath))
19000+
},
1892019001
/**
1892119002
* Update individual fields of a learning path
1892219003
* @summary Update
@@ -19456,6 +19537,19 @@ export class LearningpathsApi extends BaseAPI {
1945619537
.then((request) => request(this.axios, this.basePath))
1945719538
}
1945819539

19540+
/**
19541+
* Get a list of all learning path items
19542+
* @summary List
19543+
* @param {*} [options] Override http request option.
19544+
* @throws {RequiredError}
19545+
* @memberof LearningpathsApi
19546+
*/
19547+
public learningpathsMembershipList(options?: RawAxiosRequestConfig) {
19548+
return LearningpathsApiFp(this.configuration)
19549+
.learningpathsMembershipList(options)
19550+
.then((request) => request(this.axios, this.basePath))
19551+
}
19552+
1945919553
/**
1946019554
* Update individual fields of a learning path
1946119555
* @summary Update
@@ -24126,6 +24220,45 @@ export const UserlistsApiAxiosParamCreator = function (
2412624220
options: localVarRequestOptions,
2412724221
}
2412824222
},
24223+
/**
24224+
* Get a list of all userlist items for a user
24225+
* @summary List
24226+
* @param {*} [options] Override http request option.
24227+
* @throws {RequiredError}
24228+
*/
24229+
userlistsMembershipList: async (
24230+
options: RawAxiosRequestConfig = {},
24231+
): Promise<RequestArgs> => {
24232+
const localVarPath = `/api/v1/userlists/membership/`
24233+
// use dummy base URL string because the URL constructor only accepts absolute URLs.
24234+
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL)
24235+
let baseOptions
24236+
if (configuration) {
24237+
baseOptions = configuration.baseOptions
24238+
}
24239+
24240+
const localVarRequestOptions = {
24241+
method: "GET",
24242+
...baseOptions,
24243+
...options,
24244+
}
24245+
const localVarHeaderParameter = {} as any
24246+
const localVarQueryParameter = {} as any
24247+
24248+
setSearchParams(localVarUrlObj, localVarQueryParameter)
24249+
let headersFromBaseOptions =
24250+
baseOptions && baseOptions.headers ? baseOptions.headers : {}
24251+
localVarRequestOptions.headers = {
24252+
...localVarHeaderParameter,
24253+
...headersFromBaseOptions,
24254+
...options.headers,
24255+
}
24256+
24257+
return {
24258+
url: toPathString(localVarUrlObj),
24259+
options: localVarRequestOptions,
24260+
}
24261+
},
2412924262
/**
2413024263
* Viewset for UserLists
2413124264
* @summary Update
@@ -24504,6 +24637,33 @@ export const UserlistsApiFp = function (configuration?: Configuration) {
2450424637
configuration,
2450524638
)(axios, operationBasePath || basePath)
2450624639
},
24640+
/**
24641+
* Get a list of all userlist items for a user
24642+
* @summary List
24643+
* @param {*} [options] Override http request option.
24644+
* @throws {RequiredError}
24645+
*/
24646+
async userlistsMembershipList(
24647+
options?: RawAxiosRequestConfig,
24648+
): Promise<
24649+
(
24650+
axios?: AxiosInstance,
24651+
basePath?: string,
24652+
) => AxiosPromise<Array<MicroUserListRelationship>>
24653+
> {
24654+
const localVarAxiosArgs =
24655+
await localVarAxiosParamCreator.userlistsMembershipList(options)
24656+
const index = configuration?.serverIndex ?? 0
24657+
const operationBasePath =
24658+
operationServerMap["UserlistsApi.userlistsMembershipList"]?.[index]?.url
24659+
return (axios, basePath) =>
24660+
createRequestFunction(
24661+
localVarAxiosArgs,
24662+
globalAxios,
24663+
BASE_PATH,
24664+
configuration,
24665+
)(axios, operationBasePath || basePath)
24666+
},
2450724667
/**
2450824668
* Viewset for UserLists
2450924669
* @summary Update
@@ -24722,6 +24882,19 @@ export const UserlistsApiFactory = function (
2472224882
)
2472324883
.then((request) => request(axios, basePath))
2472424884
},
24885+
/**
24886+
* Get a list of all userlist items for a user
24887+
* @summary List
24888+
* @param {*} [options] Override http request option.
24889+
* @throws {RequiredError}
24890+
*/
24891+
userlistsMembershipList(
24892+
options?: RawAxiosRequestConfig,
24893+
): AxiosPromise<Array<MicroUserListRelationship>> {
24894+
return localVarFp
24895+
.userlistsMembershipList(options)
24896+
.then((request) => request(axios, basePath))
24897+
},
2472524898
/**
2472624899
* Viewset for UserLists
2472724900
* @summary Update
@@ -25127,6 +25300,19 @@ export class UserlistsApi extends BaseAPI {
2512725300
.then((request) => request(this.axios, this.basePath))
2512825301
}
2512925302

25303+
/**
25304+
* Get a list of all userlist items for a user
25305+
* @summary List
25306+
* @param {*} [options] Override http request option.
25307+
* @throws {RequiredError}
25308+
* @memberof UserlistsApi
25309+
*/
25310+
public userlistsMembershipList(options?: RawAxiosRequestConfig) {
25311+
return UserlistsApiFp(this.configuration)
25312+
.userlistsMembershipList(options)
25313+
.then((request) => request(this.axios, this.basePath))
25314+
}
25315+
2513025316
/**
2513125317
* Viewset for UserLists
2513225318
* @summary Update

frontends/api/src/hooks/learningResources/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,5 @@ export {
531531
useListItemMove,
532532
usePlatformsList,
533533
useSchoolsList,
534-
/*
535-
* Not intended to be imported except for special cases.
536-
* It's used in the ResourceCarousel to dynamically build a single useQueries hook
537-
* from config because a React component cannot conditionally call hooks during renders.
538-
*/
539534
learningResources,
540535
}

frontends/api/src/ssr/usePrefetchWarnings.test.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ describe("SSR prefetch warnings", () => {
2222
jest.spyOn(console, "table").mockImplementation(() => {})
2323
})
2424

25-
afterEach(() => {
26-
jest.clearAllMocks()
27-
})
28-
2925
it("Warns if a query is requested on the client that has not been prefetched", async () => {
3026
const { wrapper, queryClient } = setupReactQueryTest()
3127

@@ -46,14 +42,12 @@ describe("SSR prefetch warnings", () => {
4642
)
4743
expect(console.table).toHaveBeenCalledWith(
4844
[
49-
{
45+
expect.objectContaining({
5046
disabled: false,
51-
hash: '["learningResources","detail",1]',
5247
initialStatus: "loading",
53-
key: ["learningResources", "detail", 1],
48+
key: learningResources.detail(1).queryKey,
5449
observerCount: 1,
55-
status: "loading",
56-
},
50+
}),
5751
],
5852
["hash", "initialStatus", "status", "observerCount", "disabled"],
5953
)
@@ -71,7 +65,7 @@ describe("SSR prefetch warnings", () => {
7165
wrapper,
7266
initialProps: {
7367
queryClient,
74-
exemptions: [["learningResources", "detail", 1]],
68+
exemptions: [learningResources.detail(1).queryKey],
7569
},
7670
})
7771

@@ -111,9 +105,9 @@ describe("SSR prefetch warnings", () => {
111105
[
112106
{
113107
disabled: false,
114-
hash: '["learningResources","detail",1]',
108+
hash: JSON.stringify(learningResources.detail(1).queryKey),
115109
initialStatus: "success",
116-
key: ["learningResources", "detail", 1],
110+
key: learningResources.detail(1).queryKey,
117111
observerCount: 0,
118112
status: "success",
119113
},

frontends/main/src/app-pages/SearchPage/SearchPage.test.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,32 @@ describe("Search Page Tabs", () => {
491491
expect(params2.get("department")).toBe("8") // should preserve other params
492492
})
493493

494+
test("Switching from learning materials tab clears resource type only", async () => {
495+
setMockApiResponses({
496+
search: {
497+
count: 1000,
498+
metadata: {
499+
aggregations: {
500+
resource_type: [{ key: "video", doc_count: 100 }],
501+
},
502+
suggestions: [],
503+
},
504+
},
505+
})
506+
const { location } = renderWithProviders(<SearchPage />, {
507+
url: "?resource_category=learning_material&resource_type=video&topic=Biology",
508+
})
509+
const tabLM = screen.getByRole("tab", { name: /Learning Materials/ })
510+
const tabCourses = screen.getByRole("tab", { name: /Courses/ })
511+
expect(tabLM).toHaveAttribute("aria-selected")
512+
513+
// Click "Courses"
514+
await user.click(tabCourses)
515+
expect(location.current.search).toBe(
516+
"?resource_category=course&topic=Biology",
517+
)
518+
})
519+
494520
test("Tab titles show corret result counts", async () => {
495521
setMockApiResponses({
496522
search: {

frontends/main/src/app/page.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,6 @@ const Page: React.FC = async () => {
6767
learningResources.topics({ is_toplevel: true }),
6868

6969
testimonials.list({ position: 1 }),
70-
newsEvents.list({
71-
feed_type: [NewsEventsListFeedTypeEnum.News],
72-
limit: 6,
73-
sortby: "-news_date",
74-
}),
7570
newsEvents.list({
7671
feed_type: [NewsEventsListFeedTypeEnum.Events],
7772
limit: 5,

frontends/main/src/page-components/SearchDisplay/ResourceCategoryTabs.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ const ResourceCategoryTabList: React.FC<ResourceCategoryTabsProps> = ({
9494
const tab = tabs.find((t) => t.name === value)
9595
setSearchParams((prev) => {
9696
const next = new URLSearchParams(prev)
97+
if (prev.get("resource_category") === "learning_material") {
98+
next.delete("resource_type")
99+
}
97100
if (tab?.resource_category) {
98101
next.set("resource_category", tab.resource_category)
99102
} else {

frontends/ol-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"validator": "^13.11.0"
4646
},
4747
"devDependencies": {
48-
"@chromatic-com/storybook": "^1.9.0",
48+
"@chromatic-com/storybook": "^3.0.0",
4949
"@faker-js/faker": "^9.0.0",
5050
"@storybook/addon-actions": "^8.2.9",
5151
"@storybook/addon-essentials": "^8.2.9",

0 commit comments

Comments
 (0)