diff --git a/src/app/features/my-profile/store/my-profile.model.ts b/src/app/features/my-profile/store/my-profile.model.ts index 715b6dea7..82327707f 100644 --- a/src/app/features/my-profile/store/my-profile.model.ts +++ b/src/app/features/my-profile/store/my-profile.model.ts @@ -1,8 +1,9 @@ import { ResourceTab } from '@osf/shared/enums/resource-tab.enum'; import { Resource } from '@osf/shared/models/resource-card/resource.model'; +import { AsyncStateModel } from '@shared/models'; export interface MyProfileStateModel { - resources: Resource[]; + resources: AsyncStateModel; resourcesCount: number; searchText: string; sortBy: string; diff --git a/src/app/features/my-profile/store/my-profile.selectors.ts b/src/app/features/my-profile/store/my-profile.selectors.ts index c3150813e..5620baa18 100644 --- a/src/app/features/my-profile/store/my-profile.selectors.ts +++ b/src/app/features/my-profile/store/my-profile.selectors.ts @@ -8,7 +8,7 @@ import { Resource } from '@osf/shared/models/resource-card/resource.model'; export class MyProfileSelectors { @Selector([MyProfileState]) static getResources(state: MyProfileStateModel): Resource[] { - return state.resources; + return state.resources.data; } @Selector([MyProfileState]) diff --git a/src/app/features/my-profile/store/my-profile.state.ts b/src/app/features/my-profile/store/my-profile.state.ts index 211e87d27..50df360e0 100644 --- a/src/app/features/my-profile/store/my-profile.state.ts +++ b/src/app/features/my-profile/store/my-profile.state.ts @@ -46,7 +46,7 @@ export class MyProfileState { return this.searchService.getResources(filtersParams, searchText, sortBy, resourceTypes).pipe( tap((response) => { - ctx.patchState({ resources: response.resources }); + ctx.patchState({ resources: { data: response.resources, isLoading: false, error: null } }); ctx.patchState({ resourcesCount: response.count }); ctx.patchState({ first: response.first }); ctx.patchState({ next: response.next }); @@ -59,7 +59,7 @@ export class MyProfileState { getResourcesByLink(ctx: StateContext, action: GetResourcesByLink) { return this.searchService.getResourcesByLink(action.link).pipe( tap((response) => { - ctx.patchState({ resources: response.resources }); + ctx.patchState({ resources: { data: response.resources, isLoading: false, error: null } }); ctx.patchState({ resourcesCount: response.count }); ctx.patchState({ first: response.first }); ctx.patchState({ next: response.next }); diff --git a/src/app/features/search/store/search.model.ts b/src/app/features/search/store/search.model.ts index a74bd4559..73b302a78 100644 --- a/src/app/features/search/store/search.model.ts +++ b/src/app/features/search/store/search.model.ts @@ -1,8 +1,8 @@ import { ResourceTab } from '@osf/shared/enums'; -import { Resource } from '@osf/shared/models'; +import { AsyncStateModel, Resource } from '@osf/shared/models'; export interface SearchStateModel { - resources: Resource[]; + resources: AsyncStateModel; resourcesCount: number; searchText: string; sortBy: string; diff --git a/src/app/features/search/store/search.selectors.ts b/src/app/features/search/store/search.selectors.ts index eadac910b..509723211 100644 --- a/src/app/features/search/store/search.selectors.ts +++ b/src/app/features/search/store/search.selectors.ts @@ -9,7 +9,7 @@ import { SearchState } from './search.state'; export class SearchSelectors { @Selector([SearchState]) static getResources(state: SearchStateModel): Resource[] { - return state.resources; + return state.resources.data; } @Selector([SearchState]) diff --git a/src/app/features/search/store/search.state.ts b/src/app/features/search/store/search.state.ts index a3d96ec72..acafd4167 100644 --- a/src/app/features/search/store/search.state.ts +++ b/src/app/features/search/store/search.state.ts @@ -1,6 +1,6 @@ -import { Action, State, StateContext, Store } from '@ngxs/store'; +import { Action, NgxsOnInit, State, StateContext, Store } from '@ngxs/store'; -import { tap } from 'rxjs'; +import { BehaviorSubject, EMPTY, switchMap, tap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; @@ -27,35 +27,49 @@ import { SearchSelectors } from './search.selectors'; name: 'search', defaults: searchStateDefaults, }) -export class SearchState { +export class SearchState implements NgxsOnInit { searchService = inject(SearchService); store = inject(Store); + loadRequests = new BehaviorSubject(null); - @Action(GetResources) - getResources(ctx: StateContext) { - const filters = this.store.selectSnapshot(ResourceFiltersSelectors.getAllFilters); - const filtersParams = addFiltersParams(filters); - const searchText = this.store.selectSnapshot(SearchSelectors.getSearchText); - const sortBy = this.store.selectSnapshot(SearchSelectors.getSortBy); - const resourceTab = this.store.selectSnapshot(SearchSelectors.getResourceTab); - const resourceTypes = getResourceTypes(resourceTab); + ngxsOnInit(ctx: StateContext): void { + this.loadRequests + .pipe( + switchMap((query) => { + if (!query) return EMPTY; + const state = ctx.getState(); + ctx.patchState({ resources: { ...state.resources, isLoading: true } }); + const filters = this.store.selectSnapshot(ResourceFiltersSelectors.getAllFilters); + const filtersParams = addFiltersParams(filters); + const searchText = this.store.selectSnapshot(SearchSelectors.getSearchText); + const sortBy = this.store.selectSnapshot(SearchSelectors.getSortBy); + const resourceTab = this.store.selectSnapshot(SearchSelectors.getResourceTab); + const resourceTypes = getResourceTypes(resourceTab); - return this.searchService.getResources(filtersParams, searchText, sortBy, resourceTypes).pipe( - tap((response) => { - ctx.patchState({ resources: response.resources }); - ctx.patchState({ resourcesCount: response.count }); - ctx.patchState({ first: response.first }); - ctx.patchState({ next: response.next }); - ctx.patchState({ previous: response.previous }); - }) - ); + return this.searchService.getResources(filtersParams, searchText, sortBy, resourceTypes).pipe( + tap((response) => { + ctx.patchState({ resources: { data: response.resources, isLoading: false, error: null } }); + ctx.patchState({ resourcesCount: response.count }); + ctx.patchState({ first: response.first }); + ctx.patchState({ next: response.next }); + ctx.patchState({ previous: response.previous }); + }) + ); + }) + ) + .subscribe(); + } + + @Action(GetResources) + getResources() { + this.loadRequests.next(true); } @Action(GetResourcesByLink) getResourcesByLink(ctx: StateContext, action: GetResourcesByLink) { return this.searchService.getResourcesByLink(action.link).pipe( tap((response) => { - ctx.patchState({ resources: response.resources }); + ctx.patchState({ resources: { data: response.resources, isLoading: false, error: null } }); ctx.patchState({ resourcesCount: response.count }); ctx.patchState({ first: response.first }); ctx.patchState({ next: response.next }); diff --git a/src/app/features/search/utils/data.ts b/src/app/features/search/utils/data.ts index 5d8d09dac..0e89de1a1 100644 --- a/src/app/features/search/utils/data.ts +++ b/src/app/features/search/utils/data.ts @@ -1,7 +1,11 @@ import { ResourceTab } from '@osf/shared/enums/resource-tab.enum'; export const searchStateDefaults = { - resources: [], + resources: { + data: [], + isLoading: false, + error: null, + }, resourcesCount: 0, searchText: '', sortBy: '-relevance',