Skip to content

Commit

Permalink
feat(search): implementa animaliaDS e externaliza para uso no portal
Browse files Browse the repository at this point in the history
Implementa AnimaliaDS e externaliza para uso no portal

Fixes DTHFUI-7501
  • Loading branch information
anliben committed Nov 8, 2023
1 parent 0f635b4 commit f54fb9b
Show file tree
Hide file tree
Showing 12 changed files with 1,243 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,100 @@ import { PoFilterMode } from './po-search-filter-mode.enum';
import { Directive, EventEmitter, Input, Output } from '@angular/core';
import { convertToBoolean } from '../../utils/util';

/**
* @description
*
* O componente search, também conhecido como barra de pesquisa, é utilizado para ajudar os usuários a localizarem um determinado conteúdo.
*
* Normalmente localizado no canto superior direito acompanhado do ícone de lupa, já que é um ícone amplamente conhecido.
*
* Este componente é um recurso encontrado na maioria das soluções e ferramentas digitais, principalmente quando há grande quantidade de informações.
*
* #### Boas práticas
*
* Foram estruturados os padrões de usabilidade para auxiliar na utilização do componente e garantir uma boa experiência aos usuários. Por isso, é muito importante que ao utilizar este componente, as pessoas que o projetarem devem levar em consideração os seguintes critérios:
* - Utilize labels para apresentar resultados que estão sendo exibidos e apresente os resultados mais relevantes primeiro.
* - Exiba uma mensagem clara quando não forem encontrados resultados para busca e sempre que possível ofereça outras sugestões de busca.
* - Mantenha o texto original no campo de input, que facilita a ação do usuário caso queira fazer uma nova busca com alguma modificação na pesquisa.
* - Caso seja possível detectar um erro de digitação, mostre os resultados para a palavra "corrigida", isso evita a frustração de não obter resultados e não força o usuário a realizar uma nova busca.
* - Quando apropriado, destaque os termos da busca nos resultados.
* - A entrada do campo de pesquisa deve caber em uma linha. Não use entradas de pesquisa de várias linhas.
* - Recomenda-se ter apenas uma pesquisa por página. Se você precisar de várias pesquisas, rotule-as claramente para indicar sua finalidade.
* - Se possível, forneça sugestões de pesquisa, seja em um helptext ou sugestão de pesquisa que é um autocomplete. Isso ajuda os usuários a encontrar o que estão procurando, especialmente se os itens pesquisáveis forem complexos.
*
* #### Acessibilidade tratada no componente
*
* Algumas diretrizes de acessibilidade já são tratadas no componente, internamente, e não podem ser alteradas pelo proprietário do conteúdo. São elas:
*
* - Permitir a interação via teclado (2.1.1: Keyboard (A));
* - Alteração entre os estados precisa ser indicada por mais de um elemento além da cor (1.4.1: Use of Color);
*/
@Directive()
export class PoSearchBaseComponent {
/**
* @optional
*
* @description
*
* Desabilita o po-search e não permite que o usuário interaja com o mesmo.
*
* @default `false`
*/
@Input({ alias: 'p-disabled', transform: convertToBoolean }) disabled?: boolean;

/**
* @optional
*
* @description
*
* Exibe um ícone de carregamento à esquerda do label do botão.
*
* @default `false`
*/
@Input('p-loading') loading: boolean;

/**
* @optional
*
* @description
*
* Lista de itens que serão utilizados para pesquisa
*/
@Input('p-items') items: Array<any> = [];

/**
* @optional
*
* @description
*
* Deve ser informado o nome da propriedade do objeto que será utilizado para a conversão dos itens apresentados na lista do componente (p-items), esta propriedade será responsável pelo texto de apresentação de cada item da lista.
*/
@Input('p-filter-keys') filterKeys: Array<any> = [];

/**
* @optional
*
* @description
*
* Define o modo de pesquisa utilizado no campo de busca, quando habilitado. Valores definidos no enum: PoFilterMode
*/
@Input('p-filter-type') filterType: PoFilterMode = PoFilterMode.startsWith;

/**
* @optional
*
* @description
*
* Pode ser informada uma função que será disparada quando houver alterações no input.
*/
@Output('p-filtered-items-change') filteredItemsChange = new EventEmitter<Array<any>>();

/**
* @optional
*
* @description
*
* Pode ser informada uma função que será disparada quando houver alterações nos filtros.
*/
@Output('p-filter') filter: EventEmitter<any> = new EventEmitter<any>();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="po-search">
<div class="po-search" [class.po-search-disabled]="disabled">
<div class="po-search-icon">
<po-icon *ngIf="!loading" p-icon="po-icon-search"></po-icon>
<po-loading-icon *ngIf="loading"></po-loading-icon>
Expand All @@ -14,7 +14,12 @@
(input)="onSearchChange($event.target.value)"
/>

<div *ngIf="!!poSearchInput.value && !disabled" class="po-search-clean" [tabindex]="!disabled ? 0 : -1">
<div
*ngIf="!!poSearchInput.value && !disabled"
class="po-search-clean"
[tabindex]="!disabled ? 0 : -1"
(keydown.enter)="clearSearch()"
>
<po-clean [p-element-ref]="poSearchInput" (p-change-event)="clearSearch()"></po-clean>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ describe('PoSearchComponent', () => {
});

it('clearSearch: should clear the search', () => {
component.clearSearch();
const inputElement = document.createElement('input');
document.body.appendChild(inputElement);

expect(component.poSearchInput.nativeElement.value).toBe('');
component.poSearchInput = { nativeElement: inputElement };

spyOn(component, 'onSearchChange');
component.clearSearch();
expect(component.onSearchChange).toHaveBeenCalledWith('');

expect(component.filteredItemsChange.emit).toHaveBeenCalledWith(component.items);
expect(inputElement.value).toBe('');

document.body.removeChild(inputElement);
});

it('onSearchChange: should filter items based on search text and emit filtered items', () => {
Expand Down
25 changes: 24 additions & 1 deletion projects/ui/src/lib/components/po-search/po-search.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@ export const poSearchLiteralsDefault = {
ru: <PoSearchLiterals>{ search: 'Поиск' }
};

/**
* @docsExtends PoSearchBaseComponent
*
* @example
*
* <example name="po-search-basic" title="PO Search Basic">
* <file name="sample-po-search-basic/sample-po-search-basic.component.html"> </file>
* <file name="sample-po-search-basic/sample-po-search-basic.component.ts"> </file>
* </example>
*
* <example name="po-search-labs" title="PO Search Labs">
* <file name="sample-po-search-labs/sample-po-search-labs.component.html"> </file>
* <file name="sample-po-search-labs/sample-po-search-labs.component.ts"> </file>
* <file name="sample-po-search-labs/sample-po-search-labs.service.ts"> </file>
* </example>
*
* <example name="po-search-find-people" title="PO Search Find People">
* <file name="sample-po-search-find-people/sample-po-search-find-people.component.html"> </file>
* <file name="sample-po-search-find-people/sample-po-search-find-people.component.ts"> </file>
* <file name="sample-po-search-find-people/sample-po-search-find-people.service.ts"> </file>
* </example>
*
*/
@Component({
selector: 'po-search',
templateUrl: './po-search.component.html'
Expand Down Expand Up @@ -40,6 +63,7 @@ export class PoSearchComponent extends PoSearchBaseComponent implements OnInit {
this.poSearchInput.nativeElement.value = '';
this.onSearchChange('');
this.filteredItemsChange.emit(this.items);
this.poSearchInput.nativeElement.focus();
}

onBlur(): void {
Expand Down Expand Up @@ -75,7 +99,6 @@ export class PoSearchComponent extends PoSearchBaseComponent implements OnInit {
return false;
})
);

this.filteredItemsChange.emit(this.filteredItems);
} else {
this.filteredItems = [];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<po-search p-clean></po-search>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Component } from '@angular/core';

@Component({
selector: 'sample-po-search-basic',
templateUrl: './sample-po-search-basic.component.html'
})
export class SamplePoSearchBasicComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="po-row">
<po-search
class="po-md-12"
name="Po Search"
p-tooltip="Pesquisar por name, nickname or email"
[p-items]="items"
[p-filter-keys]="filterKeys"
(p-filter)="filtered($event)"
(p-filtered-items-change)="filtered($event)"
></po-search>
</div>

<hr />

<div class="po-row" *ngIf="(people.name && people.nickname && people.email) !== null">
<po-info class="po-md-4" p-label="Name" [p-value]="people.name"> </po-info>

<po-info class="po-md-4" p-label="Nickname" [p-value]="people.nickname"> </po-info>

<po-info class="po-md-4" p-label="Email" [p-value]="people.email"> </po-info>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Component, OnInit } from '@angular/core';
import { SamplePoSearchFindPeopleService } from './sample-po-search-find-people.service';

@Component({
selector: 'sample-po-search-find-people',
templateUrl: './sample-po-search-find-people.component.html',
providers: [SamplePoSearchFindPeopleService]
})
export class SamplePoSearchFindPeopleComponent implements OnInit {
people: any = {};
items: any;
filterKeys: Array<string> = ['name', 'nickname', 'email'];

constructor(private service: SamplePoSearchFindPeopleService) {}

ngOnInit() {
this.items = this.service.getItems();
}

filtered(event: any) {
try {
this.people = {
name: event[0]['name'],
nickname: event[0]['nickname'],
email: event[0]['email']
};
} catch (error) {
return undefined;
}
}
}
Loading

0 comments on commit f54fb9b

Please sign in to comment.