Skip to content

Instantly share code, notes, and snippets.

@Sutil
Created October 23, 2020 00:28
Show Gist options
  • Save Sutil/9fb9b0604c6575ffc31aee4d0a6e247d to your computer and use it in GitHub Desktop.
Save Sutil/9fb9b0604c6575ffc31aee4d0a6e247d to your computer and use it in GitHub Desktop.
<ng-template #conteudoDaLinha >
<tr class="{{ classeCss }}" >
<!-- percorrer cada coluna -->
<td *ngFor="let coluna of colunas; let i = index" class="{{ coluna.classeCss }}" >
<div class="conteudo-celula" >
<!-- Deve existir um recuo na linha dependendo de cada nível na tabela -->
<div *ngIf="i === 0" class="recuo-linha-filha-nivel-{{ nivel }}" ></div>
<!-- O botáo de expandir e retrair deve aparecer somente se for a primeira coluna e a linha tiver filhos -->
<button *ngIf="i === 0 && filhos && filhos.length > 0" class="seta" [class.expandido]="expandido" (click)="expandido = !expandido" ></button>
<!-- Em breve criaremos o componente que vai representar cada célula -->
<celula-tabela-aninhada [linha]="linha" [coluna]="coluna" ></celula-tabela-aninhada>
</div>
</td>
<!-- fim da coluna -->
</tr>
<!-- As linhas filhas só aparecem se estiver expandido -->
<ng-container *ngIf="expandido" >
<!-- percorrer as linhas filhas e chamar esse componente recursivamente -->
<ng-container *ngFor="let linhaFilha of filhos" >
<linha-tabela-aninhada
[linha]="linhaFilha"
[colunas]="colunas"
[extratorDeFilhos]="extratorDeFilhos"
[nivel]="nivel + 1"
[extratorDeClasseCss]="extratorDeClasseCss" ></linha-tabela-aninhada>
</ng-container>
</ng-container>
</ng-template>
td {
border-top: 1px solid #fff;
height: 30px;
line-height: 30px;
font-size: 13px;
.conteudo-celula {
display: flex;
align-items: center;
}
}
.seta {
background-color: transparent;
padding: 0;
outline: none;
width: 0;
height: 0;
border: 5px solid #777;
border-right-width: 0;
border-top-color: transparent;
border-bottom-color: transparent;
margin: 3px 5px 3px 3px;
cursor: pointer;
transition: transform 0.2s;
}
.seta.expandido {
transform: rotate(90deg);
}
/* definindo classes para os níveis 1 a 5 */
@for $i from 1 through 5 {
$recuo: 10px * $i;
.recuo-linha-filha-nivel-#{$i} {
width: $recuo;
display: inline-block;
}
}
import { Component, Input, OnInit, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';
import { ColunaTabelaAninhada } from '../coluna-tabela-aninhada';
@Component({
selector: 'linha-tabela-aninhada',
templateUrl: './linha-tabela-aninhada.component.html',
styleUrls: ['./linha-tabela-aninhada.component.scss']
})
export class LinhaTabelaAninhadaComponent implements OnInit {
@ViewChild('conteudoDaLinha', {static: true})
conteudoDaLinha: TemplateRef<any>;
/**
* Inoforme o objeto que representa a linha da tabela
*/
@Input()
linha: any;
/**
* Informe as colunas da tabela
*/
@Input()
colunas: ColunaTabelaAninhada[] = [];
/**
* Informe a função para extrair, de cada linha, as linhas filhas.
*/
@Input()
extratorDeFilhos: (linha: any) => any[] = (_:any) => null;
/**
* Informe a função para extrair, de cada linha, a classe de css customizada
*/
@Input()
extratorDeClasseCss: (nivel) => string;
/**
* Esse input vai ser chamado recursivamente para definir o nível de cada linha
*/
@Input()
nivel = 0;
filhos: any[] = [];
/**
* Define se a linha está expandida ou retraída.
*/
expandido = false;
/**
* Armazena a classe CSS da linha.
*/
classeCss = '';
constructor(private viewContainerRef: ViewContainerRef) { }
ngOnInit(): void {
this.viewContainerRef.createEmbeddedView(this.conteudoDaLinha);
this.extrairFilhos();
this.extrairClasseCss();
}
private extrairFilhos() {
if(this.extrairFilhos) {
this.filhos = this.extratorDeFilhos(this.linha);
}
}
private extrairClasseCss() {
if(this.extratorDeClasseCss) {
this.classeCss = this.extratorDeClasseCss(this.nivel);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment