diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.spec.ts index c70caaf4c9f..37cea00539f 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.spec.ts @@ -18,6 +18,7 @@ import { LoginServiceMock, MockDotMessageService } from '@dotcms/utils-testing'; import { DotEmaBookmarksComponent } from './dot-ema-bookmarks.component'; +import { mockCurrentUser } from '../../../../../shared/mocks'; import { UVEStore } from '../../../../../store/dot-uve.store'; describe('DotEmaBookmarksComponent', () => { @@ -29,7 +30,10 @@ describe('DotEmaBookmarksComponent', () => { providers: [ DialogService, HttpClient, - mockProvider(UVEStore, { $previewMode: signal(false) }), + mockProvider(UVEStore, { + $previewMode: signal(false), + currentUser: signal(mockCurrentUser) + }), { provide: LoginService, useClass: LoginServiceMock diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.ts index 11a258c72f0..538a0cbd73a 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/components/dot-ema-bookmarks/dot-ema-bookmarks.component.ts @@ -1,13 +1,22 @@ -import { ChangeDetectionStrategy, Component, Input, OnInit, inject, signal } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + ChangeDetectionStrategy, + Component, + DestroyRef, + Input, + OnInit, + inject, + signal +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { ButtonModule } from 'primeng/button'; import { DialogService } from 'primeng/dynamicdialog'; import { TooltipModule } from 'primeng/tooltip'; -import { map, switchMap } from 'rxjs/operators'; +import { delay, map, retryWhen, takeWhile } from 'rxjs/operators'; import { DotFavoritePageService, DotMessageService } from '@dotcms/data-access'; -import { LoginService } from '@dotcms/dotcms-js'; import { DotCMSContentlet } from '@dotcms/dotcms-models'; import { DotFavoritePageComponent } from '@dotcms/portlets/dot-ema/ui'; import { DotMessagePipe } from '@dotcms/ui'; @@ -24,10 +33,11 @@ import { UVEStore } from '../../../../../store/dot-uve.store'; export class DotEmaBookmarksComponent implements OnInit { @Input() url = ''; - private readonly loginService = inject(LoginService); private readonly dotFavoritePageService = inject(DotFavoritePageService); + private readonly http = inject(HttpClient); private readonly dialogService = inject(DialogService); private readonly dotMessageService = inject(DotMessageService); + private readonly destroyRef = inject(DestroyRef); protected readonly store = inject(UVEStore); favoritePage: DotCMSContentlet; @@ -68,18 +78,25 @@ export class DotEmaBookmarksComponent implements OnInit { private fetchFavoritePage(url: string): void { this.loading.set(true); - this.loginService - .getCurrentUser() + this.dotFavoritePageService + .get({ + url, + userId: this.store.currentUser()?.userId, + limit: 10 + }) .pipe( - switchMap((user) => { - return this.dotFavoritePageService - .get({ - url, - userId: user.userId, - limit: 10 + takeUntilDestroyed(this.destroyRef), + retryWhen((errors) => + errors.pipe( + delay(500), + takeWhile((error) => { + // This request is returning null in some cases and we need to retry + return error instanceof TypeError; }) - .pipe(map((res) => res.jsonObjectView.contentlets[0])); - }) + ) + ), + + map((res) => res.jsonObjectView.contentlets[0]) ) .subscribe((favoritePage) => { this.loading.set(false); diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-palette/store/edit-ema-palette.store.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-palette/store/edit-ema-palette.store.ts index eb77d25bd8e..d5764cd54d4 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-palette/store/edit-ema-palette.store.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/edit-ema-editor/components/edit-ema-palette/store/edit-ema-palette.store.ts @@ -4,7 +4,7 @@ import { EMPTY, Observable, forkJoin } from 'rxjs'; import { Injectable, inject } from '@angular/core'; -import { catchError, map, switchMap, tap } from 'rxjs/operators'; +import { catchError, delay, map, retryWhen, switchMap, takeWhile, tap } from 'rxjs/operators'; import { DotContentTypeService, @@ -248,6 +248,15 @@ export class DotPaletteStore extends ComponentStore { DotConfigurationVariables.CONTENT_PALETTE_HIDDEN_CONTENT_TYPES ) }).pipe( + retryWhen((errors) => + errors.pipe( + delay(500), + takeWhile((error) => { + // The request is returning null in some cases and we need to retry + return error instanceof TypeError; + }) + ) + ), map(({ contentTypes, widgets, hiddenContentTypes }) => { /** * This filter is used to prevent widgets from being repeated. diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/mocks.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/mocks.ts index 20c5869ead8..4439e9b830e 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/mocks.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/shared/mocks.ts @@ -1,5 +1,6 @@ import { of } from 'rxjs'; +import { CurrentUser } from '@dotcms/dotcms-js'; import { DEFAULT_VARIANT_ID, DotPageContainerStructure, @@ -986,3 +987,12 @@ export const dotPropertiesServiceMock = { [FeaturedFlags.FEATURE_FLAG_UVE_PREVIEW_MODE]: false }) }; + +export const mockCurrentUser: CurrentUser = { + email: 'test@example.com', + givenName: 'Test', + loginAs: false, + roleId: 'role123', + surname: 'User', + userId: 'user123' +}; diff --git a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.spec.ts b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.spec.ts index ce3326c3bdc..5aa633b6bfa 100644 --- a/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.spec.ts +++ b/core-web/libs/portlets/edit-ema/portlet/src/lib/store/features/editor/toolbar/withUVEToolbar.spec.ts @@ -6,7 +6,6 @@ import { of } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; import { UVE_MODE } from '@dotcms/client'; -import { CurrentUser } from '@dotcms/dotcms-js'; import { DEFAULT_VARIANT_ID, DEFAULT_VARIANT_NAME } from '@dotcms/dotcms-models'; import { getRunningExperimentMock, mockDotDevices } from '@dotcms/utils-testing'; @@ -15,7 +14,7 @@ import { withUVEToolbar } from './withUVEToolbar'; import { DotPageApiService } from '../../../../services/dot-page-api.service'; import { DEFAULT_PERSONA } from '../../../../shared/consts'; import { UVE_STATUS } from '../../../../shared/enums'; -import { MOCK_RESPONSE_HEADLESS } from '../../../../shared/mocks'; +import { MOCK_RESPONSE_HEADLESS, mockCurrentUser } from '../../../../shared/mocks'; import { Orientation, UVEState } from '../../../models'; const pageParams = { @@ -46,15 +45,6 @@ const initialState: UVEState = { } }; -const currentUser: CurrentUser = { - email: 'test@example.com', - givenName: 'Test', - loginAs: false, - roleId: 'role123', - surname: 'User', - userId: 'user123' -}; - export const uveStoreMock = signalStore( { protectedState: false }, withState(initialState), @@ -194,7 +184,7 @@ describe('withEditor', () => { lockedBy: '456' } }, - currentUser + currentUser: mockCurrentUser }); expect(store.$infoDisplayProps()).toEqual({ icon: 'pi pi-lock', @@ -214,12 +204,12 @@ describe('withEditor', () => { ...MOCK_RESPONSE_HEADLESS.page, locked: true, canLock: false, - lockedByName: currentUser.givenName, - lockedBy: currentUser.userId + lockedByName: mockCurrentUser.givenName, + lockedBy: mockCurrentUser.userId } }, currentUser: { - ...currentUser, + ...mockCurrentUser, userId: '123' } }); @@ -242,11 +232,11 @@ describe('withEditor', () => { ...MOCK_RESPONSE_HEADLESS.page, locked: true, canLock: true, - lockedByName: currentUser.givenName, - lockedBy: currentUser.userId + lockedByName: mockCurrentUser.givenName, + lockedBy: mockCurrentUser.userId } }, - currentUser + currentUser: mockCurrentUser }); expect(store.$infoDisplayProps()).toBe(null);