diff --git a/projects/ui/src/lib/components/components.module.ts b/projects/ui/src/lib/components/components.module.ts index 458ac256d..160cc8daf 100644 --- a/projects/ui/src/lib/components/components.module.ts +++ b/projects/ui/src/lib/components/components.module.ts @@ -46,6 +46,7 @@ import { PoTreeViewModule } from './po-tree-view/po-tree-view.module'; import { PoWidgetModule } from './po-widget/po-widget.module'; import { PoSearchModule } from './po-search'; import { PoBadgeModule } from './po-badge/po-badge.module'; +import { PoMessageHourModule } from './po-message-hour'; @NgModule({ imports: [ @@ -94,7 +95,8 @@ import { PoBadgeModule } from './po-badge/po-badge.module'; PoPageSlideModule, PoSwitchModule, PoSearchModule, - PoBadgeModule + PoBadgeModule, + PoMessageHourModule ], exports: [ PoAccordionModule, @@ -142,7 +144,8 @@ import { PoBadgeModule } from './po-badge/po-badge.module'; PoPageSlideModule, PoSwitchModule, PoSearchModule, - PoBadgeModule + PoBadgeModule, + PoMessageHourModule ], providers: [], bootstrap: [], diff --git a/projects/ui/src/lib/components/index.ts b/projects/ui/src/lib/components/index.ts index 1f6a92cbf..e8cfb73ec 100644 --- a/projects/ui/src/lib/components/index.ts +++ b/projects/ui/src/lib/components/index.ts @@ -45,3 +45,4 @@ export * from './po-toolbar/index'; export * from './po-tree-view/index'; export * from './po-widget/index'; export * from './po-search/index'; +export * from './po-message-hour/index'; diff --git a/projects/ui/src/lib/components/po-message-hour/index.ts b/projects/ui/src/lib/components/po-message-hour/index.ts new file mode 100644 index 000000000..dc36c8895 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/index.ts @@ -0,0 +1,3 @@ +export * from './po-message-hour.component'; + +export * from './po-message-hour.module'; diff --git a/projects/ui/src/lib/components/po-message-hour/literals/po-message-hour-literals.ts b/projects/ui/src/lib/components/po-message-hour/literals/po-message-hour-literals.ts new file mode 100644 index 000000000..3340f3bbd --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/literals/po-message-hour-literals.ts @@ -0,0 +1,10 @@ +export interface PoMessageHourLiterals { + /** + * @usedBy PoMessageHour + * + * @description + * + * Interface para configuração de mensagem de saudação. + */ + salutation?: string; +} diff --git a/projects/ui/src/lib/components/po-message-hour/po-message-hour-base.component.spec.ts b/projects/ui/src/lib/components/po-message-hour/po-message-hour-base.component.spec.ts new file mode 100644 index 000000000..359701211 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/po-message-hour-base.component.spec.ts @@ -0,0 +1,13 @@ +import { PoMessageHourBaseComponent } from './po-message-hour-base.component'; + +describe('PoMessageHourBaseComponent:', () => { + let component: PoMessageHourBaseComponent; + + beforeEach(() => { + component = new PoMessageHourBaseComponent(); + }); + + it('should be created', () => { + expect(component instanceof PoMessageHourBaseComponent).toBeTruthy(); + }); +}); diff --git a/projects/ui/src/lib/components/po-message-hour/po-message-hour-base.component.ts b/projects/ui/src/lib/components/po-message-hour/po-message-hour-base.component.ts new file mode 100644 index 000000000..c2e093674 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/po-message-hour-base.component.ts @@ -0,0 +1,41 @@ +import { Directive, EventEmitter, Input, Output } from '@angular/core'; + +/** + * @description + * + * O componente `PoMessageHour` é responsável por exibir mensagens horárias personalizadas com base no período do dia. + * + * #### Boas Práticas + * + * Este componente é projetado seguindo as práticas recomendadas para proporcionar uma experiência de usuário eficiente e acessível, sendo especialmente útil para saudações exibidas após alguma ação do usuário: + * + * ##### Uso + * - Gera mensagens de saudação de acordo com o período do dia: madrugada, manhã, tarde ou noite. + * + * ##### Acessibilidade + * - Utiliza controles HTML padrão para permitir a identificação por tecnologias assistivas. + * - Mantém o underline no link para diferenciar de textos comuns, atendendo às diretrizes de contraste. + * - Preserva o estado de foco do componente e garante que a aparência do foco atenda aos requisitos de acessibilidade. + * + */ +@Directive() +export class PoMessageHourBaseComponent { + /** + * @optional + * + * @description + * + * Label da mensagem. + */ + @Input('p-label') label?: string; + + /** + * @optional + * + * @description + * + * Evento emitido quando o período do dia da mensagem é atualizado. + * O período do dia pode ser 'dawn' (madrugada), 'morning' (manhã), 'afternoon' (tarde) ou 'night' (noite). + */ + @Output('p-message-hour') messageHour = new EventEmitter(); +} diff --git a/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.html b/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.html new file mode 100644 index 000000000..51136d554 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.html @@ -0,0 +1,4 @@ +
+ {{ label }} + +
diff --git a/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.spec.ts b/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.spec.ts new file mode 100644 index 000000000..c2354ce42 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.spec.ts @@ -0,0 +1,112 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PoMessageHourComponent } from './po-message-hour.component'; + +describe('PoMessageHourComponent', () => { + let component: PoMessageHourComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [PoMessageHourComponent] + }); + fixture = TestBed.createComponent(PoMessageHourComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should set message for dawn', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(4); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.dawn}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.dawn}` + ); + }); + + it('should set message for morning', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(10); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.morning}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.morning}` + ); + }); + + it('should set message for night', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(21); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.night}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.night}` + ); + }); + + it('should set message for afternoon', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(15); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.afternoon}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.afternoon}` + ); + }); + + it('should set message for edge case: 5 AM', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(5); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.dawn}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.dawn}` + ); + }); + + it('should set message for edge case: 12 PM', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(12); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.afternoon}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.afternoon}` + ); + }); + + it('should set message for edge case: 6 PM', () => { + spyOn(component.messageHour, 'emit'); + + spyOn(component, 'getCurrentHour').and.returnValue(18); + + component.setMessage(); + + expect(component.message).toEqual(`${component.literals.salutation} ${component.literals.night}`); + expect(component.messageHour.emit).toHaveBeenCalledWith( + `${component.literals.salutation} ${component.literals.night}` + ); + }); +}); diff --git a/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.ts b/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.ts new file mode 100644 index 000000000..f91c09fd7 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/po-message-hour.component.ts @@ -0,0 +1,88 @@ +import { Component } from '@angular/core'; +import { PoMessageHourLiterals } from './literals/po-message-hour-literals'; +import { PoMessageHourBaseComponent } from './po-message-hour-base.component'; + +export const poMessageHourDefault = { + en: { + salutation: 'Welcome', + dawn: 'Good dawn', + morning: 'Good morning', + afternoon: 'Good afternoon', + night: 'Good night' + }, + es: { + salutation: 'Bienvenido', + dawn: 'Buen amanecer', + morning: 'Buenos días', + afternoon: 'Buenas tardes', + night: 'Buenas noches' + }, + pt: { + salutation: 'Bem vindo', + dawn: 'Boa madrugada', + morning: 'Bom dia', + afternoon: 'Boa tarde', + night: 'Boa noite' + }, + ru: { + salutation: 'добро пожаловать', + dawn: 'Доброй ночи', + morning: 'Доброе утро', + afternoon: 'Добрый день', + night: 'Добрый вечер' + } +}; + +/** + * @docsExtends PoMessageHourBaseComponent + * + * @example + * + * + * + * + * + * + * + * + * + * + */ +@Component({ + selector: 'po-message-hour', + templateUrl: './po-message-hour.component.html' +}) +export class PoMessageHourComponent extends PoMessageHourBaseComponent { + public literals?: any; + + message: string; + + ngOnInit() { + const browserLanguage = navigator.language.split('-')[0]; + this.literals = poMessageHourDefault[browserLanguage]; + + this.setMessage(); + } + + getCurrentHour() { + return new Date().getHours(); + } + + setMessage() { + const hour = this.getCurrentHour(); + let timeOfDay = ''; + + if (hour <= 5) { + timeOfDay = this.literals.dawn; + } else if (hour < 12) { + timeOfDay = this.literals.morning; + } else if (hour < 18) { + timeOfDay = this.literals.afternoon; + } else { + timeOfDay = this.literals.night; + } + + this.message = `${this.literals.salutation} ${timeOfDay}`; + this.messageHour.emit(this.message); + } +} diff --git a/projects/ui/src/lib/components/po-message-hour/po-message-hour.module.ts b/projects/ui/src/lib/components/po-message-hour/po-message-hour.module.ts new file mode 100644 index 000000000..be7e7c688 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/po-message-hour.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { PoMessageHourComponent } from './po-message-hour.component'; +import { PoLinkModule } from '../po-link'; + +/** + * @description + * + * Módulo do componente po-message-hour. + */ +@NgModule({ + declarations: [PoMessageHourComponent], + imports: [CommonModule, RouterModule, PoLinkModule], + exports: [PoMessageHourComponent, PoLinkModule] +}) +export class PoMessageHourModule {} diff --git a/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-basic/sample-po-message-hour-basic.component.html b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-basic/sample-po-message-hour-basic.component.html new file mode 100644 index 000000000..0a68bc2a9 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-basic/sample-po-message-hour-basic.component.html @@ -0,0 +1 @@ + diff --git a/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-basic/sample-po-message-hour-basic.component.ts b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-basic/sample-po-message-hour-basic.component.ts new file mode 100644 index 000000000..4fa1928b8 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-basic/sample-po-message-hour-basic.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sample-po-message-hour-basic', + templateUrl: './sample-po-message-hour-basic.component.html' +}) +export class SamplePoMessageHourBasicComponent {} diff --git a/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-menu/sample-po-message-hour-menu.component.html b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-menu/sample-po-message-hour-menu.component.html new file mode 100644 index 000000000..b3ef85e8d --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-menu/sample-po-message-hour-menu.component.html @@ -0,0 +1,7 @@ +
+ + + + + +
diff --git a/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-menu/sample-po-message-hour-menu.component.ts b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-menu/sample-po-message-hour-menu.component.ts new file mode 100644 index 000000000..f2b951899 --- /dev/null +++ b/projects/ui/src/lib/components/po-message-hour/samples/sample-po-message-hour-menu/sample-po-message-hour-menu.component.ts @@ -0,0 +1,56 @@ +import { PoMenuItem } from '@po-ui/ng-components'; +import { Component } from '@angular/core'; + +@Component({ + selector: 'sample-po-message-hour-menu', + templateUrl: './sample-po-message-hour-menu.component.html' +}) +export class SamplePoMessageHourMenuComponent { + menuItemSelected: string; + + menus: Array = [ + { label: 'Register user', action: this.printMenuAction.bind(this), icon: 'po-icon-user', shortLabel: 'Register' }, + { + label: 'Timekeeping', + action: this.printMenuAction.bind(this), + icon: 'po-icon-clock', + shortLabel: 'Timekeeping', + badge: { value: 1 } + }, + { + label: 'Useful links', + icon: 'po-icon-share', + shortLabel: 'Links', + subItems: [ + { label: 'Ministry of Labour', action: this.printMenuAction.bind(this), link: 'http://trabalho.gov.br/' }, + { label: 'SindPD Syndicate', action: this.printMenuAction.bind(this), link: 'http://www.sindpd.com.br/' } + ] + }, + { + label: 'Benefits', + icon: 'po-icon-star', + shortLabel: 'Benefits', + subItems: [ + { + label: 'Meal tickets', + subItems: [ + { label: 'Acceptance network ', action: this.printMenuAction.bind(this) }, + { + label: 'Extracts', + action: this.printMenuAction.bind(this), + subItems: [ + { label: 'Monthly', action: this.printMenuAction.bind(this), badge: { value: 3, color: 'color-03' } }, + { label: 'Custom', action: this.printMenuAction.bind(this) } + ] + } + ] + }, + { label: 'Transportation tickets', action: this.printMenuAction.bind(this), badge: { value: 12 } } + ] + } + ]; + + printMenuAction(menu: PoMenuItem) { + this.menuItemSelected = menu.label; + } +}