diff --git a/src/app/core/interceptors/auth.interceptor.ts b/src/app/core/interceptors/auth.interceptor.ts index c70348470..108fbd579 100644 --- a/src/app/core/interceptors/auth.interceptor.ts +++ b/src/app/core/interceptors/auth.interceptor.ts @@ -15,7 +15,7 @@ export const authInterceptor: HttpInterceptorFn = ( if (!req.url.includes('/api.crossref.org/funders')) { const headers: Record = { - Accept: req.responseType === 'text' ? '*/*' : 'application/vnd.api+json', + Accept: req.responseType === 'text' ? '*/*' : 'application/vnd.api+json;version=2.20', 'Content-Type': 'application/vnd.api+json', }; diff --git a/src/app/core/models/json-api.model.ts b/src/app/core/models/json-api.model.ts index cdf0c28f6..f1a7ff950 100644 --- a/src/app/core/models/json-api.model.ts +++ b/src/app/core/models/json-api.model.ts @@ -7,10 +7,10 @@ export interface JsonApiResponseWithMeta extends JsonApiRe meta: Meta; } -export interface JsonApiResponseWithPaging extends JsonApiResponse { - links: { - meta: MetaJsonApi; - }; +export interface ResponseJsonApi { + data: Data; + links: PaginationLinksJsonApi; + meta: MetaJsonApi; } export interface ApiData { diff --git a/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.spec.ts b/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.spec.ts index aad25fc66..3f079b1d8 100644 --- a/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.spec.ts +++ b/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.spec.ts @@ -13,6 +13,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { UserState } from '@core/store/user'; import { AdminTableComponent } from '@osf/features/admin-institutions/components'; import { InstitutionsAdminState } from '@osf/features/admin-institutions/store'; +import { ToastService } from '@osf/shared/services'; import { LoadingSpinnerComponent, SelectComponent } from '@shared/components'; import { TranslateServiceMock } from '@shared/mocks'; @@ -33,6 +34,7 @@ describe('InstitutionsUsersComponent', () => { MockProvider(ActivatedRoute, { queryParams: of({}) }), MockProvider(Router), TranslateServiceMock, + MockProvider(ToastService), provideStore([InstitutionsAdminState, UserState]), provideHttpClient(), provideHttpClientTesting(), diff --git a/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts b/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts index f6f6e2618..afa6a847c 100644 --- a/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts +++ b/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts @@ -36,6 +36,7 @@ import { } from '@osf/features/admin-institutions/store/institutions-admin.actions'; import { InstitutionsAdminSelectors } from '@osf/features/admin-institutions/store/institutions-admin.selectors'; import { LoadingSpinnerComponent, SelectComponent } from '@osf/shared/components'; +import { ToastService } from '@osf/shared/services'; import { TABLE_PARAMS } from '@shared/constants'; import { SortOrder } from '@shared/enums'; import { QueryParams } from '@shared/models'; @@ -63,6 +64,7 @@ export class InstitutionsUsersComponent implements OnInit { private readonly translate = inject(TranslateService); private readonly dialogService = inject(DialogService); private readonly destroyRef = inject(DestroyRef); + private readonly toastService = inject(ToastService); private readonly actions = createDispatchMap({ fetchInstitutionUsers: FetchInstitutionUsers, @@ -268,12 +270,14 @@ export class InstitutionsUsersComponent implements OnInit { private sendEmailToUser(userRowData: TableCellData, emailData: SendEmailDialogData): void { const userId = (userRowData['userLink'] as TableCellLink).text as string; - this.actions.sendUserMessage( - userId, - this.institutionId, - emailData.emailContent, - emailData.ccSender, - emailData.allowReplyToSender - ); + this.actions + .sendUserMessage( + userId, + this.institutionId, + emailData.emailContent, + emailData.ccSender, + emailData.allowReplyToSender + ) + .subscribe(() => this.toastService.showSuccess('adminInstitutions.institutionUsers.messageSent')); } } diff --git a/src/app/features/admin-institutions/services/institutions-admin.service.ts b/src/app/features/admin-institutions/services/institutions-admin.service.ts index 78969dd50..6db0db40c 100644 --- a/src/app/features/admin-institutions/services/institutions-admin.service.ts +++ b/src/app/features/admin-institutions/services/institutions-admin.service.ts @@ -110,7 +110,7 @@ export class InstitutionsAdminService { const payload = sendMessageRequestMapper(request); return this.jsonApiService.post( - `${environment.apiUrl}/institutions/messages/`, + `${environment.apiUrl}/users/${request.userId}/messages/`, payload ); } diff --git a/src/app/features/admin-institutions/store/institutions-admin.actions.ts b/src/app/features/admin-institutions/store/institutions-admin.actions.ts index 0d74548e7..85bb41615 100644 --- a/src/app/features/admin-institutions/store/institutions-admin.actions.ts +++ b/src/app/features/admin-institutions/store/institutions-admin.actions.ts @@ -1,3 +1,8 @@ +export class FetchInstitutionById { + static readonly type = '[InstitutionsAdmin] Fetch Institution By Id'; + constructor(public institutionId: string) {} +} + export class FetchInstitutionDepartments { static readonly type = '[InstitutionsAdmin] Fetch Institution Departments'; constructor(public institutionId: string) {} diff --git a/src/app/features/admin-institutions/store/institutions-admin.model.ts b/src/app/features/admin-institutions/store/institutions-admin.model.ts index fc3588d2b..ed0bc1f3f 100644 --- a/src/app/features/admin-institutions/store/institutions-admin.model.ts +++ b/src/app/features/admin-institutions/store/institutions-admin.model.ts @@ -1,4 +1,4 @@ -import { AsyncStateModel, AsyncStateWithLinksModel, AsyncStateWithTotalCount } from '@shared/models'; +import { AsyncStateModel, AsyncStateWithLinksModel, AsyncStateWithTotalCount, Institution } from '@shared/models'; import { InstitutionDepartment, @@ -24,4 +24,21 @@ export interface InstitutionsAdminModel { sendMessage: AsyncStateModel; selectedInstitutionId: string | null; currentSearchPropertyPath: string | null; + institution: AsyncStateModel; } + +export const INSTITUTIONS_ADMIN_STATE_DEFAULTS: InstitutionsAdminModel = { + departments: { data: [], isLoading: false, error: null }, + summaryMetrics: { data: {} as InstitutionSummaryMetrics, isLoading: false, error: null }, + hasOsfAddonSearch: { data: [], isLoading: false, error: null }, + storageRegionSearch: { data: [], isLoading: false, error: null }, + searchResults: { data: [], isLoading: false, error: null }, + users: { data: [], totalCount: 0, isLoading: false, error: null }, + projects: { data: [], totalCount: 0, isLoading: false, error: null, links: undefined }, + registrations: { data: [], totalCount: 0, isLoading: false, error: null, links: undefined }, + preprints: { data: [], totalCount: 0, isLoading: false, error: null, links: undefined }, + sendMessage: { data: null, isLoading: false, error: null }, + selectedInstitutionId: null, + currentSearchPropertyPath: null, + institution: { data: {} as Institution, isLoading: false, error: null }, +}; diff --git a/src/app/features/admin-institutions/store/institutions-admin.state.ts b/src/app/features/admin-institutions/store/institutions-admin.state.ts index 312a54c52..8e831decd 100644 --- a/src/app/features/admin-institutions/store/institutions-admin.state.ts +++ b/src/app/features/admin-institutions/store/institutions-admin.state.ts @@ -1,16 +1,20 @@ import { Action, State, StateContext } from '@ngxs/store'; +import { patch } from '@ngxs/store/operators'; import { catchError, tap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; import { handleSectionError } from '@core/handlers'; +import { Institution } from '@osf/shared/models'; +import { InstitutionsService } from '@osf/shared/services'; -import { InstitutionPreprint, InstitutionProject, InstitutionRegistration, InstitutionSummaryMetrics } from '../models'; +import { InstitutionPreprint, InstitutionProject, InstitutionRegistration } from '../models'; import { InstitutionsAdminService } from '../services/institutions-admin.service'; import { FetchHasOsfAddonSearch, + FetchInstitutionById, FetchInstitutionDepartments, FetchInstitutionSearchResults, FetchInstitutionSummaryMetrics, @@ -21,29 +25,33 @@ import { FetchStorageRegionSearch, SendUserMessage, } from './institutions-admin.actions'; -import { InstitutionsAdminModel } from './institutions-admin.model'; +import { INSTITUTIONS_ADMIN_STATE_DEFAULTS, InstitutionsAdminModel } from './institutions-admin.model'; @State({ name: 'institutionsAdmin', - defaults: { - departments: { data: [], isLoading: false, error: null }, - summaryMetrics: { data: {} as InstitutionSummaryMetrics, isLoading: false, error: null }, - hasOsfAddonSearch: { data: [], isLoading: false, error: null }, - storageRegionSearch: { data: [], isLoading: false, error: null }, - searchResults: { data: [], isLoading: false, error: null }, - users: { data: [], totalCount: 0, isLoading: false, error: null }, - projects: { data: [], totalCount: 0, isLoading: false, error: null, links: undefined }, - registrations: { data: [], totalCount: 0, isLoading: false, error: null, links: undefined }, - preprints: { data: [], totalCount: 0, isLoading: false, error: null, links: undefined }, - sendMessage: { data: null, isLoading: false, error: null }, - selectedInstitutionId: null, - currentSearchPropertyPath: null, - }, + defaults: INSTITUTIONS_ADMIN_STATE_DEFAULTS, }) @Injectable() export class InstitutionsAdminState { + private readonly institutionsService = inject(InstitutionsService); private readonly institutionsAdminService = inject(InstitutionsAdminService); + @Action(FetchInstitutionById) + fetchInstitutionById(ctx: StateContext, action: FetchInstitutionById) { + ctx.patchState({ institution: { data: {} as Institution, isLoading: true, error: null } }); + + return this.institutionsService.getInstitutionById(action.institutionId).pipe( + tap((response) => { + ctx.setState( + patch({ + institution: patch({ data: response, error: null, isLoading: false }), + }) + ); + }), + catchError((error) => handleSectionError(ctx, 'institution', error)) + ); + } + @Action(FetchInstitutionDepartments) fetchDepartments(ctx: StateContext, action: FetchInstitutionDepartments) { const state = ctx.getState(); diff --git a/src/app/features/meetings/mappers/meetings.mapper.ts b/src/app/features/meetings/mappers/meetings.mapper.ts index d17e04a58..7b75c276f 100644 --- a/src/app/features/meetings/mappers/meetings.mapper.ts +++ b/src/app/features/meetings/mappers/meetings.mapper.ts @@ -1,4 +1,4 @@ -import { JsonApiResponseWithPaging } from '@core/models'; +import { ResponseJsonApi } from '@core/models'; import { MeetingGetResponseJsonApi, @@ -8,9 +8,7 @@ import { } from '../models'; export class MeetingsMapper { - static fromMeetingsGetResponse( - response: JsonApiResponseWithPaging - ): MeetingsWithPaging { + static fromMeetingsGetResponse(response: ResponseJsonApi): MeetingsWithPaging { return { data: response.data.map((item) => ({ id: item.id, @@ -20,12 +18,12 @@ export class MeetingsMapper { endDate: item.attributes.end_date, submissionsCount: item.attributes.submissions_count, })), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } static fromMeetingSubmissionGetResponse( - response: JsonApiResponseWithPaging + response: ResponseJsonApi ): MeetingSubmissionsWithPaging { return { data: response.data.map((item) => ({ @@ -37,7 +35,7 @@ export class MeetingsMapper { meetingCategory: item.attributes.meeting_category, downloadLink: item.links.download, })), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } diff --git a/src/app/features/meetings/services/meetings.service.ts b/src/app/features/meetings/services/meetings.service.ts index a95c22357..34835e343 100644 --- a/src/app/features/meetings/services/meetings.service.ts +++ b/src/app/features/meetings/services/meetings.service.ts @@ -3,7 +3,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; import { JsonApiService } from '@core/services'; -import { JsonApiResponse, JsonApiResponseWithPaging } from '@osf/core/models'; +import { JsonApiResponse, ResponseJsonApi } from '@osf/core/models'; import { MeetingsMapper } from '@osf/features/meetings/mappers'; import { MeetingGetResponseJsonApi, @@ -35,7 +35,7 @@ export class MeetingsService { ); return this.jsonApiService - .get>(this.baseUrl, params) + .get>(this.baseUrl, params) .pipe(map((response) => MeetingsMapper.fromMeetingsGetResponse(response))); } @@ -54,9 +54,7 @@ export class MeetingsService { ); return this.jsonApiService - .get< - JsonApiResponseWithPaging - >(`${this.baseUrl}${meetingId}/submissions/`, params) + .get>(`${this.baseUrl}${meetingId}/submissions/`, params) .pipe(map((response) => MeetingsMapper.fromMeetingSubmissionGetResponse(response))); } diff --git a/src/app/features/moderation/mappers/moderation.mapper.ts b/src/app/features/moderation/mappers/moderation.mapper.ts index d039bfa90..0cb94cc26 100644 --- a/src/app/features/moderation/mappers/moderation.mapper.ts +++ b/src/app/features/moderation/mappers/moderation.mapper.ts @@ -1,4 +1,4 @@ -import { JsonApiResponseWithPaging, UserGetResponse } from '@osf/core/models'; +import { ResponseJsonApi, UserGetResponse } from '@osf/core/models'; import { PaginatedData } from '@osf/shared/models'; import { AddModeratorType, ModeratorPermission } from '../enums'; @@ -17,7 +17,7 @@ export class ModerationMapper { } static fromUsersWithPaginationGetResponse( - response: JsonApiResponseWithPaging + response: ResponseJsonApi ): PaginatedData { return { data: response.data.map( @@ -28,7 +28,7 @@ export class ModerationMapper { permission: ModeratorPermission.Moderator, }) as ModeratorAddModel ), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } diff --git a/src/app/features/moderation/mappers/preprint-moderation.mapper.ts b/src/app/features/moderation/mappers/preprint-moderation.mapper.ts index 9de8de171..6ce0bdeff 100644 --- a/src/app/features/moderation/mappers/preprint-moderation.mapper.ts +++ b/src/app/features/moderation/mappers/preprint-moderation.mapper.ts @@ -1,4 +1,4 @@ -import { JsonApiResponseWithPaging } from '@osf/core/models'; +import { ResponseJsonApi } from '@osf/core/models'; import { PaginatedData } from '@osf/shared/models'; import { @@ -35,11 +35,11 @@ export class PreprintModerationMapper { } static fromResponseWithPagination( - response: JsonApiResponseWithPaging + response: ResponseJsonApi ): PaginatedData { return { data: response.data.map((x) => this.fromResponse(x)), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } diff --git a/src/app/features/moderation/mappers/registry-moderation.mapper.ts b/src/app/features/moderation/mappers/registry-moderation.mapper.ts index 0b12c1ea2..c101c3082 100644 --- a/src/app/features/moderation/mappers/registry-moderation.mapper.ts +++ b/src/app/features/moderation/mappers/registry-moderation.mapper.ts @@ -26,7 +26,7 @@ export class RegistryModerationMapper { static fromResponseWithPagination(response: RegistryResponseJsonApi): PaginatedData { return { data: response.data.map((x) => this.fromResponse(x)), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } diff --git a/src/app/features/moderation/models/registry-json-api.model.ts b/src/app/features/moderation/models/registry-json-api.model.ts index 664919ee5..6cfa6dd82 100644 --- a/src/app/features/moderation/models/registry-json-api.model.ts +++ b/src/app/features/moderation/models/registry-json-api.model.ts @@ -1,7 +1,7 @@ -import { JsonApiResponseWithPaging } from '@osf/core/models'; +import { ResponseJsonApi } from '@osf/core/models'; import { RegistrationReviewStates, RevisionReviewStates } from '@osf/shared/enums'; -export type RegistryResponseJsonApi = JsonApiResponseWithPaging; +export type RegistryResponseJsonApi = ResponseJsonApi; export interface RegistryDataJsonApi { id: string; diff --git a/src/app/features/moderation/services/moderators.service.ts b/src/app/features/moderation/services/moderators.service.ts index 5e4e6c302..dd3248450 100644 --- a/src/app/features/moderation/services/moderators.service.ts +++ b/src/app/features/moderation/services/moderators.service.ts @@ -2,7 +2,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; -import { JsonApiResponse, JsonApiResponseWithPaging, UserGetResponse } from '@osf/core/models'; +import { JsonApiResponse, ResponseJsonApi, UserGetResponse } from '@osf/core/models'; import { JsonApiService } from '@osf/core/services'; import { ResourceType } from '@osf/shared/enums'; import { PaginatedData } from '@osf/shared/models'; @@ -63,7 +63,7 @@ export class ModeratorsService { const baseUrl = `${environment.apiUrl}/users/?filter[full_name]=${value}&page=${page}`; return this.jsonApiService - .get>(baseUrl) + .get>(baseUrl) .pipe(map((response) => ModerationMapper.fromUsersWithPaginationGetResponse(response))); } } diff --git a/src/app/features/moderation/services/preprint-moderation.service.ts b/src/app/features/moderation/services/preprint-moderation.service.ts index 99c56f658..6d8f253f2 100644 --- a/src/app/features/moderation/services/preprint-moderation.service.ts +++ b/src/app/features/moderation/services/preprint-moderation.service.ts @@ -2,7 +2,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; -import { JsonApiResponse, JsonApiResponseWithPaging } from '@osf/core/models'; +import { JsonApiResponse, ResponseJsonApi } from '@osf/core/models'; import { JsonApiService } from '@osf/core/services'; import { PaginatedData } from '@osf/shared/models'; @@ -49,7 +49,7 @@ export class PreprintModerationService { const baseUrl = `${environment.apiUrl}/actions/reviews/?embed=provider&embed=target&page=${page}`; return this.jsonApiService - .get>(baseUrl) + .get>(baseUrl) .pipe(map((response) => PreprintModerationMapper.fromResponseWithPagination(response))); } diff --git a/src/app/features/preprints/mappers/preprints.mapper.ts b/src/app/features/preprints/mappers/preprints.mapper.ts index 2adab1cc6..d6410f715 100644 --- a/src/app/features/preprints/mappers/preprints.mapper.ts +++ b/src/app/features/preprints/mappers/preprints.mapper.ts @@ -1,4 +1,4 @@ -import { ApiData, JsonApiResponseWithMeta, JsonApiResponseWithPaging } from '@core/models'; +import { ApiData, JsonApiResponseWithMeta, ResponseJsonApi } from '@core/models'; import { Preprint, PreprintAttributesJsonApi, @@ -155,9 +155,8 @@ export class PreprintsMapper { } static fromMyPreprintJsonApi( - response: JsonApiResponseWithPaging< - ApiData[], - null + response: ResponseJsonApi< + ApiData[] > ): PreprintShortInfoWithTotalCount { return { @@ -175,7 +174,7 @@ export class PreprintsMapper { providerId: preprintData.relationships.provider.data.id, }; }), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } } diff --git a/src/app/features/preprints/services/preprints.service.ts b/src/app/features/preprints/services/preprints.service.ts index 88952827f..bb42356e7 100644 --- a/src/app/features/preprints/services/preprints.service.ts +++ b/src/app/features/preprints/services/preprints.service.ts @@ -3,7 +3,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; import { JsonApiService } from '@core/services'; -import { ApiData, JsonApiResponse, JsonApiResponseWithMeta, JsonApiResponseWithPaging } from '@osf/core/models'; +import { ApiData, JsonApiResponse, JsonApiResponseWithMeta, ResponseJsonApi } from '@osf/core/models'; import { RegistryModerationMapper } from '@osf/features/moderation/mappers'; import { ReviewActionsResponseJsonApi } from '@osf/features/moderation/models'; import { preprintSortFieldMap } from '@osf/features/preprints/constants'; @@ -150,7 +150,7 @@ export class PreprintsService { getPreprintVersionIds(preprintId: string): Observable { return this.jsonApiService .get< - JsonApiResponseWithPaging[], null> + ResponseJsonApi[]> >(`${environment.apiUrl}/preprints/${preprintId}/versions/`) .pipe(map((response) => response.data.map((data) => data.id))); } @@ -166,10 +166,7 @@ export class PreprintsService { return this.jsonApiService .get< - JsonApiResponseWithPaging< - ApiData[], - null - > + ResponseJsonApi[]> >(`${environment.apiUrl}/users/me/preprints/`, params) .pipe(map((response) => PreprintsMapper.fromMyPreprintJsonApi(response))); } diff --git a/src/app/features/project/metadata/models/cedar-metadata-template.models.ts b/src/app/features/project/metadata/models/cedar-metadata-template.models.ts index 75044e300..ea2c3d7e3 100644 --- a/src/app/features/project/metadata/models/cedar-metadata-template.models.ts +++ b/src/app/features/project/metadata/models/cedar-metadata-template.models.ts @@ -1,4 +1,4 @@ -import { PaginationLinksJsonApi } from '@osf/core/models'; +import { MetaJsonApi, PaginationLinksJsonApi } from '@osf/core/models'; export interface CedarMetadataDataTemplateJsonApi { id: string; @@ -194,11 +194,7 @@ export interface CedarRecordDataBinding { export interface CedarMetadataRecordJsonApi { data: CedarMetadataRecordData[]; links: PaginationLinksJsonApi; - meta: { - per_page: number; - total: number; - version: string; - }; + meta: MetaJsonApi; } export interface CedarMetadataRecordData { diff --git a/src/app/features/project/metadata/models/metadata.models.ts b/src/app/features/project/metadata/models/metadata.models.ts index ee506cee2..d4fddbf9a 100644 --- a/src/app/features/project/metadata/models/metadata.models.ts +++ b/src/app/features/project/metadata/models/metadata.models.ts @@ -1,3 +1,5 @@ +import { MetaJsonApi } from '@osf/core/models'; + export interface ProjectMetadata { id: string; title: string; @@ -110,12 +112,6 @@ export interface UserInstitutionsResponse { last: string | null; prev: string | null; next: string | null; - meta: { - total: number; - per_page: number; - }; - }; - meta: { - version: string; }; + meta: MetaJsonApi; } diff --git a/src/app/features/project/overview/mappers/project-overview.mapper.ts b/src/app/features/project/overview/mappers/project-overview.mapper.ts index 0e42347b5..5f69d1907 100644 --- a/src/app/features/project/overview/mappers/project-overview.mapper.ts +++ b/src/app/features/project/overview/mappers/project-overview.mapper.ts @@ -35,7 +35,7 @@ export class ProjectOverviewMapper { currentUserIsContributorOrGroupMember: response.attributes.current_user_is_contributor_or_group_member, wikiEnabled: response.attributes.wiki_enabled, customCitation: response.attributes.custom_citation, - subjects: response.attributes.subjects.map((subjectArray) => subjectArray[0]), + subjects: response.attributes.subjects?.map((subjectArray) => subjectArray[0]), contributors: response.embeds.bibliographic_contributors.data.map((contributor) => ({ id: contributor.embeds.users.data.id, familyName: contributor.embeds.users.data.attributes.family_name, diff --git a/src/app/features/project/overview/project-overview.component.ts b/src/app/features/project/overview/project-overview.component.ts index ab91fd96a..1cd079e8b 100644 --- a/src/app/features/project/overview/project-overview.component.ts +++ b/src/app/features/project/overview/project-overview.component.ts @@ -35,7 +35,6 @@ import { ToastService } from '@shared/services'; import { ClearWiki, CollectionsSelectors, - GetAllNodeLinks, GetBookmarksCollectionId, GetCollectionProvider, GetHomeWiki, @@ -108,7 +107,6 @@ export class ProjectOverviewComponent implements OnInit { getHomeWiki: GetHomeWiki, getComponents: GetComponents, getLinkedProjects: GetLinkedResources, - getNodeLinks: GetAllNodeLinks, setProjectCustomCitation: SetProjectCustomCitation, getCollectionProvider: GetCollectionProvider, getCurrentReviewAction: GetSubmissionsReviewActions, @@ -196,7 +194,6 @@ export class ProjectOverviewComponent implements OnInit { this.actions.getBookmarksId(); this.actions.getHomeWiki(ResourceType.Project, projectId); this.actions.getComponents(projectId); - this.actions.getNodeLinks(projectId); this.actions.getLinkedProjects(projectId); } } diff --git a/src/app/features/project/overview/services/project-overview.service.ts b/src/app/features/project/overview/services/project-overview.service.ts index 0740c63a9..b5955818e 100644 --- a/src/app/features/project/overview/services/project-overview.service.ts +++ b/src/app/features/project/overview/services/project-overview.service.ts @@ -17,7 +17,7 @@ import { environment } from 'src/environments/environment'; providedIn: 'root', }) export class ProjectOverviewService { - #jsonApiService = inject(JsonApiService); + private readonly jsonApiService = inject(JsonApiService); getProjectById(projectId: string): Observable { const params: Record = { @@ -35,7 +35,7 @@ export class ProjectOverviewService { related_counts: 'forks,view_only_links', }; - return this.#jsonApiService + return this.jsonApiService .get(`${environment.apiUrl}/nodes/${projectId}/`, params) .pipe(map((response) => ProjectOverviewMapper.fromGetProjectResponse(response.data))); } @@ -51,7 +51,7 @@ export class ProjectOverviewService { }, }; - return this.#jsonApiService.patch(`${environment.apiUrl}/nodes/${projectId}/`, payload); + return this.jsonApiService.patch(`${environment.apiUrl}/nodes/${projectId}/`, payload); } forkResource(projectId: string, resourceType: string): Observable { @@ -61,7 +61,7 @@ export class ProjectOverviewService { }, }; - return this.#jsonApiService.post(`${environment.apiUrl}/${resourceType}/${projectId}/forks/`, payload); + return this.jsonApiService.post(`${environment.apiUrl}/${resourceType}/${projectId}/forks/`, payload); } duplicateProject(projectId: string, title: string): Observable { @@ -76,7 +76,7 @@ export class ProjectOverviewService { }, }; - return this.#jsonApiService.post(`${environment.apiUrl}/nodes/`, payload); + return this.jsonApiService.post(`${environment.apiUrl}/nodes/`, payload); } createComponent( @@ -112,11 +112,11 @@ export class ProjectOverviewService { params['affiliated_institutions'] = affiliatedInstitutions; } - return this.#jsonApiService.post(`${environment.apiUrl}/nodes/${projectId}/children/`, payload, params); + return this.jsonApiService.post(`${environment.apiUrl}/nodes/${projectId}/children/`, payload, params); } deleteComponent(componentId: string): Observable { - return this.#jsonApiService.delete(`${environment.apiUrl}/nodes/${componentId}/`); + return this.jsonApiService.delete(`${environment.apiUrl}/nodes/${componentId}/`); } getComponents(projectId: string): Observable { @@ -125,7 +125,7 @@ export class ProjectOverviewService { 'fields[users]': 'family_name,full_name,given_name,middle_name', }; - return this.#jsonApiService + return this.jsonApiService .get< JsonApiResponse >(`${environment.apiUrl}/nodes/${projectId}/children`, params) diff --git a/src/app/features/project/registrations/services/registrations.service.ts b/src/app/features/project/registrations/services/registrations.service.ts index 706a54f01..3f13c0806 100644 --- a/src/app/features/project/registrations/services/registrations.service.ts +++ b/src/app/features/project/registrations/services/registrations.service.ts @@ -2,7 +2,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; -import { JsonApiResponseWithPaging } from '@osf/core/models'; +import { ResponseJsonApi } from '@osf/core/models'; import { JsonApiService } from '@osf/core/services'; import { RegistrationMapper } from '@osf/shared/mappers/registration'; import { RegistrationCard, RegistrationDataJsonApi } from '@osf/shared/models'; @@ -21,14 +21,14 @@ export class RegistrationsService { }; const url = `${environment.apiUrl}/nodes/${projectId}/linked_by_registrations/`; - return this.jsonApiService.get>(url, params).pipe( + return this.jsonApiService.get>(url, params).pipe( map((response) => { const data = response.data.map((registration: RegistrationDataJsonApi) => RegistrationMapper.fromRegistrationToRegistrationCard(registration) ); return { data, - totalCount: response.links.meta?.total, + totalCount: response.meta?.total, }; }) ); diff --git a/src/app/features/registries/services/registries.service.ts b/src/app/features/registries/services/registries.service.ts index 27bbb5695..fba9971b8 100644 --- a/src/app/features/registries/services/registries.service.ts +++ b/src/app/features/registries/services/registries.service.ts @@ -2,7 +2,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; -import { JsonApiResponseWithPaging } from '@osf/core/models'; +import { ResponseJsonApi } from '@osf/core/models'; import { JsonApiService } from '@osf/core/services'; import { PageSchemaMapper, RegistrationMapper } from '@osf/shared/mappers/registration'; import { @@ -132,9 +132,7 @@ export class RegistriesService { embed: ['bibliographic_contributors', 'registration_schema', 'provider'], }; return this.jsonApiService - .get< - JsonApiResponseWithPaging - >(`${this.apiUrl}/draft_registrations/`, params) + .get>(`${this.apiUrl}/draft_registrations/`, params) .pipe( map((response) => { const data = response.data.map((registration: DraftRegistrationDataJsonApi) => @@ -142,7 +140,7 @@ export class RegistriesService { ); return { data, - totalCount: response.links.meta?.total, + totalCount: response.meta?.total, }; }) ); @@ -159,9 +157,7 @@ export class RegistriesService { embed: ['bibliographic_contributors', 'registration_schema', 'provider'], }; return this.jsonApiService - .get< - JsonApiResponseWithPaging - >(`${this.apiUrl}/users/${userId}/registrations/`, params) + .get>(`${this.apiUrl}/users/${userId}/registrations/`, params) .pipe( map((response) => { const data = response.data.map((registration: RegistrationDataJsonApi) => @@ -169,7 +165,7 @@ export class RegistriesService { ); return { data, - totalCount: response.links.meta?.total, + totalCount: response.meta?.total, }; }) ); diff --git a/src/app/features/registry/models/bibliographic-contributors.models.ts b/src/app/features/registry/models/bibliographic-contributors.models.ts index eaee96b64..5bdb108ad 100644 --- a/src/app/features/registry/models/bibliographic-contributors.models.ts +++ b/src/app/features/registry/models/bibliographic-contributors.models.ts @@ -1,3 +1,4 @@ +import { MetaJsonApi } from '@osf/core/models'; import { InstitutionUsersLinksJsonApi } from '@osf/features/admin-institutions/models'; export interface BibliographicContributorJsonApi { @@ -72,12 +73,7 @@ export interface BibliographicContributorJsonApi { export interface BibliographicContributorsResponse { data: BibliographicContributorJsonApi[]; - meta: { - total: number; - per_page: number; - total_bibliographic: number; - version: string; - }; + meta: MetaJsonApi; links: InstitutionUsersLinksJsonApi; } diff --git a/src/app/features/registry/models/linked-nodes-json-api.model.ts b/src/app/features/registry/models/linked-nodes-json-api.model.ts index 5ef5bdd82..a868b5728 100644 --- a/src/app/features/registry/models/linked-nodes-json-api.model.ts +++ b/src/app/features/registry/models/linked-nodes-json-api.model.ts @@ -1,3 +1,5 @@ +import { MetaJsonApi } from '@osf/core/models'; + export interface LinkedNodeJsonApi { id: string; type: 'nodes'; @@ -114,11 +116,7 @@ export interface LinkedNodeJsonApi { export interface LinkedNodesJsonApiResponse { data: LinkedNodeJsonApi[]; - meta: { - total: number; - per_page: number; - version: string; - }; + meta: MetaJsonApi; links: { self: string; first: string | null; diff --git a/src/app/features/registry/models/linked-registrations-json-api.model.ts b/src/app/features/registry/models/linked-registrations-json-api.model.ts index 7ae822ddb..75349418d 100644 --- a/src/app/features/registry/models/linked-registrations-json-api.model.ts +++ b/src/app/features/registry/models/linked-registrations-json-api.model.ts @@ -1,3 +1,4 @@ +import { MetaJsonApi } from '@osf/core/models'; import { RegistrationReviewStates } from '@shared/enums'; export interface LinkedRegistrationJsonApi { @@ -33,11 +34,7 @@ export interface LinkedRegistrationJsonApi { export interface LinkedRegistrationsJsonApiResponse { data: LinkedRegistrationJsonApi[]; - meta: { - total: number; - per_page: number; - version: string; - }; + meta: MetaJsonApi; links: { self: string; first: string | null; diff --git a/src/app/features/registry/models/linked-response.models.ts b/src/app/features/registry/models/linked-response.models.ts index 66f12585b..9c7d0fe23 100644 --- a/src/app/features/registry/models/linked-response.models.ts +++ b/src/app/features/registry/models/linked-response.models.ts @@ -1,11 +1,10 @@ +import { MetaJsonApi } from '@osf/core/models'; + import { LinkedNode, LinkedRegistration } from './linked-nodes.models'; export interface LinkedNodesResponseJsonApi { data: LinkedNode[]; - meta: { - total: number; - per_page: number; - }; + meta: MetaJsonApi; links: { self: string; first: string | null; @@ -17,10 +16,7 @@ export interface LinkedNodesResponseJsonApi { export interface LinkedRegistrationsResponseJsonApi { data: LinkedRegistration[]; - meta: { - total: number; - per_page: number; - }; + meta: MetaJsonApi; links: { self: string; first: string | null; diff --git a/src/app/features/registry/models/registry-components-json-api.model.ts b/src/app/features/registry/models/registry-components-json-api.model.ts index 7e51f4f07..c2f1229a7 100644 --- a/src/app/features/registry/models/registry-components-json-api.model.ts +++ b/src/app/features/registry/models/registry-components-json-api.model.ts @@ -1,3 +1,5 @@ +import { MetaJsonApi } from '@osf/core/models'; + import { RegistryComponentModel } from './registry-components.models'; export interface RegistryComponentJsonApi { @@ -18,13 +20,10 @@ export interface RegistryComponentJsonApi { export interface RegistryComponentsJsonApiResponse { data: RegistryComponentJsonApi[]; - meta: { - total: number; - per_page: number; - }; + meta: MetaJsonApi; } export interface RegistryComponentsResponseJsonApi { data: RegistryComponentModel[]; - meta: { total: number; per_page: number }; + meta: MetaJsonApi; } diff --git a/src/app/features/registry/models/registry-contributor-json-api.model.ts b/src/app/features/registry/models/registry-contributor-json-api.model.ts index 3193d114e..e1e3bac84 100644 --- a/src/app/features/registry/models/registry-contributor-json-api.model.ts +++ b/src/app/features/registry/models/registry-contributor-json-api.model.ts @@ -1,3 +1,5 @@ +import { MetaJsonApi } from '@osf/core/models'; + export interface RegistryContributorJsonApi { id: string; type: 'contributors'; @@ -73,9 +75,7 @@ export interface RegistryContributorJsonApiResponse { links: { self: string; }; - meta: { - version: string; - }; + meta: MetaJsonApi; } export interface RegistryContributorUpdateRequest { @@ -87,24 +87,6 @@ export interface RegistryContributorUpdateRequest { }; } -export interface RegistryContributorsListJsonApiResponse { - data: RegistryContributorJsonApi[]; - links: { - first: string | null; - last: string | null; - prev: string | null; - next: string | null; - meta: { - total: number; - per_page: number; - total_bibliographic: number; - }; - }; - meta: { - version: string; - }; -} - export interface RegistryContributorAddRequest { data: { type: 'contributors'; diff --git a/src/app/features/registry/models/registry-institutions-json-api.model.ts b/src/app/features/registry/models/registry-institutions-json-api.model.ts index e3aab2ad1..a8b0b3244 100644 --- a/src/app/features/registry/models/registry-institutions-json-api.model.ts +++ b/src/app/features/registry/models/registry-institutions-json-api.model.ts @@ -1,3 +1,5 @@ +import { MetaJsonApi } from '@osf/core/models'; + export interface RegistryInstitutionJsonApi { id: string; type: string; @@ -18,12 +20,6 @@ export interface RegistryInstitutionsJsonApiResponse { last: string | null; prev: string | null; next: string | null; - meta: { - total: number; - per_page: number; - }; - }; - meta: { - version: string; }; + meta: MetaJsonApi; } diff --git a/src/app/features/registry/models/registry-metadata.models.ts b/src/app/features/registry/models/registry-metadata.models.ts index 0a5e7d1bc..4b5227f37 100644 --- a/src/app/features/registry/models/registry-metadata.models.ts +++ b/src/app/features/registry/models/registry-metadata.models.ts @@ -1,11 +1,8 @@ +import { MetaJsonApi } from '@osf/core/models'; + export interface BibliographicContributorsJsonApi { data: BibliographicContributorData[]; - meta: { - total: number; - per_page: number; - total_bibliographic: number; - version: string; - }; + meta: MetaJsonApi; links: { self: string; first: string | null; @@ -125,11 +122,7 @@ export interface UserInstitution { export interface UserInstitutionsResponse { data: UserInstitution[]; - meta: { - total: number; - per_page: number; - version: string; - }; + meta: MetaJsonApi; links: { self: string; first: string | null; @@ -161,14 +154,8 @@ export interface RegistrySubjectsJsonApi { last: string | null; prev: string | null; next: string | null; - meta: { - total: number; - per_page: number; - }; - }; - meta: { - version: string; }; + meta: MetaJsonApi; } export interface RegistrySubjectData { diff --git a/src/app/features/registry/services/registry-metadata.service.ts b/src/app/features/registry/services/registry-metadata.service.ts index d138ba8a8..88e2ff1b9 100644 --- a/src/app/features/registry/services/registry-metadata.service.ts +++ b/src/app/features/registry/services/registry-metadata.service.ts @@ -13,6 +13,7 @@ import { License } from '@shared/models'; import { RegistryMetadataMapper } from '../mappers'; import { + BibliographicContributor, BibliographicContributorsJsonApi, CustomItemMetadataRecord, CustomItemMetadataResponse, @@ -34,11 +35,7 @@ export class RegistryMetadataService { private readonly jsonApiService = inject(JsonApiService); private readonly apiUrl = environment.apiUrl; - getBibliographicContributors( - registryId: string, - page = 1, - pageSize = 100 - ): Observable { + getBibliographicContributors(registryId: string, page = 1, pageSize = 100): Observable { const params: Record = { 'fields[contributors]': 'index,users', 'fields[users]': 'full_name', @@ -46,10 +43,12 @@ export class RegistryMetadataService { 'page[size]': pageSize, }; - return this.jsonApiService.get( - `${this.apiUrl}/registrations/${registryId}/bibliographic_contributors/`, - params - ); + return this.jsonApiService + .get( + `${this.apiUrl}/registrations/${registryId}/bibliographic_contributors/`, + params + ) + .pipe(map((response) => RegistryMetadataMapper.mapBibliographicContributors(response))); } getCustomItemMetadata(guid: string): Observable { diff --git a/src/app/features/registry/store/registry-metadata/registry-metadata.state.ts b/src/app/features/registry/store/registry-metadata/registry-metadata.state.ts index d21eeb8e3..623313e61 100644 --- a/src/app/features/registry/store/registry-metadata/registry-metadata.state.ts +++ b/src/app/features/registry/store/registry-metadata/registry-metadata.state.ts @@ -9,7 +9,6 @@ import { CedarMetadataRecord, CedarMetadataRecordJsonApi } from '@osf/features/p import { ResourceType } from '@shared/enums'; import { GetAllContributors } from '@shared/stores'; -import { RegistryMetadataMapper } from '../../mappers'; import { CustomItemMetadataRecord } from '../../models'; import { RegistryMetadataService } from '../../services/registry-metadata.service'; @@ -97,8 +96,7 @@ export class RegistryMetadataState { return this.registryMetadataService .getBibliographicContributors(action.registryId, action.page, action.pageSize) .pipe( - tap((response) => { - const contributors = RegistryMetadataMapper.mapBibliographicContributors(response); + tap((contributors) => { ctx.patchState({ bibliographicContributors: { data: contributors, diff --git a/src/app/shared/mappers/collections/collections.mapper.ts b/src/app/shared/mappers/collections/collections.mapper.ts index 91e6eef6c..774e3713a 100644 --- a/src/app/shared/mappers/collections/collections.mapper.ts +++ b/src/app/shared/mappers/collections/collections.mapper.ts @@ -1,4 +1,4 @@ -import { JsonApiResponseWithPaging } from '@core/models'; +import { ResponseJsonApi } from '@core/models'; import { CollectionSubmissionReviewAction, CollectionSubmissionReviewActionJsonApi, @@ -107,7 +107,7 @@ export class CollectionsMapper { } static fromGetCollectionSubmissionsResponse( - response: JsonApiResponseWithPaging + response: ResponseJsonApi ): PaginatedData { return { data: response.data.map((submission) => ({ @@ -139,7 +139,7 @@ export class CollectionsMapper { } : undefined, })), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } diff --git a/src/app/shared/mappers/contributors/contributors.mapper.ts b/src/app/shared/mappers/contributors/contributors.mapper.ts index 46101c53c..aa1287a4c 100644 --- a/src/app/shared/mappers/contributors/contributors.mapper.ts +++ b/src/app/shared/mappers/contributors/contributors.mapper.ts @@ -1,4 +1,4 @@ -import { JsonApiResponseWithPaging, UserGetResponse } from '@osf/core/models'; +import { ResponseJsonApi, UserGetResponse } from '@osf/core/models'; import { AddContributorType, ContributorPermission } from '@osf/shared/enums'; import { ContributorAddModel, @@ -24,7 +24,7 @@ export class ContributorsMapper { } static fromUsersWithPaginationGetResponse( - response: JsonApiResponseWithPaging + response: ResponseJsonApi ): PaginatedData { return { data: response.data.map( @@ -36,7 +36,7 @@ export class ContributorsMapper { permission: ContributorPermission.Read, }) as ContributorAddModel ), - totalCount: response.links.meta.total, + totalCount: response.meta.total, }; } diff --git a/src/app/shared/mappers/institutions/general-institution.mapper.ts b/src/app/shared/mappers/institutions/general-institution.mapper.ts index 15dc684b6..13dfbc583 100644 --- a/src/app/shared/mappers/institutions/general-institution.mapper.ts +++ b/src/app/shared/mappers/institutions/general-institution.mapper.ts @@ -19,7 +19,7 @@ export class GeneralInstitutionMapper { static adaptInstitutions(response: FetchInstitutionsJsonApi): GetGeneralInstitutionsResponse { return { data: response.data.map((institution) => this.adaptInstitution(institution)), - total: response.links.meta.total, + total: response.meta.total, }; } } diff --git a/src/app/shared/mappers/view-only-links.mapper.ts b/src/app/shared/mappers/view-only-links.mapper.ts index 4b754f692..3dd1b12c6 100644 --- a/src/app/shared/mappers/view-only-links.mapper.ts +++ b/src/app/shared/mappers/view-only-links.mapper.ts @@ -23,8 +23,8 @@ export class ViewOnlyLinksMapper { return { items, - total: response.links.meta.total, - perPage: response.links.meta.per_page, + total: response.meta.total, + perPage: response.meta.per_page, next: response.links.next, prev: response.links.prev, }; diff --git a/src/app/shared/models/institutions/institutions-json-api.model.ts b/src/app/shared/models/institutions/institutions-json-api.model.ts index 49017a50c..0c91072a0 100644 --- a/src/app/shared/models/institutions/institutions-json-api.model.ts +++ b/src/app/shared/models/institutions/institutions-json-api.model.ts @@ -1,3 +1,4 @@ +import { ResponseJsonApi } from '@osf/core/models'; import { Institution, InstitutionAttributes } from '@shared/models'; export interface InstitutionRelationships { @@ -46,18 +47,10 @@ export interface InstitutionsResponseLinks { last: string | null; prev: string | null; next: string | null; - meta: { - total: number; - per_page: number; - }; } -export interface FetchInstitutionsJsonApi { - data: InstitutionData[]; +export interface FetchInstitutionsJsonApi extends ResponseJsonApi { links: InstitutionsResponseLinks; - meta: { - version: string; - }; } export interface GetGeneralInstitutionsResponse { diff --git a/src/app/shared/models/my-resources/my-resources.models.ts b/src/app/shared/models/my-resources/my-resources.models.ts index 219c157d2..31afd4eda 100644 --- a/src/app/shared/models/my-resources/my-resources.models.ts +++ b/src/app/shared/models/my-resources/my-resources.models.ts @@ -1,4 +1,8 @@ -import { JsonApiResponse } from '@core/models'; +import { ResponseJsonApi } from '@core/models'; + +export type MyResourcesItemResponseJsonApi = ResponseJsonApi; + +export type MyResourcesResponseJsonApi = ResponseJsonApi; export interface MyResourcesItemGetResponseJsonApi { id: string; @@ -25,12 +29,6 @@ export interface MyResourcesItemGetResponseJsonApi { }; }; }[]; - links: { - meta: { - total: number; - per_page: number; - }; - }; }; }; } @@ -51,22 +49,3 @@ export interface MyResourcesItem { isPublic: boolean; contributors: MyResourcesContributor[]; } - -export interface MyResourcesItemResponseJsonApi { - data: MyResourcesItem[]; - links: { - meta: { - total: number; - per_page: number; - }; - }; -} - -export interface MyResourcesResponseJsonApi extends JsonApiResponse { - links: { - meta: { - total: number; - per_page: number; - }; - }; -} diff --git a/src/app/shared/models/view-only-links/view-only-link-response.model.ts b/src/app/shared/models/view-only-links/view-only-link-response.model.ts index 29eb57cc0..58a8544b5 100644 --- a/src/app/shared/models/view-only-links/view-only-link-response.model.ts +++ b/src/app/shared/models/view-only-links/view-only-link-response.model.ts @@ -1,11 +1,9 @@ -import { UserGetResponse } from '@osf/core/models'; +import { MetaJsonApi, UserGetResponse } from '@osf/core/models'; export interface ViewOnlyLinksResponseJsonApi { data: ViewOnlyLinkJsonApi[]; links: PaginationLinksJsonApi; - meta: { - version: string; - }; + meta: MetaJsonApi; } export interface ViewOnlyLinkJsonApi { @@ -54,8 +52,4 @@ export interface PaginationLinksJsonApi { last: string | null; prev: string | null; next: string | null; - meta: { - total: number; - per_page: number; - }; } diff --git a/src/app/shared/services/collections.service.ts b/src/app/shared/services/collections.service.ts index 11330d77b..05617b36b 100644 --- a/src/app/shared/services/collections.service.ts +++ b/src/app/shared/services/collections.service.ts @@ -4,7 +4,7 @@ import { forkJoin, map, Observable, of, switchMap } from 'rxjs'; import { inject, Injectable } from '@angular/core'; -import { JsonApiResponse, JsonApiResponseWithPaging } from '@core/models'; +import { JsonApiResponse, ResponseJsonApi } from '@core/models'; import { JsonApiService } from '@core/services'; import { CollectionSubmissionReviewAction, @@ -87,31 +87,29 @@ export class CollectionsService { type: 'search', }; - return this.jsonApiService - .post>(url, payload, params) - .pipe( - switchMap((response) => { - if (!response.data.length) { - return of([]); - } - - const contributorUrls = response.data.map( - (submission) => submission.embeds.guid.data.relationships.bibliographic_contributors.links.related.href - ); - const contributorRequests = contributorUrls.map((url) => this.getCollectionContributors(url)); - const totalCount = response.links.meta?.total ?? 0; - this.actions.setTotalSubmissions(totalCount); - - return forkJoin(contributorRequests).pipe( - map((contributorsArrays) => { - return response.data.map((submission, index) => ({ - ...CollectionsMapper.fromPostCollectionSubmissionsResponse([submission])[0], - contributors: contributorsArrays[index], - })); - }) - ); - }) - ); + return this.jsonApiService.post>(url, payload, params).pipe( + switchMap((response) => { + if (!response.data.length) { + return of([]); + } + + const contributorUrls = response.data.map( + (submission) => submission.embeds.guid.data.relationships.bibliographic_contributors.links.related.href + ); + const contributorRequests = contributorUrls.map((url) => this.getCollectionContributors(url)); + const totalCount = response.meta?.total ?? 0; + this.actions.setTotalSubmissions(totalCount); + + return forkJoin(contributorRequests).pipe( + map((contributorsArrays) => + response.data.map((submission, index) => ({ + ...CollectionsMapper.fromPostCollectionSubmissionsResponse([submission])[0], + contributors: contributorsArrays[index], + })) + ) + ); + }) + ); } fetchCollectionSubmissionsByStatus( @@ -130,13 +128,9 @@ export class CollectionsService { return this.jsonApiService .get< - JsonApiResponseWithPaging + ResponseJsonApi >(`${environment.apiUrl}/collections/${collectionId}/collection_submissions/`, params) - .pipe( - map((response) => { - return CollectionsMapper.fromGetCollectionSubmissionsResponse(response); - }) - ); + .pipe(map((response) => CollectionsMapper.fromGetCollectionSubmissionsResponse(response))); } fetchProjectCollections(projectId: string): Observable { @@ -161,11 +155,7 @@ export class CollectionsService { .get< JsonApiResponse >(`${environment.apiUrl}/collections/${collectionId}/collection_submissions/`, params) - .pipe( - map((response) => { - return CollectionsMapper.fromCurrentSubmissionResponse(response.data[0]); - }) - ); + .pipe(map((response) => CollectionsMapper.fromCurrentSubmissionResponse(response.data[0]))); } fetchCollectionSubmissionsActions( @@ -214,11 +204,13 @@ export class CollectionsService { 'fields[users]': 'full_name', }; - return this.jsonApiService.get(contributorsUrl, params).pipe( - map((response: ContributorsResponseJsonApi) => { - return CollectionsMapper.fromGetCollectionContributorsResponse(response.data); - }) - ); + return this.jsonApiService + .get(contributorsUrl, params) + .pipe( + map((response: ContributorsResponseJsonApi) => + CollectionsMapper.fromGetCollectionContributorsResponse(response.data) + ) + ); } private fetchUserCollectionSubmissionsByStatus( @@ -233,12 +225,8 @@ export class CollectionsService { return this.jsonApiService .get< - JsonApiResponseWithPaging + ResponseJsonApi >(`${environment.apiUrl}/collections/${providerId}/collection_submissions/`, params) - .pipe( - map((response) => { - return CollectionsMapper.fromGetCollectionSubmissionsResponse(response); - }) - ); + .pipe(map((response) => CollectionsMapper.fromGetCollectionSubmissionsResponse(response))); } } diff --git a/src/app/shared/services/contributors.service.ts b/src/app/shared/services/contributors.service.ts index 80ee919ed..7aee9a33b 100644 --- a/src/app/shared/services/contributors.service.ts +++ b/src/app/shared/services/contributors.service.ts @@ -2,7 +2,7 @@ import { map, Observable } from 'rxjs'; import { inject, Injectable } from '@angular/core'; -import { JsonApiResponse, JsonApiResponseWithPaging, UserGetResponse } from '@osf/core/models'; +import { JsonApiResponse, ResponseJsonApi, UserGetResponse } from '@osf/core/models'; import { JsonApiService } from '@osf/core/services'; import { AddContributorType, ResourceType } from '@osf/shared/enums'; import { ContributorsMapper } from '@osf/shared/mappers/contributors'; @@ -46,7 +46,7 @@ export class ContributorsService { const baseUrl = `${environment.apiUrl}/users/?filter[full_name]=${value}&page=${page}`; return this.jsonApiService - .get>(baseUrl) + .get>(baseUrl) .pipe(map((response) => ContributorsMapper.fromUsersWithPaginationGetResponse(response))); } diff --git a/src/app/shared/services/my-resources.service.ts b/src/app/shared/services/my-resources.service.ts index dbfb223cb..c0f8a30d0 100644 --- a/src/app/shared/services/my-resources.service.ts +++ b/src/app/shared/services/my-resources.service.ts @@ -102,6 +102,7 @@ export class MyResourcesService { map((response: MyResourcesResponseJsonApi) => ({ data: response.data.map((item: MyResourcesItemGetResponseJsonApi) => MyResourcesMapper.fromResponse(item)), links: response.links, + meta: response.meta, })) ); } diff --git a/src/app/shared/services/node-links.service.ts b/src/app/shared/services/node-links.service.ts index 4b3a0cdf8..a0c029ab0 100644 --- a/src/app/shared/services/node-links.service.ts +++ b/src/app/shared/services/node-links.service.ts @@ -50,12 +50,8 @@ export class NodeLinksService { }; return this.jsonApiService - .get>(`${environment.apiUrl}/nodes/${projectId}/node_links/`, params) - .pipe( - map((response) => { - return response.data.map((item) => NodeLinksMapper.fromNodeLinkResponse(item)); - }) - ); + .get>(`${environment.apiUrl}/nodes/${projectId}/linked_nodes/`, params) + .pipe(map((response) => response.data.map((item) => NodeLinksMapper.fromNodeLinkResponse(item)))); } deleteNodeLink(projectId: string, nodeLinkId: string): Observable { diff --git a/src/app/shared/stores/my-resources/my-resources.state.ts b/src/app/shared/stores/my-resources/my-resources.state.ts index ff76f3b3f..8f92c4614 100644 --- a/src/app/shared/stores/my-resources/my-resources.state.ts +++ b/src/app/shared/stores/my-resources/my-resources.state.ts @@ -46,7 +46,7 @@ export class MyResourcesState { isLoading: false, error: null, }, - totalProjects: res.links.meta.total, + totalProjects: res.meta.total, }); }), catchError((error) => handleSectionError(ctx, 'projects', error)) @@ -73,7 +73,7 @@ export class MyResourcesState { isLoading: false, error: null, }, - totalRegistrations: res.links.meta.total, + totalRegistrations: res.meta.total, }); }), catchError((error) => handleSectionError(ctx, 'registrations', error)) @@ -98,7 +98,7 @@ export class MyResourcesState { isLoading: false, error: null, }, - totalPreprints: res.links.meta.total, + totalPreprints: res.meta.total, }); }), catchError((error) => handleSectionError(ctx, 'preprints', error)) @@ -127,7 +127,7 @@ export class MyResourcesState { isLoading: false, error: null, }, - totalBookmarks: res.links.meta.total, + totalBookmarks: res.meta.total, }); }), catchError((error) => handleSectionError(ctx, 'bookmarks', error)) @@ -159,9 +159,7 @@ export class MyResourcesState { tap((results) => { const allData = [...results.projects.data, ...results.preprints.data, ...results.registrations.data]; const totalCount = - results.projects.links.meta.total + - results.preprints.links.meta.total + - results.registrations.links.meta.total; + results.projects.meta.total + results.preprints.meta.total + results.registrations.meta.total; ctx.patchState({ bookmarks: { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index cbbf2aefa..9ce8b64e5 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -2450,7 +2450,8 @@ "sendMessage": "Send message", "osfLink": "OSF Link", "orcid": "ORCID", - "noData": "No users found" + "noData": "No users found", + "messageSent": "Message has been sent." }, "projects": { "title": "Title",