-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(uve): FTM - Implement "Bookmarks" button on UVE Toolbar (#30793)
### Showcase https://github.com/user-attachments/assets/b25924df-46ed-465c-895e-89623863739e This pull request introduces significant changes to the `core-web/libs/portlets/edit-ema` module, focusing on the new toolbar variant and its integration with the existing components. The key changes include the addition of the `TOOLBAR_VARIANTS` enum, updates to the `dot-ema-bookmarks` and `dot-uve-toolbar` components, and modifications to the state management for the new toolbar variant. ### Toolbar Variants and Component Updates: * **Introduction of `TOOLBAR_VARIANTS` Enum:** - Added `TOOLBAR_VARIANTS` enum to define different toolbar styles, including the new UVE toolbar variant. * **Component Updates for Toolbar Variants:** - Updated `dot-ema-bookmarks.component.html` to conditionally render buttons based on the toolbar variant. - Modified `dot-uve-toolbar.component.html` to include conditional rendering for the new toolbar variant and preview mode. [[1]](diffhunk://#diff-9937556e73b051b878ba22ad1ce971a70019a617d7979b3e0bcc814801ad350bL3-R12) [[2]](diffhunk://#diff-9937556e73b051b878ba22ad1ce971a70019a617d7979b3e0bcc814801ad350bR23-R26) [[3]](diffhunk://#diff-9937556e73b051b878ba22ad1ce971a70019a617d7979b3e0bcc814801ad350bR36-R39) - Enhanced `dot-uve-toolbar.component.ts` to integrate the `TOOLBAR_VARIANTS` enum and handle preview mode toggling. ### State Management Enhancements: * **State Management for Toolbar Variants:** - Introduced `withUVEToolbar` to manage the state of the new toolbar variant, including methods for toggling preview mode. - Updated the `withEditor` function to include the `withUVEToolbar` state feature. [[1]](diffhunk://#diff-86e692578757ed7f4f6cba5d0aeb07641312f3b17885825d1a45987153ae87f0R22-R24) [[2]](diffhunk://#diff-86e692578757ed7f4f6cba5d0aeb07641312f3b17885825d1a45987153ae87f0R70) ### Testing Enhancements: * **Unit Tests for New Toolbar Variant:** - Updated `dot-uve-toolbar.component.spec.ts` to include tests for the new toolbar variant and its attributes. [[1]](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1L1-R130) [[2]](diffhunk://#diff-3eaa147616a5d1ff374a5fa27b0f38f0159a9039ef7e8d672dec43631f48a9e1R157) - Added tests in `withEditor.spec.ts` to validate the state management of the new toolbar variant. These changes collectively enhance the flexibility and functionality of the toolbar in the UVE interface, providing a more dynamic user experience. --------- Co-authored-by: Kevin Davila <[email protected]>
- Loading branch information
1 parent
3dd6041
commit 910d7e2
Showing
11 changed files
with
412 additions
and
50 deletions.
There are no files selected for viewing
23 changes: 16 additions & 7 deletions
23
...let/src/lib/edit-ema-editor/components/dot-ema-bookmarks/dot-ema-bookmarks.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
<p-button | ||
(onClick)="toggleBookmark()" | ||
[loading]="loading()" | ||
[icon]="bookmarked() ? 'pi pi-star-fill' : 'pi pi-star'" | ||
[label]="'editpage.toolbar.bookmark' | dm" | ||
styleClass="p-button-text p-button-sm" | ||
data-testId="bookmark-button" /> | ||
@if (store.$previewMode()) { | ||
<p-button | ||
(click)="toggleBookmark()" | ||
[icon]="bookmarked() ? 'pi pi-star-fill' : 'pi pi-star'" | ||
[loading]="loading()" | ||
styleClass="p-button-text" | ||
data-testId="bookmark-button" /> | ||
} @else { | ||
<p-button | ||
(onClick)="toggleBookmark()" | ||
[loading]="loading()" | ||
[icon]="bookmarked() ? 'pi pi-star-fill' : 'pi pi-star'" | ||
[label]="'editpage.toolbar.bookmark' | dm" | ||
styleClass="p-button-text p-button-sm" | ||
data-testId="bookmark-button" /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 137 additions & 27 deletions
164
...tlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,157 @@ | ||
import { byTestId, Spectator } from '@ngneat/spectator'; | ||
import { byTestId, mockProvider, Spectator } from '@ngneat/spectator'; | ||
import { createComponentFactory } from '@ngneat/spectator/jest'; | ||
import { MockComponent } from 'ng-mocks'; | ||
import { of } from 'rxjs'; | ||
|
||
import { HttpClientTestingModule, provideHttpClientTesting } from '@angular/common/http/testing'; | ||
import { signal } from '@angular/core'; | ||
|
||
import { DotExperimentsService, DotLanguagesService, DotLicenseService } from '@dotcms/data-access'; | ||
import { LoginService } from '@dotcms/dotcms-js'; | ||
import { | ||
DotExperimentsServiceMock, | ||
DotLanguagesServiceMock, | ||
DotLicenseServiceMock | ||
} from '@dotcms/utils-testing'; | ||
|
||
import { DotUveToolbarComponent } from './dot-uve-toolbar.component'; | ||
|
||
import { DotPageApiService } from '../../../services/dot-page-api.service'; | ||
import { DEFAULT_PERSONA } from '../../../shared/consts'; | ||
import { | ||
HEADLESS_BASE_QUERY_PARAMS, | ||
MOCK_RESPONSE_HEADLESS, | ||
MOCK_RESPONSE_VTL | ||
} from '../../../shared/mocks'; | ||
import { UVEStore } from '../../../store/dot-uve.store'; | ||
import { | ||
createFavoritePagesURL, | ||
createFullURL, | ||
createPageApiUrlWithQueryParams, | ||
sanitizeURL | ||
} from '../../../utils'; | ||
import { DotEmaBookmarksComponent } from '../dot-ema-bookmarks/dot-ema-bookmarks.component'; | ||
|
||
describe('DotUveToolbarComponent', () => { | ||
let spectator: Spectator<DotUveToolbarComponent>; | ||
const createComponent = createComponentFactory({ | ||
component: DotUveToolbarComponent | ||
component: DotUveToolbarComponent, | ||
imports: [HttpClientTestingModule, MockComponent(DotEmaBookmarksComponent)], | ||
providers: [ | ||
UVEStore, | ||
provideHttpClientTesting(), | ||
{ | ||
provide: DotLanguagesService, | ||
useValue: new DotLanguagesServiceMock() | ||
}, | ||
{ | ||
provide: DotExperimentsService, | ||
useValue: DotExperimentsServiceMock | ||
}, | ||
{ | ||
provide: DotLicenseService, | ||
useValue: new DotLicenseServiceMock() | ||
}, | ||
{ | ||
provide: DotPageApiService, | ||
useValue: { | ||
get: () => of(MOCK_RESPONSE_HEADLESS) | ||
} | ||
}, | ||
{ | ||
provide: LoginService, | ||
useValue: { | ||
getCurrentUser: () => of({}) | ||
} | ||
} | ||
] | ||
}); | ||
|
||
beforeEach(() => { | ||
spectator = createComponent(); | ||
}); | ||
const params = HEADLESS_BASE_QUERY_PARAMS; | ||
const url = sanitizeURL(params?.url); | ||
|
||
it('should have preview button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-preview'))).toBeTruthy(); | ||
}); | ||
const pageAPIQueryParams = createPageApiUrlWithQueryParams(url, params); | ||
const pageAPIResponse = MOCK_RESPONSE_HEADLESS; | ||
|
||
it('should have bookmark button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-bookmark'))).toBeTruthy(); | ||
}); | ||
const pageAPI = `/api/v1/page/${'json'}/${pageAPIQueryParams}`; | ||
|
||
it('should have copy url button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-copy-url'))).toBeTruthy(); | ||
}); | ||
const shouldShowInfoDisplay = false || pageAPIResponse?.page.locked || false || false; | ||
|
||
it('should have api link button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-api-link'))).toBeTruthy(); | ||
const bookmarksUrl = createFavoritePagesURL({ | ||
languageId: Number(params?.language_id), | ||
pageURI: url, | ||
siteId: pageAPIResponse?.site.identifier | ||
}); | ||
|
||
it('should have experiments button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-running-experiment'))).toBeTruthy(); | ||
}); | ||
describe('base state', () => { | ||
beforeEach(() => { | ||
spectator = createComponent({ | ||
providers: [ | ||
mockProvider(UVEStore, { | ||
$uveToolbar: signal({ | ||
editor: { | ||
bookmarksUrl, | ||
copyUrl: createFullURL(params, pageAPIResponse?.site.identifier), | ||
apiUrl: `${'http://localhost'}${pageAPI}` | ||
}, | ||
preview: null, | ||
|
||
it('should have language selector', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-language-selector'))).toBeTruthy(); | ||
}); | ||
currentLanguage: pageAPIResponse?.viewAs.language, | ||
urlContentMap: null, | ||
runningExperiment: null, | ||
workflowActionsInode: pageAPIResponse?.page.inode, | ||
unlockButton: null, | ||
showInfoDisplay: shouldShowInfoDisplay, | ||
personaSelector: { | ||
pageId: pageAPIResponse?.page.identifier, | ||
value: pageAPIResponse?.viewAs.persona ?? DEFAULT_PERSONA | ||
} | ||
}), | ||
setDevice: jest.fn(), | ||
setSocialMedia: jest.fn(), | ||
pageParams: signal(params), | ||
pageAPIResponse: signal(MOCK_RESPONSE_VTL), | ||
reloadCurrentPage: jest.fn(), | ||
loadPageAsset: jest.fn() | ||
}) | ||
] | ||
}); | ||
}); | ||
|
||
it('should have persona selector', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-persona-selector'))).toBeTruthy(); | ||
}); | ||
describe('dot-ema-bookmarks', () => { | ||
it('should have attr', () => { | ||
const bookmarks = spectator.query(DotEmaBookmarksComponent); | ||
|
||
expect(bookmarks.url).toBe('/test-url?host_id=123-xyz-567-xxl&language_id=1'); | ||
}); | ||
}); | ||
|
||
it('should have preview button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-preview'))).toBeTruthy(); | ||
}); | ||
|
||
it('should have copy url button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-copy-url'))).toBeTruthy(); | ||
}); | ||
|
||
it('should have api link button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-api-link'))).toBeTruthy(); | ||
}); | ||
|
||
it('should have experiments button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-running-experiment'))).toBeTruthy(); | ||
}); | ||
|
||
it('should have language selector', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-language-selector'))).toBeTruthy(); | ||
}); | ||
|
||
it('should have persona selector', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-persona-selector'))).toBeTruthy(); | ||
}); | ||
|
||
it('should have workflows button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-workflow-actions'))).toBeTruthy(); | ||
it('should have workflows button', () => { | ||
expect(spectator.query(byTestId('uve-toolbar-workflow-actions'))).toBeTruthy(); | ||
}); | ||
}); | ||
}); |
18 changes: 14 additions & 4 deletions
18
...a/portlet/src/lib/edit-ema-editor/components/dot-uve-toolbar/dot-uve-toolbar.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,26 @@ | ||
import { ChangeDetectionStrategy, Component } from '@angular/core'; | ||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; | ||
|
||
import { ButtonModule } from 'primeng/button'; | ||
import { ToolbarModule } from 'primeng/toolbar'; | ||
|
||
import { DotMessagePipe } from '@dotcms/ui'; | ||
import { UVEStore } from '../../../store/dot-uve.store'; | ||
import { DotEmaBookmarksComponent } from '../dot-ema-bookmarks/dot-ema-bookmarks.component'; | ||
import { DotEmaInfoDisplayComponent } from '../dot-ema-info-display/dot-ema-info-display.component'; | ||
|
||
@Component({ | ||
selector: 'dot-uve-toolbar', | ||
standalone: true, | ||
imports: [ButtonModule, DotMessagePipe, ToolbarModule], | ||
imports: [ButtonModule, ToolbarModule, DotEmaBookmarksComponent, DotEmaInfoDisplayComponent], | ||
templateUrl: './dot-uve-toolbar.component.html', | ||
styleUrl: './dot-uve-toolbar.component.scss', | ||
changeDetection: ChangeDetectionStrategy.OnPush | ||
}) | ||
export class DotUveToolbarComponent {} | ||
export class DotUveToolbarComponent { | ||
#store = inject(UVEStore); | ||
|
||
readonly $toolbar = this.#store.$uveToolbar; | ||
|
||
togglePreviewMode(preview: boolean) { | ||
this.#store.togglePreviewMode(preview); | ||
} | ||
} |
Oops, something went wrong.