Projeto criado para componentes reutilizaveis entre os frontends do portal de agendamento.
npm i --save @seniorlogistica/yms-components
- Refresh Button
- Decorators para Salvar Filtro aplicado ao navegar entre telas
- Componente de seleção de plantas
- Componente de visualização dos anexos da agenda
O componente refresh-button necessíta de uma chave com o nome "update_grid" no arquivo de translate
Para facilitar o salvamento e recarregamento de filtros aplicados ao component nos projetos de frontend foi criado um serviço que utiliza o sessionStorage do browser para armazenar o filtro e também foram criados decorators para aplicar e manter o estado dos filtros de maneira simplificada. Lembrando que o salvamento é feito propositalmente no sessionStorage do browser para que esta informação esteja acessível somente à janela onde esta foi criada, isto é, ao aplicar e realizado o salvamento de um filtro em uma janela do browser, este não estará disponível em outras instâncias, ficando restrita apenas à janela que foi criada.
Para a utilização desta funcionalidade de salvamento deve-se respeitar algumas premissas.
- yms-components: Deve-se obrigatóriamente estar utilizando o pacote yms-components
- Aliado à estrutura gerada pelo gerador: Deve utilizar aliado ao gerado pelo gerado de frontends nas telas de listagem bem como os métodos de aplicação de filtros e refresh criados pelo @seniorsistemas/frontend-generator.
- Injetar o Component p-table: Derverá ser injetado o component HTML para ser acessível via typescript do component.
<p-table #componentTable [value]="componentGridData" [columns]="componentGridColumns" dataKey="id" [lazy]="true"
[scrollable]="true" [resizableColumns]="true" sortMode="single" [paginator]="true"
[totalRecords]="componentTotalRecords" rows="10" [rowsPerPageOptions]="[10, 20, 50, 100]"
[(selection)]="componentSelection" (onLazyLoad)="componentGridChange($event)" [loading]="componentGridLoading"
[sortOrder]="1" >
import { ViewChild } from "@angular/core";
import { Table } from "primeng/table";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy {
...
@ViewChild('componentTable')
public componentTable: Table;
...
}
- Injetar o Serviço SaveScreenFilterService: Injetar o serviço SaveScreenFilterService para que seja fornecido com item da configuração dos decorators
import { SaveScreenFilterService } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy {
...
constructor(
private saveScreenFilterService:SaveScreenFilterService
) {}
}
- Criar o objeto SaveFilterConfig: No método ngOnInit criar o objeto SaveFilterConfig que é necessário para o funcionamento dos decorators.
import { SaveFilterConfig } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy {
//Declaração como Field
public saveFilterConfig: SaveFilterConfig;
...
public ngOnInit() {
this.saveFilterConfig = {
environment: environment, //importação dos dados do projeto
formFilter: this.conponentFiltersForm, //formGroup que agrega os filtros permitidos na listagem
saveScreenFilterService: this.saveScreenFilterService, //Injeção do serviço que realiza o salvamento
searchMethodName: "componentSearch", //Método que é chamado a aplicar os filtros
tableRef: this.componentTable, //@ViewChild do component p-table
tableCurrentListParams: "componentCurrentListParams"// Objeto ListParams que faz parte do componente e guarda os tokens de consulta
};
}
}
- Interface SaveFilterInfoProvider: Implementar a interface SaveFilterInfoProvider no componente para que as informações necessárias ao salvamento/aplicação filtros estejam disponíveis através da chamada do método getSaveFilterConfig() para que os decorators funcionem adequadamente.
import { SaveFilterInfoProvider, SaveFilterConfig } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy, SaveFilterInfoProvider {
...
getSaveFilterConfig(): SaveFilterConfig {
return this.saveFilterConfig;
}
}
No método onde é aplicado os filtros na tela de listagem deve se adicionado o decorator @StoreFilters() para que seja armazenado o filtro ao ser executado qualquer filtro no grid.
import { StoreFilters } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy, SaveFilterInfoProvider {
...
@StoreFilters()//Decorator responsável por salvar o filtro aplicado
public componentSearch(table: any) {
if (!this.componentFiltersForm.valid) {
return this.validateAllFormFields(this.componentFiltersForm);
}
const filterData = this.componentFiltersForm.getRawValue();
this.componentFiltersPanelCollapsed = true;
this.componentResetGrid(table, { filterData });
}
...
}
No método ngOnInit que é executado ao inicializar a tela deve ser adicionado o decorator @ApplyFilterOnInit() ao método ngOnInit() e também adicionar @ApplyFilterOnGridChange() ao método que esteja vinculado ao evento (onLazyLoad) do p-table para que ao abrir a tela e existir um filtro já armazenado, este seja aplicado
import { ApplyFilterOnInit, ApplyFilterOnGridChange } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy, SaveFilterInfoProvider {
...
@ApplyFilterOnInit()//Decorator que é responsável por localizar filtro salvo e aplicá-lo na abertura da tela
public ngOnInit() {
...
}
@ApplyFilterOnGridChange()
public componentGridChange(event: LazyLoadEvent) {
...
}
...
}
Como é possível remover o filtro token a token que foi aplicado é necessário aplicar o decorator @UpdateStoredFilters() no método de remoção dos tokens para que seja atualizado o filtro salvo assim que removido um token.
import { UpdateStoredFilters } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy, SaveFilterInfoProvider {
...
@UpdateStoredFilters()//Decoretor responsável por realizar a atualização do filtro salvo
public componentRemoveToken(table: any, token: CustomIToken) {
if (token.id == "status") {
this.componentFiltersForm
.get(token.id)
.setValue(this.componentFiltersForm
.get(token.id)
.value.filter((val: any) => val != token.value));
} else {
this.componentFiltersForm.get(token.id).setValue(undefined);
}
const filterData = this.componentFiltersForm.getRawValue();
this.componentResetGrid(table, { filterData });
}
...
}
Para executar a remoção do filtro salvo ao limpar todos os filtros da tela é necessário aplicar o decorator @ClearStoredFilters() no método de limpeza dos filtros na tela de listagem.
import { ClearStoredFilters } from "@seniorlogistica/yms-components";
...
@Component({
templateUrl: "./component-list.component.html",
providers: [ConfirmationService],
})
export class ComponentListComponent implements OnInit, OnDestroy, SaveFilterInfoProvider {
...
@ClearStoredFilters()
public componentClear(table: any) {
this.componentFiltersForm.reset();
const filterData = this.componentFiltersForm.getRawValue();
this.componentResetGrid(table, { filterData });
}
...
}
O componente de seleção de plantas foi criado para centralizar o vínculo da planta à sessão. Para isso, foram desenvolvidas regras que devem ser utilizadas para a utilização desse módulo.
Para direcionar qualquer rota para o componente de seleção de planta, é necessário dois passos. Importar o módulo SelectPlantModule
no módulo que será utilizado e empacotar todas as rotas dentro de uma validação canActivate
utilizando o serviço ValidatePlant
que deve estar no array de providers do módulo.
Segue exemplo:
export const routes: Routes = [
{
path: "",
canActivate: [ ValidatePlant ],
children: [
/*
* Rotas da aplicação
*/
]
}
];
@NgModule({
imports: [
// Módulo da aplicação
RouterModule.forChild(routes),
SelectPlantModule
],
providers: [
ValidatePlant
]
})
export class AppModule {}
Dessa maneira, qualquer caminho que direcione para alguma das rotas da aplicação, primeiramente vai ser validado se a planta já foi selecionada ou não.
Para saber qual planta foi selecionada pelo usuário, é necessário a utilização do serviço SelectPlantService
. Para isso, pode-se injetar o serviço dentro de um componente e após isso, chamar o método getPlant()
. Segue exemplo.
@Component({
// Configuração do componente
})
export class MyComponent {
constructor(private selectPlantService: SelectPlantService) {
let planta = selectPlantService.getPlant();
}
}
Também é possível verificar se a planta foi selecionada chamando o método isPresent()
do serviço SelectPlantService
.
Para que a tradução funcione, é necessário que algumas chaves sejam adicionadas no arquivo de internacionalização. Segue as chaves com um valor de exemplo já setado.
{
"nothing_found": "Nada encontrado",
"filter": "Filtrar",
"clear": "Limpar",
"select": "Selecionar",
"continue": "Continuar",
"select_plant": "Selecionar planta",
"yms.components.select_plant_title": "Selecione a planta",
"yms.components.select_plant_search_title": "Selecione a planta",
"yms.components.select_plant.plant_name": "Nome",
"yms.components.select_plant_empty_state": "Selecione a planta",
"yms.components.select_plant_empty_state_description": "É necessário selecionar a planta para acessar a Gestão de Pátio",
"yms.components.select_plant_has_plant": "Planta já selecionada",
"yms.components.select_plant_has_plant_description": "Sua sessão já possui uma planta selecionada"
}
Esse componente deve ser utilizado para exibir os anexos do agendamento. Ele dá a opção de fazer o download de um anexo.
Além de poder visualizar os anexos dentro de um componente específico ou dentro de um DynamicDialog
Para utilizar os componentes, deve ser importado o modulo AgendaAnexosModule
. Segue exemplo:
@NgModule({
...,
imports: [
...,
AgendaAnexosModule
]
})
export class MyModule {}
Para exibir os anexos diretamente na tela, utilize o componente agenda-anexos
no HTML. O componente espera 2 argumentos: anexos
e agendaId
<div>
<h1> Agenda </h1>
<agenda-anexos [anexos]="myAgenda.anexo" [agendaId]="myAgenda.id"></agenda-anexos>
</div>
A biblioteca já disponibiliza um componente para visualizar os anexos em um modal. Para isso faça os seguintes passos:
- Em seu módulo importe o seguinte módulo da biblioteca do primeng:
DynamicDialogModule
- Em seu componente adicione
DialogService
nos providers e injete ele no construtor
@Component({
...,
providers: [DialogService]
})
export class MyComponent {
constructor(private dialogService: DialogService) {
}
}
- Para abrir o modal, utilie o método
open
do objetodialogService
passando o componenteAgendaAnexosDialogComponent
como primeiro argumento. - No segundo argumento, devem ser passadas as configurações do modal. Na configuração
data
devem ser passados os seguintes campos:anexos
eagendaId
this.dialogService.open(AgendaAnexosDialogComponent, {
header: "myTitle",
width: "600px",
data: {
anexos: myAgenda.anexo,
agendaId: myAgenda.id
}
})