Skip to content

Commit

Permalink
feat(announcements): modal closing enhancement for announcements (dot…
Browse files Browse the repository at this point in the history
…CMS#27707)

* dotCMS#27434 Adding modal closing enhancement

* dotCMS#27434 Adding modal closing enhancement

* Clean up

* Clean up

* Applying style

* PR Feedback

* PR feedback

* dotCMS#27434 Adding toolbar

* PR feedback
  • Loading branch information
manuelrojas authored and spbolton committed Feb 28, 2024
1 parent f8f9376 commit dcbdf1b
Show file tree
Hide file tree
Showing 18 changed files with 230 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export class DotShowHideFeatureDirective implements OnInit {
this._alternateTemplateRef = alternateTemplateRef;
}

@Input() dotShowOnNotFound: boolean;

get alternateTemplateRef(): TemplateRef<Component> {
return this._alternateTemplateRef;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<div class="dot-mask" *ngIf="show" (click)="onToggle()"></div>
<button
class="p-button-rounded p-button-text"
*ngIf="icon"
[disabled]="disabled"
[icon]="icon"
(click)="onToggle()"
pButton
data-testid="icon-button"
></button>
data-testid="icon-button"></button>

<button
*ngIf="title"
Expand All @@ -16,14 +16,8 @@
pButton
icon="pi pi-chevron-down"
iconPos="right"
data-testid="title-button"
></button>
data-testid="title-button"></button>

<div
class="dropdown-content"
*ngIf="show"
[@enterAnimation]="show"
[ngStyle]="!position || position === 'left' ? { left: 0 } : { right: 0 }"
>
<div class="dropdown-content" *ngIf="show" [@enterAnimation]="show" [ngStyle]="positionStyle">
<ng-content></ng-content>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import { DotDropdownComponent } from './dot-dropdown.component';
template: `<dot-dropdown-component
[icon]="icon"
[title]="title"
[disabled]="disabled"
></dot-dropdown-component>`
[disabled]="disabled"></dot-dropdown-component>`
})
class DotTestHostComponent {
disabled: boolean;
Expand Down Expand Up @@ -120,4 +119,19 @@ describe('DotDropdownComponent', () => {
comp.closeIt();
expect(comp.show).toBe(false);
});

it('shold show the mask', () => {
comp.show = true;
hostFixture.detectChanges();
const mask = de.query(By.css('.dot-mask'));
mask.nativeElement.click();
expect(mask).toBeTruthy();
});

it('shold hide the mask', () => {
comp.show = false;
hostFixture.detectChanges();
const mask = de.query(By.css('.dot-mask'));
expect(mask).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ export class DotDropdownComponent implements OnChanges {
@Input()
title = null;

@Input()
position: string;
@Input() position: 'left' | 'right' = 'left';

@Input()
inverted = false;
Expand All @@ -53,9 +52,14 @@ export class DotDropdownComponent implements OnChanges {
shutdown = new EventEmitter<never>();

show = false;
positionStyle = {};

constructor(private elementRef: ElementRef) {}

ngOnInit() {
this.positionStyle[this.position] = '0';
}

ngOnChanges(changes: SimpleChanges): void {
if (changes.disabled && this.icon) {
this.disabled = changes.disabled.currentValue ? true : null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,67 +1,66 @@
<h5 class="announcements__title">{{ 'announcements' | dm }}</h5>
<ul class="announcements__list">
@for (item of announcements(); track item.identifier;) {
<li
class="announcements__list-item"
[class.announcements__list-item--active]="!item.hasBeenRead">
<span class="announcements__badge" *ngIf="!item.hasBeenRead"></span>
<span
class="announcements__image pi"
[ngClass]="typesIcons[item.type | lowercase] || typesIcons['important']"></span>
<a
class="announcements__url"
[href]="item.url"
target="_blank"
rel="noopener noreferrer"
data-testId="announcement_link"
aria-labelledby="announcement-label date-label">
<div class="announcements__content">
<span class="announcements__label">{{ item.title }}</span>
<span class="announcements__date">{{ item.announcementDateAsISO8601 | date }}</span>
<div class="dot-mask" *ngIf="showMask()" data-testId="dot-mask"></div>
<p-overlayPanel
#toolbarAnnouncements
(onHide)="hideDialog()"
appendTo="body"
styleClass="toolbar-announcements__container">
<div class="announcements__main-container">
<h5 class="announcements__title">{{ 'announcements' | dm }}</h5>
<ul class="announcements__list">
@for (item of announcements(); track item.identifier;) {
<li
class="announcements__list-item"
[class.announcements__list-item--active]="!item.hasBeenRead">
<span class="announcements__badge" *ngIf="!item.hasBeenRead"></span>
<span
class="announcements__image pi"
[ngClass]="typesIcons[item.type | lowercase] || typesIcons['important']"></span>
<a
class="announcements__url"
[href]="item.url"
target="_blank"
rel="noopener noreferrer"
data-testId="announcement_link"
aria-labelledby="announcement-label date-label">
<div class="announcements__content">
<span class="announcements__label">{{ item.title }}</span>
<span class="announcements__date">{{
item.announcementDateAsISO8601 | date
}}</span>
</div>
</a>
</li>
}
</ul>

<div class="announcements__container">
<div class="announcements__link-container">
<i class="pi pi-external-link"></i>
<a
class="announcements__link"
[href]="linkToDotCms()"
target="_blank"
data-testId="announcement_link_all"
rel="noopener"
>{{ 'announcements.show.all' | dm }}</a
>
</div>
</a>
</li>
}
</ul>
</div>

<div class="announcements__container">
<div class="announcements__link-container">
<i class="pi pi-external-link"></i>
<a
class="announcements__link"
[href]="linkToDotCms()"
target="_blank"
data-testId="announcement_link_all"
rel="noopener"
>{{ 'announcements.show.all' | dm }}</a
>
@for (item of aboutLinks; track $index) {
<h5 class="announcements__title">{{ item.title | dm }}</h5>
<div class="announcements__about">
@for (item of item.items; track $index) {
<a
class="announcements__about-link"
[href]="item.url"
data-testId="announcement_link"
target="_blank"
rel="noopener"
>{{ item.label }}</a
>
}
</div>
}
</div>
</div>

<h5 class="announcements__title">{{ 'announcements.knowledge.center' | dm }}</h5>
<div class="announcements__about">
@for (item of knowledgeCenterLinks(); track item.id;) {
<a
class="announcements__about-link"
[href]="item.url"
data-testId="announcement_link"
target="_blank"
rel="noopener"
>{{ item.label }}</a
>
}
</div>

<h5 class="announcements__title">{{ 'announcements.knowledge.contact.us' | dm }}</h5>
<div class="announcements__about">
@for (item of contactLinks(); track item.id;) {
<a
class="announcements__about-link"
[href]="item.url"
data-testId="announcement_link"
target="_blank"
rel="noopener"
>{{ item.label }}</a
>
}
</div>
</p-overlayPanel>
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
@use "variables" as *;

:host {
.announcements__main-container {
max-height: 100vh;
overflow: auto;
display: block;
padding: $spacing-4;
width: 26rem;
width: 24rem;
}

.announcements__list {
Expand Down Expand Up @@ -119,13 +118,3 @@
left: 39px;
top: 14px;
}

::ng-deep {
.toolbar-announcements__container {
&.p-overlaypanel {
.p-overlaypanel-content {
padding: 0;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { NgClass, NgForOf } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing';

import { OverlayPanelModule } from 'primeng/overlaypanel';

import { DotMessageService } from '@dotcms/data-access';
import { SiteService, SiteServiceMock } from '@dotcms/dotcms-js';
import { DotMessagePipe } from '@dotcms/ui';
Expand Down Expand Up @@ -56,11 +58,12 @@ describe('DotToolbarAnnouncementsComponent', () => {
useValue: siteServiceMock
}
],
imports: [NgForOf, NgClass, DotMessagePipe, HttpClientTestingModule]
imports: [NgForOf, NgClass, DotMessagePipe, HttpClientTestingModule, OverlayPanelModule]
});

beforeEach(() => {
spectator = createComponent();
spectator.component.toggleDialog(new MouseEvent('click'));
});

it('should display announcements', () => {
Expand Down Expand Up @@ -90,4 +93,16 @@ describe('DotToolbarAnnouncementsComponent', () => {
spectator.setInput('showUnreadAnnouncement', false);
expect(markAnnouncementsAsReadSpy).toHaveBeenCalled();
});

it('should show the mask when the dialog is opened', () => {
spectator.detectChanges();
const mask = spectator.query(byTestId('dot-mask'));
expect(mask).toBeTruthy();
});

it('should hide the mask when the dialog is closed', () => {
spectator.component.toggleDialog(new MouseEvent('click'));
const mask = spectator.query(byTestId('dot-mask'));
expect(mask).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import { NgClass, NgForOf, CommonModule } from '@angular/common';
import { Component, Input, OnChanges, OnInit, Signal, inject } from '@angular/core';
import {
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
Signal,
ViewChild,
inject,
signal
} from '@angular/core';
import { RouterLink } from '@angular/router';

import { OverlayPanel, OverlayPanelModule } from 'primeng/overlaypanel';

import { skip } from 'rxjs/operators';

import {
Expand All @@ -19,27 +32,36 @@ import { DotMessagePipe } from '@dotcms/ui';
templateUrl: './dot-toolbar-announcements.component.html',
styleUrls: ['./dot-toolbar-announcements.component.scss'],
standalone: true,
imports: [NgForOf, NgClass, DotMessagePipe, RouterLink, CommonModule],
imports: [NgForOf, NgClass, DotMessagePipe, RouterLink, CommonModule, OverlayPanelModule],
providers: [AnnouncementsStore]
})
export class DotToolbarAnnouncementsComponent implements OnInit, OnChanges {
announcementsStore = inject(AnnouncementsStore);
dotMessageService = inject(DotMessageService);
siteService = inject(SiteService);
@ViewChild('toolbarAnnouncements', { static: true }) toolbarAnnouncements: OverlayPanel;
@Output() hideMenu = new EventEmitter();

@Input() showUnreadAnnouncement: boolean;
announcements: Signal<Announcement[]> = this.announcementsStore.announcementsSignal;
contactLinks: Signal<AnnouncementLink[]> = this.announcementsStore.selectContactLinks;
knowledgeCenterLinks: Signal<AnnouncementLink[]> =
this.announcementsStore.selectKnowledgeCenterLinks;
linkToDotCms: Signal<string> = this.announcementsStore.selectLinkToDotCms;
showMask = signal<boolean>(false);

aboutLinks: { title: string; items: AnnouncementLink[] }[] = [];

ngOnInit(): void {
this.announcementsStore.load();

this.siteService.switchSite$.pipe(skip(1)).subscribe(() => {
this.announcementsStore.refreshUtmParameters();
this.announcementsStore.load();
this.aboutLinks = [
{ title: 'announcements.knowledge.center', items: this.knowledgeCenterLinks() },
{ title: 'announcements.knowledge.contact.us', items: this.contactLinks() }
];
});
}

Expand All @@ -49,6 +71,24 @@ export class DotToolbarAnnouncementsComponent implements OnInit, OnChanges {
}
}

/**
* Toggle the dialog
* @param event
*/
toggleDialog(event): void {
this.showMask.update((value) => !value);
this.toolbarAnnouncements.toggle(event);
}

/**
* On hide dialog mark announcements as read
* @param event
*/
hideDialog(): void {
this.hideMenu.emit();
this.showMask.set(false);
}

typesIcons = {
tip: TypesIcons.Tip,
release: TypesIcons.Release,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ a {
.notification-item__wrapper {
display: flex;
flex-direction: row;
justify-content: center;
padding: $spacing-3 0;
align-items: self-start;
gap: $spacing-3;
Expand Down
Loading

0 comments on commit dcbdf1b

Please sign in to comment.