CRUDComponentBase Abstração para páginas de CRUD
Este abstração possui todos os métodos necessárias para uma página de CRUD, utilizando todo o potencial do Cat UI.
C (CREATE)
Para a parte de criação existe a opção padrão que é utilizando Dialog , ou, caso queira, poderá abrir uma Janela Lateral ou navegar para uma nova página.
Para abrir um dialog com seu formulário utilize o método openFormDialog.
O método openFormDialog utiliza por padrão o componente de formulários dinâmicos , permitindo a configuração de um Dialog com formulário sem a necessidade de criar arquivos para tal.
Copy import { CatCRUDComponentBase } from "@catrx/ui/common" ;
@ Component ({ ... })
export class PageExempleComponent extends CatCRUDComponentBase {
...
openDialog (data ?: any ) {
this .openFormDialog (
this .formService
.build < Cat >(data)
.text ( 'Raça' , 'race' , (builder) =>
builder .grid ( 6 ) .setRequired () .generate ()
)
.select ( 'Sexo' , 'sex' , (builder) =>
builder
.setOptions (CatSexSelectOptions)
.grid ( 6 )
.setRequired ()
.generate ()
)
.url ( 'URL da Foto' , 'photo' , (builder) =>
builder .setRequired () .generate ()
)
.onSubmit ((cat) => this . service .save (cat , data ?.id))
.generate () ,
!! data ,
{ title : 'Gato' }
);
}
}
Ao realizar o submit no formulário gerado, já será realizado o disparo de spinner no botão de submit junto com seu bloqueio ...após o retorno da API em caso de sucesso ou error um Snackbar será exibido de acordo e em caso de sucesso o Dialog será fechado e um comando de reloadList será disparado, em seguida o componente de Datatable será recarregado.
R (READ)
Para a parte de leitura, teremos aqui a utilização do componente de Datatable , onde teremos que configurar o mesmo, passando as colunas que serão exibidas, habilitando seletores, botões de ação e filtro.
Copy import { CatCRUDComponentBase } from "@catrx/ui/common" ;
@ Component ({ ... })
export class PageExempleComponent extends CatCRUDComponentBase {
filterConfig = this .filterFormBuilder
.search ( 'Filtro' , 'filter' , (builder) => builder .grid ( 3 ) .generate ())
.onChange ((data) => this . filterValueChanges$ .next ( data ?.filter))
.generate ();
listConfig = this .datatableService
.build ( this .filterValueChanges$ , (filter) =>
this . service .getDatatable (filter)
)
.setColumns ([ 'Foto' , 'Sexo' , 'Raça' ])
.setItemLine ({
columnIndex : 0 ,
component : (item) => new CatDynamicComponent (CatPhotoComponent , item .photo) ,
})
.setItemLine ({ columnIndex : 1 , text : (item) => item .sex })
.setItemLine ({ columnIndex : 2 , text : (item) => item .race })
.setActionButton ({
iconName : 'fa-solid fa-pencil' ,
tooltip : 'Editar' ,
fnAction : (item) => this .openDialog (item) ,
})
.getSelection ((selection) => ( this .selection = selection))
.getDatasource ((datasource) => ( this .datasource = datasource))
.hasSelection ()
.hasActions ()
.generate ();
...
}
A parte de leitura também existe a possibilidade de exportação em .csv ou .xlsx, e para isso, utilizaremos o método exportByService presente na abstração de Serviços HTTP .
Copy import { CatCRUDComponentBase } from "@catrx/ui/common" ;
@ Component ({ ... })
export class PageExempleComponent extends CatCRUDComponentBase {
...
export (filename : string ) : void {
this .exportByService ({
xlsx : { filename , sheetName : 'Gatos' }
} , this . service .export ());
}
}
Copy ...
< cat-form [config] = "filterConfig" ></ cat-form >
< cat-datatable [config] = "listConfig" >
...
< nav list-actions >
< cat-icon-button
*ngIf = "datasource?.length > 0"
(click) = "export('Lista de Gatos')"
icon = "fa-solid fa-download"
tooltip = "Exportar Lista" >
</ cat-icon-button >
</ nav >
</ cat-datatable >
U (UPDATE)
Terá a mesma implementação do Create , porém, precisará informar o objeto que deseja editar, para que após a abertura do formulário, o mesmo seja automaticamente preenchido e um comando de PUT seja enviado após o submit.
D (DELETE)
O componente de Datatable , possui em suas configurações, a opção de habilitar seletores ou incluir botões de ação . Aproveitando este recurso, iremos implementar a ação de DELETE por meio de seletores na lista.
Neste caso, todo a implementação para delete já está pronta para uso, bastando chamar pelo método deleteSelected por meio do click do botão.
Copy ...
< cat-datatable [config] = "listConfig" >
< nav list-checked-actions >
< cat-icon-button
(click) = "deleteSelected()"
icon = "fa-solid fa-trash-can"
tooltip = "Excluir Selecionados" >
</ cat-icon-button >
</ nav >
...
</ cat-datatable >
Overview
Implementação Completa
1. Implementando serviço HTTP
cat.interface.ts cat.service.ts
Copy import { CatFormListOptions } from "@catrx/ui/form" ;
export interface CatFilter {
filter ?: string ;
}
export interface Cat {
id ?: number ;
photo : string ;
race : string ;
sex : CatSexType ;
}
export type CatSexType = 'M' | 'F' ;
export const CatSexSelectOptions : CatFormListOptions [] = [
{ value : 'M' , name : 'Macho' } ,
{ value : 'F' , name : 'Fêmea' } ,
];
Copy import { Injectable } from "@angular/core" ;
import { CatServiceBase } from "@catrx/ui/common" ;
import { HttpClient } from '@angular/common/http' ;
import { Cat , CatFilter } from "./cat.interface" ;
import { CatDatatableDataHttpResponse } from "@catrx/ui/datatable" ;
import { map } from "rxjs/internal/operators/map" ;
import { Observable } from "rxjs/internal/Observable" ;
@ Injectable ({ providedIn : 'root' })
export class CatService extends CatServiceBase < CatFilter , Array < Cat > , Cat > {
constructor (http : HttpClient ) {
super (http , 'cat' , {
useMockup : true ,
mockupStartBase : [
{
id : 1 ,
race : 'Frajola' ,
sex : 'M' ,
photo :
'https://static1.patasdacasa.com.br/articles/7/49/77/@/20775-o-gato-preto-e-branco-tem-um-charme-que-articles_media_mobile-2.jpg',
} ,
{
id : 2 ,
race : 'Tigrado' ,
sex : 'M' ,
photo :
'https://t1.ea.ltmcdn.com/pt/posts/1/2/6/4_gato_europeu_23621_3_600.jpg' ,
} ,
{
id : 3 ,
race : 'Branco' ,
sex : 'M' ,
photo :
'https://static1.patasdacasa.com.br/articles/5/29/95/@/12462-saiba-o-que-e-bolsa-primordial-e-sua-fun-articles_media_mobile-1.jpg',
} ,
] ,
});
}
public export () {
return this .exportByService (() => this .getDatatable ());
}
public getDatatable (filter ?: CatFilter ) : Observable < CatDatatableDataHttpResponse < Cat >> {
return this .getAll (filter) .pipe ( map (response => {
return {
count : response . length ,
items : response
};
}))
}
}
2. Implementando componente de foto
Copy import { Component } from '@angular/core' ;
import { CatDynamicComponentDataInterface } from '@catrx/ui/dynamic-component' ;
@ Component ({
template : `<img [src]="data" alt="Foto de Gato" width="100" height="100" />` ,
styles : [
`
img {
border-radius: 50%;
}
` ,
] ,
})
export class CatPhotoComponent implements CatDynamicComponentDataInterface {
data : string ;
}
3. Implementando componente de página
page-crud-example.component.html page-crud-example.component.ts
Copy < cat-toolbar [config] = "getToolbarInfo()" >
< nav buttons >
< cat-primary-button (click) = "openDialog()" >Incluir Gato</ cat-primary-button >
</ nav >
</ cat-toolbar >
< cat-form [config] = "filterConfig" ></ cat-form >
< cat-datatable [config] = "listConfig" >
< nav list-checked-actions >
< cat-icon-button
(click) = "deleteSelected()"
icon = "fa-solid fa-trash-can"
tooltip = "Excluir Selecionados" >
</ cat-icon-button >
</ nav >
< nav list-actions >
< cat-icon-button
*ngIf = "datasource?.length > 0"
(click) = "export('Lista de Gatos')"
icon = "fa-solid fa-download"
tooltip = "Exportar Lista" >
</ cat-icon-button >
</ nav >
</ cat-datatable >
Copy import { Component } from '@angular/core' ;
import { CatCRUDComponentBase } from '@catrx/ui/common' ;
import { CatConfirmService } from '@catrx/ui/confirm' ;
import { CatDatatableService } from '@catrx/ui/datatable' ;
import { CatDialogService } from '@catrx/ui/dialog' ;
import { CatDynamicComponent } from '@catrx/ui/dynamic-component' ;
import { CatFormService } from '@catrx/ui/form' ;
import { CatLoaderPageService } from '@catrx/ui/loader-page' ;
import { CatSnackbarService } from '@catrx/ui/snackbar' ;
import { CatCsvService , CatXlsxService } from '@catrx/ui/utils' ;
import { CatPhotoComponent } from './cat-photo.component' ;
import { Cat , CatFilter , CatSexSelectOptions } from './services/cat.interface' ;
import { CatService } from './services/cat.service' ;
@ Component ({
templateUrl : './page-crud-example.component.html' ,
styles : [
`
cat-form {
display: block;
margin: 20px 20px 10px;
}
` ,
] ,
})
export class PageCRUDExampleComponent extends CatCRUDComponentBase <
CatFilter ,
Cat
> {
filterConfig = this .filterFormBuilder
.search ( 'Filtro' , 'filter' , (builder) => builder .grid ( 3 ) .generate ())
.onChange ((data) => this . filterValueChanges$ .next ( data ?.filter))
.generate ();
listConfig = this .datatableService
.build ( this .filterValueChanges$ , (filter) =>
this . service .getDatatable (filter)
)
.setColumns ([ 'Foto' , 'Sexo' , 'Raça' ])
.setItemLine ({
columnIndex : 0 ,
component : (item) => new CatDynamicComponent (CatPhotoComponent , item .photo) ,
})
.setItemLine ({ columnIndex : 1 , text : (item) => item .sex })
.setItemLine ({ columnIndex : 2 , text : (item) => item .race })
.setActionButton ({
iconName : 'fa-solid fa-pencil' ,
tooltip : 'Editar' ,
fnAction : (item) => this .openDialog (item) ,
})
.getSelection ((selection) => ( this .selection = selection))
.getDatasource ((datasource) => ( this .datasource = datasource))
.hasSelection ()
.hasActions ()
.generate ();
constructor (
protected override service : CatService ,
formService : CatFormService ,
datatableService : CatDatatableService ,
dialogService : CatDialogService ,
confirmService : CatConfirmService ,
csvService : CatCsvService ,
xlsxService : CatXlsxService ,
loaderService : CatLoaderPageService ,
snackbarService : CatSnackbarService
) {
super (
formService ,
datatableService ,
service ,
loaderService ,
snackbarService ,
dialogService ,
confirmService ,
{ csv : csvService , xlsx : xlsxService }
);
}
export (filename : string ) : void {
this .exportByService ({
xlsx : { filename , sheetName : 'Gatos' }
} , this . service .export ());
}
openDialog (data ?: Cat ) {
this .openFormDialog (
this .formService
.build < Cat >(data)
.text ( 'Raça' , 'race' , (builder) =>
builder .grid ( 6 ) .setRequired () .generate ()
)
.select ( 'Sexo' , 'sex' , (builder) =>
builder
.setOptions (CatSexSelectOptions)
.grid ( 6 )
.setRequired ()
.generate ()
)
.url ( 'URL da Foto' , 'photo' , (builder) =>
builder .setRequired () .generate ()
)
.onSubmit ((cat) => this . service .save (cat , data ?.id))
.generate () ,
!! data ,
{ title : 'Gato' }
);
}
}
4. Implementando módulo
page-crud-example.module.ts
Copy import { NgModule } from '@angular/core' ;
import { PageCRUDExampleComponent } from './page-crud-example.component' ;
import { CommonModule } from '@angular/common' ;
import { CatToolbarModule } from '@catrx/ui/toolbar' ;
import { CatFormModule } from '@catrx/ui/form' ;
import { CatDatatableModule } from '@catrx/ui/datatable' ;
import { CatDialogModule } from '@catrx/ui/dialog' ;
import { CatConfirmModule } from '@catrx/ui/confirm' ;
import { PageCRUDExampleRoutingModule } from './page-crud-example.routing.module' ;
import { CatPrimaryButtonComponent } from '@catrx/ui/button' ;
import { CatIconButtonModule } from '@catrx/ui/icon-button' ;
import { CatPhotoComponent } from './cat-photo.component' ;
@ NgModule ({
declarations : [PageCRUDExampleComponent , CatPhotoComponent] ,
imports : [
CommonModule ,
CatToolbarModule ,
CatFormModule ,
CatDatatableModule ,
CatDialogModule ,
CatConfirmModule ,
CatIconButtonModule ,
CatPrimaryButtonComponent ,
PageCRUDExampleRoutingModule ,
] ,
})
export class PageCRUDExampleModule {}
5. Configurando xlsx
Copy import { NgModule } from '@angular/core' ;
import { AppRoutingModule } from './app-routing.module' ;
import { AppComponent } from './app.component' ;
import { CatUiModule } from '@catrx/ui/core' ;
import { environment } from '../environments/environment' ;
@ NgModule ({
declarations : [AppComponent] ,
imports : [ CatUiModule .forRoot (environment , {
xlsxConfig : {
headerBackgroundColor : '#212121' ,
headerFontColor : '#f1f1f1' ,
normalizeHeader : true
}
}) , AppRoutingModule] ,
bootstrap : [AppComponent] ,
})
export class AppModule {}