Commit 8472f529 authored by RenanMontenegro3's avatar RenanMontenegro3

feat: ajustes em componentes de aceite, blacklist, navio, bercos e csv

parent 8533bdd0
import { TestBed } from '@angular/core/testing';
import { CsvService } from './csv.service';
describe('CsvService', () => {
let service: CsvService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(CsvService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CsvService {
public saveDataInCSV(data: Array<any>): string {
console.log(data)
if (!Array.isArray(data) || data.length === 0) {
console.warn('Nenhum dado disponível para exportação.');
return '';
}
let propertyNames = Object.keys(data[0]);
console.log(Object.keys(data[0]))
let rowWithPropertyNames = Object.keys(data[0]).join(';') + '\n';
let csvContent = rowWithPropertyNames;
let rows: string[] = [];
data.forEach((item) => {
let values: string[] = [];
propertyNames.forEach((key) => {
let val: any = item[key];
if (val !== undefined && val !== null) {
val = new String(val);
} else {
val = '';
}
values.push(val);
});
rows.push(values.join(';'));
});
csvContent += rows.join('\n');
return csvContent;
}
public importDataFromCSV(csvText: string): Array<any> {
const propertyNames = csvText.slice(0, csvText.indexOf('\n')).split(',');
const dataRows = csvText.slice(csvText.indexOf('\n') + 1).split('\n');
let dataArray: any[] = [];
dataRows.forEach((row) => {
let values = row.split(',');
let obj: any = new Object();
for (let index = 0; index < propertyNames.length; index++) {
const propertyName: string = propertyNames[index];
let val: any = values[index];
if (val === '') {
val = null;
}
obj[propertyName] = val;
}
dataArray.push(obj);
});
return dataArray;
}
}
......@@ -46,75 +46,61 @@
<div class="row">
<mat-form-field class="field medium" appearance="outline">
<mat-label>Calado de Entrada</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }" formControlName="calado_entrada">
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="calado_entrada">
<mat-error *ngIf="empForm.get('calado_entrada')?.invalid">{{ getErrorMessage('calado_entrada') }}</mat-error>
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Calado de Saída</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }" formControlName="calado_saida">
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="calado_saida">
<mat-error *ngIf="empForm.get('calado_saida')?.invalid">{{ getErrorMessage('calado_saida') }}</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field large" appearance="outline">
<mat-label>DWT (Atual)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="dwt">
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }" formControlName="dwt">
<mat-error *ngIf="empForm.get('dwt')?.invalid">{{ getErrorMessage('dwt') }}</mat-error>
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Pontal (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }" formControlName="pontal">
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="pontal">
<mat-error *ngIf="empForm.get('pontal')?.invalid">{{ getErrorMessage('pontal') }}</mat-error>
</mat-form-field>
<mat-form-field class="field small" appearance="outline">
<mat-label>Ponte Mfold (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }" formControlName="ponte_mfold">
<mat-error *ngIf="empForm.get('ponte_mfold')?.invalid">{{ getErrorMessage('ponte_mfold') }}</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field large" appearance="outline">
<mat-label>Mfold Quilha (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }" formControlName="mfold_quilha">
<mat-error *ngIf="empForm.get('mfold_quilha')?.invalid">{{ getErrorMessage('mfold_quilha') }}</mat-error>
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Categoria</mat-label>
<mat-select formControlName="categoria">
<mat-select formControlName="categoria" (selectionChange)="onCategoriaChange($event.value)">
<mat-option *ngFor="let cat of categoria" [value]="cat.id">
{{ cat.nome }}
</mat-option>
</mat-select>
<mat-error *ngIf="empForm.get('categoria')?.invalid">{{ getErrorMessage('categoria') }}</mat-error>
</mat-form-field>
<!-- Campo Mfold Quilha (m) só aparece se for Granel Líquido -->
<mat-form-field class="field large" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Mfold Quilha (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="mfold_quilha">
<mat-error *ngIf="empForm.get('mfold_quilha')?.invalid">{{ getErrorMessage('mfold_quilha') }}</mat-error>
</mat-form-field>
<mat-form-field class="field small" appearance="outline">
<mat-label>Flag</mat-label>
<mat-select formControlName="flag">
<mat-select-trigger>
<img
*ngIf="selectedCountry"
[src]="selectedCountry.flagUrl"
width="20"
height="15"
alt="{{ selectedCountry.name }} flag"
style="margin-right: 8px"
/>
<img *ngIf="selectedCountry" [src]="selectedCountry.flagUrl" width="20" height="15"
alt="{{ selectedCountry.name }} flag" style="margin-right: 8px" />
{{ selectedCountry?.name }}
</mat-select-trigger>
<mat-option
*ngFor="let country of countries"
[value]="country.id"
(onSelectionChange)="onCountrySelected(country)"
>
<img
[src]="country.flagUrl"
width="20"
height="15"
alt="{{ country.name }} flag"
style="margin-right: 8px"
/>
<mat-option *ngFor="let country of countries" [value]="country.id"
(onSelectionChange)="onCountrySelected(country)">
<img [src]="country.flagUrl" width="20" height="15" alt="{{ country.name }} flag"
style="margin-right: 8px" />
{{ country.name }}
</mat-option>
</mat-select>
......@@ -123,7 +109,15 @@
</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field small" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Ponte Mfold (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="ponte_mfold">
<mat-error *ngIf="empForm.get('ponte_mfold')?.invalid">{{ getErrorMessage('ponte_mfold') }}</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field full-width" appearance="outline">
<mat-label>Observação</mat-label>
......@@ -134,13 +128,7 @@
</div>
<div class="row file-upload-container">
<mat-label style="color:cadetblue">Adicione o documente Q88 da embarcação</mat-label>
<input
type="file"
class="file-input"
(change)="onFileSelected($event)"
#fileUpload
style="display: none"
/>
<input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload style="display: none" />
<div class="file-upload-content">
<div class="file-info">
......@@ -148,12 +136,7 @@
</div>
<div class="upload-button-wrapper">
<button
mat-mini-fab
color="primary"
class="upload-btn"
(click)="fileUpload.click()"
>
<button mat-mini-fab color="primary" class="upload-btn" (click)="fileUpload.click()">
<mat-icon>attach_file</mat-icon>
</button>
</div>
......@@ -161,17 +144,25 @@
<div class="uploaded-image-container" *ngIf="imageUrl">
<img [src]="imageUrl" alt="Uploaded Image" class="uploaded-image" />
<button
mat-mini-fab
color="warn"
class="remove-image-btn"
(click)="removeImage()"
>
<button mat-mini-fab color="warn" class="remove-image-btn" (click)="removeImage()">
<mat-icon>close</mat-icon>
</button>
</div>
</div>
<div class="row">
<mat-form-field class="field full-width" appearance="outline">
<mat-label>Berços</mat-label>
<mat-select formControlName="bercosSelecionados" multiple>
<mat-option *ngFor="let berco of bercosDisponiveis" [value]="berco.nome">
Berço {{ berco.nome }}
</mat-option>
</mat-select>
<mat-hint>Selecione um ou mais berços</mat-hint>
</mat-form-field>
</div>
</div>
<div mat-dialog-actions class="action">
<button mat-raised-button type="button" color="warn" [mat-dialog-close]="false">Cancelar</button>
<button mat-raised-button color="primary" type="submit">Salvar</button>
......
......@@ -20,6 +20,7 @@ import { Observable, catchError, distinctUntilChanged, map, of, switchMap, tap }
import { HttpClient } from '@angular/common/http';
import { ToastrService } from 'ngx-toastr';
import { NgxCurrencyDirective } from 'ngx-currency';
import { BercosService } from '../../../services/bercos/bercos.service';
@Component({
selector: 'app-aceite-add',
......@@ -36,7 +37,7 @@ import { NgxCurrencyDirective } from 'ngx-currency';
MatSelectModule,
MatRadioModule,
MatIconModule,
MatSnackBarModule,NgxCurrencyDirective
MatSnackBarModule, NgxCurrencyDirective
],
templateUrl: './aceite-add.component.html',
styleUrls: ['./aceite-add.component.scss']
......@@ -61,11 +62,12 @@ export class AceiteAddComponent implements OnInit {
private _dialog: MatDialog,
private http: HttpClient,
private toastService: ToastrService,
private _bercoService: BercosService // Injetando o serviço de berços
) {
this.empForm = this._fb.group({
imo: [data ? data.imo : '', Validators.required, this.ImoValidator()],
mmsi: [data ? data.mmsi : '', ],
mmsi: [data ? data.mmsi : '',],
nome: [data ? data.nome : '', Validators.required],
loa: [data ? data.loa : '', Validators.required],
boca: [data ? data.boca : '', Validators.required],
......@@ -76,8 +78,21 @@ export class AceiteAddComponent implements OnInit {
categoria: [data ? data.categoria : '', Validators.required],
flag: [data ? data.flag : '', Validators.required],
obs: [data ? data.obs : ''],
calado_entrada:[ '', Validators.required],
calado_saida:['', Validators.required],
calado_entrada: ['', Validators.required],
calado_saida: ['', Validators.required],
bercosSelecionados: ['']
,
});
this.empForm.get('categoria')?.valueChanges.subscribe(catId => {
const cat = this.categoria.find((c: any) => c.id === catId);
if (cat && cat.nome === 'Granel Líquido') {
this.empForm.get('mfold_quilha')?.setValidators([Validators.required]);
this.empForm.get('ponte_mfold')?.setValidators([Validators.required]);
} else {
this.empForm.get('mfold_quilha')?.clearValidators();
this.empForm.get('ponte_mfold')?.clearValidators();
}
this.empForm.get('mfold_quilha')?.updateValueAndValidity();
});
}
......@@ -86,6 +101,8 @@ export class AceiteAddComponent implements OnInit {
event.preventDefault();
}
}
countries = [
{ id: 1, name: 'Afeganistão', flagUrl: 'https://flagcdn.com/w20/af.png' },
{ id: 2, name: 'África do Sul', flagUrl: 'https://flagcdn.com/w20/za.png' },
......@@ -427,11 +444,24 @@ export class AceiteAddComponent implements OnInit {
onCountrySelected(country: { id: number; name: string; flagUrl: string }) {
this.selectedCountry = country;
}
bercosDisponiveis: any[] = [];
ngOnInit(): void {
if (this.data) {
this.empForm.patchValue(this.data);
}
this._bercoService.getBercosListSemPaginacao().subscribe({
next: (res) => {
console.log(res)
// Ajuste para consumir do _embedded.bercoResponseList
this.bercosDisponiveis = res && res._embedded && res._embedded.bercoResponseList
? res._embedded.bercoResponseList
: [];
console.log(this.bercosDisponiveis);
},
error: () => {
this.bercosDisponiveis = [];
}
});
this.empForm.get('imo')?.valueChanges
.pipe(
distinctUntilChanged(),
......@@ -470,7 +500,8 @@ export class AceiteAddComponent implements OnInit {
this.imageUrl = (e.target?.result as string) || '';
};
reader.readAsDataURL(file);
}}
}
}
removeImage() {
this.imageUrl = null;
this.fileName = '';
......@@ -492,7 +523,12 @@ export class AceiteAddComponent implements OnInit {
);
};
}
selectedCategoriaNome: string = '';
onCategoriaChange(catId: any) {
const cat = this.categoria.find((c: any) => c.id === catId);
this.selectedCategoriaNome = cat ? cat.nome : '';
}
getErrorMessage(formControlName: string): string {
if (this.empForm.get(formControlName)?.hasError('required')) {
return 'Campo obrigatório';
......@@ -516,7 +552,7 @@ export class AceiteAddComponent implements OnInit {
if (this.empForm.valid) {
if (this.selectedFile) {
this._empService.addAceite(this.empForm.value,this.selectedFile).subscribe({
this._empService.addAceite(this.empForm.value, this.selectedFile).subscribe({
next: () => {
this._dialogRef.close(true);
this.toastService.success('Aceite cadastrado com sucesso!');
......@@ -526,7 +562,7 @@ export class AceiteAddComponent implements OnInit {
},
});
} else {
this._empService.addAceite(this.empForm.value,null).subscribe({
this._empService.addAceite(this.empForm.value, null).subscribe({
next: () => {
this._dialogRef.close(true);
this.toastService.success('Aceite cadastrado com sucesso!');
......@@ -534,7 +570,8 @@ export class AceiteAddComponent implements OnInit {
error: (err: any) => {
console.error(err);
},
}); }
});
}
}
}
}
......
<div mat-dialog-title>
<h1>{{ "Buscar Aceite" }}</h1>
</div>
</div>
<form [formGroup]="empForm" (ngSubmit)="onFormSubmit()">
<form [formGroup]="empForm" (ngSubmit)="onFormSubmit()">
<div mat-dialog-content class="content">
<div class="row">
<!-- IMO -->
<mat-form-field class="field full-width" appearance="outline">
<mat-label>IMO</mat-label>
<input
matInput
type="number"
(keydown)="preventNegative($event)"
min="0"
formControlName="imo"
/>
<input matInput type="number" (keydown)="preventNegative($event)" min="0" formControlName="imo" />
<mat-error *ngIf="empForm.get('imo')?.invalid">{{
getErrorMessage("imo")
}}</mat-error>
</mat-form-field>
</div>
<!--
<!--
<div class="row">
<mat-form-field class="field medium" appearance="outline">
<mat-label>Categoria</mat-label>
......@@ -71,17 +65,22 @@
</div>
-->
<div class="row">
<mat-form-field class="field medium" appearance="outline">
<mat-label>Data de Início</mat-label>
<input matInput type="date" formControlName="dataInicio" />
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Data de Fim</mat-label>
<input matInput type="date" formControlName="dataFim" />
</mat-form-field>
</div>
</div>
<div mat-dialog-actions class="action">
<button
mat-raised-button
type="button"
color="warn"
[mat-dialog-close]="false"
>
<button mat-raised-button type="button" color="warn" [mat-dialog-close]="false">
Cancelar
</button>
<button mat-raised-button color="primary" type="submit">Buscar</button>
</div>
</form>
\ No newline at end of file
</form>
......@@ -47,7 +47,7 @@ export class AceiteSearchComponent implements OnInit {
empForm: FormGroup;
selectedFile: File | null = null;
categoria: number[] = [1, 2,3];
categoria: number[] = [1, 2, 3];
constructor(
private _fb: FormBuilder,
......@@ -60,8 +60,9 @@ export class AceiteSearchComponent implements OnInit {
) {
this.empForm = this._fb.group({
imo: [''],
categoria: [''],
flag: [''],
dataInicio: [''],
dataFim: [''],
// ...outros campos...
});
}
......@@ -95,7 +96,8 @@ export class AceiteSearchComponent implements OnInit {
this.imageUrl = (e.target?.result as string) || '';
};
reader.readAsDataURL(file);
}}
}
}
getErrorMessage(formControlName: string): string {
if (this.empForm.get(formControlName)?.hasError('required')) {
......@@ -451,8 +453,8 @@ export class AceiteSearchComponent implements OnInit {
if (this.empForm.valid) {
const searchCriteria = {
imo: this.empForm.value.imo,
categoria: this.empForm.value.categoria,
flag: this.empForm.value.flag,
dataInicio: this.empForm.value.dataInicio,
dataFim: this.empForm.value.dataFim,
};
this._empService.searchAceite(searchCriteria).subscribe({
......
......@@ -3,7 +3,14 @@
[secondaryButtonColor]="'accent'" [secondaryButtonAction]="openSearchBercoForm.bind(this)">
</app-add-search>
<!-- Botão Exportar Excel Verde -->
<div class="main-body">
<button mat-raised-button color="primary" style="background-color: #43a047; color: #fff; margin: 12px 0;" (click)="saveDataInCSV('aceites')">
<mat-icon>download</mat-icon>
Exportar Excel
</button>
<div class="table-container" style="overflow-x: auto">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
......
......@@ -26,6 +26,7 @@ import { AceiteSearchComponent } from '../aceite-search/aceite-search.component'
import { JwtDecoderService } from '../../../jwt-decoder.service';
import { AuthService } from '../../../auth.service';
import { jwtDecode } from 'jwt-decode';
import { CsvService } from '../../../csv.service';
interface AceiteData {
id: number;
imo: number;
......@@ -88,11 +89,13 @@ export class AceitesComponent implements OnInit {
private _coreService: CoreService,
private jwtDecoderService: JwtDecoderService,
private authService: AuthService,
private cdr: ChangeDetectorRef
private cdr: ChangeDetectorRef,
private _csvService: CsvService
) {}
) { }
ngOnInit(): void { this.validationToken();
ngOnInit(): void {
this.validationToken();
}
ngAfterViewInit(): void {
......@@ -109,6 +112,343 @@ export class AceitesComponent implements OnInit {
}
return null;
}
countries = [
{ id: 1, name: 'Afeganistão', flagUrl: 'https://flagcdn.com/w20/af.png' },
{ id: 2, name: 'África do Sul', flagUrl: 'https://flagcdn.com/w20/za.png' },
{ id: 3, name: 'Albânia', flagUrl: 'https://flagcdn.com/w20/al.png' },
{ id: 4, name: 'Alemanha', flagUrl: 'https://flagcdn.com/w20/de.png' },
{ id: 5, name: 'Andorra', flagUrl: 'https://flagcdn.com/w20/ad.png' },
{ id: 6, name: 'Angola', flagUrl: 'https://flagcdn.com/w20/ao.png' },
{
id: 7,
name: 'Antígua e Barbuda',
flagUrl: 'https://flagcdn.com/w20/ag.png',
},
{
id: 8,
name: 'Arábia Saudita',
flagUrl: 'https://flagcdn.com/w20/sa.png',
},
{ id: 9, name: 'Argélia', flagUrl: 'https://flagcdn.com/w20/dz.png' },
{ id: 10, name: 'Argentina', flagUrl: 'https://flagcdn.com/w20/ar.png' },
{ id: 11, name: 'Armênia', flagUrl: 'https://flagcdn.com/w20/am.png' },
{ id: 12, name: 'Austrália', flagUrl: 'https://flagcdn.com/w20/au.png' },
{ id: 13, name: 'Áustria', flagUrl: 'https://flagcdn.com/w20/at.png' },
{ id: 14, name: 'Azerbaijão', flagUrl: 'https://flagcdn.com/w20/az.png' },
{ id: 15, name: 'Bahamas', flagUrl: 'https://flagcdn.com/w20/bs.png' },
{ id: 16, name: 'Bahrein', flagUrl: 'https://flagcdn.com/w20/bh.png' },
{ id: 17, name: 'Bangladesh', flagUrl: 'https://flagcdn.com/w20/bd.png' },
{ id: 18, name: 'Barbados', flagUrl: 'https://flagcdn.com/w20/bb.png' },
{ id: 19, name: 'Bélgica', flagUrl: 'https://flagcdn.com/w20/be.png' },
{ id: 20, name: 'Belize', flagUrl: 'https://flagcdn.com/w20/bz.png' },
{ id: 21, name: 'Benin', flagUrl: 'https://flagcdn.com/w20/bj.png' },
{ id: 22, name: 'Bielorrússia', flagUrl: 'https://flagcdn.com/w20/by.png' },
{ id: 23, name: 'Bolívia', flagUrl: 'https://flagcdn.com/w20/bo.png' },
{
id: 24,
name: 'Bósnia e Herzegovina',
flagUrl: 'https://flagcdn.com/w20/ba.png',
},
{ id: 25, name: 'Botswana', flagUrl: 'https://flagcdn.com/w20/bw.png' },
{ id: 26, name: 'Brasil', flagUrl: 'https://flagcdn.com/w20/br.png' },
{ id: 27, name: 'Brunei', flagUrl: 'https://flagcdn.com/w20/bn.png' },
{ id: 28, name: 'Bulgária', flagUrl: 'https://flagcdn.com/w20/bg.png' },
{ id: 29, name: 'Burkina Faso', flagUrl: 'https://flagcdn.com/w20/bf.png' },
{ id: 30, name: 'Burundi', flagUrl: 'https://flagcdn.com/w20/bi.png' },
{ id: 31, name: 'Butão', flagUrl: 'https://flagcdn.com/w20/bt.png' },
{ id: 32, name: 'Cabo Verde', flagUrl: 'https://flagcdn.com/w20/cv.png' },
{ id: 33, name: 'Camboja', flagUrl: 'https://flagcdn.com/w20/kh.png' },
{ id: 34, name: 'Camarões', flagUrl: 'https://flagcdn.com/w20/cm.png' },
{ id: 35, name: 'Canadá', flagUrl: 'https://flagcdn.com/w20/ca.png' },
{ id: 36, name: 'Catar', flagUrl: 'https://flagcdn.com/w20/qa.png' },
{ id: 37, name: 'Cazaquistão', flagUrl: 'https://flagcdn.com/w20/kz.png' },
{ id: 38, name: 'Chade', flagUrl: 'https://flagcdn.com/w20/td.png' },
{ id: 39, name: 'Chile', flagUrl: 'https://flagcdn.com/w20/cl.png' },
{ id: 40, name: 'China', flagUrl: 'https://flagcdn.com/w20/cn.png' },
{ id: 41, name: 'Chipre', flagUrl: 'https://flagcdn.com/w20/cy.png' },
{ id: 42, name: 'Colômbia', flagUrl: 'https://flagcdn.com/w20/co.png' },
{ id: 43, name: 'Comores', flagUrl: 'https://flagcdn.com/w20/km.png' },
{ id: 44, name: 'Congo', flagUrl: 'https://flagcdn.com/w20/cg.png' },
{
id: 45,
name: 'Costa do Marfim',
flagUrl: 'https://flagcdn.com/w20/ci.png',
},
{ id: 46, name: 'Costa Rica', flagUrl: 'https://flagcdn.com/w20/cr.png' },
{ id: 47, name: 'Croácia', flagUrl: 'https://flagcdn.com/w20/hr.png' },
{ id: 48, name: 'Cuba', flagUrl: 'https://flagcdn.com/w20/cu.png' },
{ id: 49, name: 'Dinamarca', flagUrl: 'https://flagcdn.com/w20/dk.png' },
{ id: 50, name: 'Dominica', flagUrl: 'https://flagcdn.com/w20/dm.png' },
{ id: 51, name: 'Egito', flagUrl: 'https://flagcdn.com/w20/eg.png' },
{ id: 52, name: 'El Salvador', flagUrl: 'https://flagcdn.com/w20/sv.png' },
{
id: 53,
name: 'Emirados Árabes Unidos',
flagUrl: 'https://flagcdn.com/w20/ae.png',
},
{ id: 54, name: 'Equador', flagUrl: 'https://flagcdn.com/w20/ec.png' },
{ id: 55, name: 'Eritreia', flagUrl: 'https://flagcdn.com/w20/er.png' },
{ id: 56, name: 'Eslováquia', flagUrl: 'https://flagcdn.com/w20/sk.png' },
{ id: 57, name: 'Eslovênia', flagUrl: 'https://flagcdn.com/w20/si.png' },
{ id: 58, name: 'Espanha', flagUrl: 'https://flagcdn.com/w20/es.png' },
{
id: 59,
name: 'Estados Unidos',
flagUrl: 'https://flagcdn.com/w20/us.png',
},
{ id: 60, name: 'Estônia', flagUrl: 'https://flagcdn.com/w20/ee.png' },
{ id: 61, name: 'Eswatini', flagUrl: 'https://flagcdn.com/w20/sz.png' },
{ id: 62, name: 'Etiópia', flagUrl: 'https://flagcdn.com/w20/et.png' },
{ id: 63, name: 'Fiji', flagUrl: 'https://flagcdn.com/w20/fj.png' },
{ id: 64, name: 'Filipinas', flagUrl: 'https://flagcdn.com/w20/ph.png' },
{ id: 65, name: 'Finlândia', flagUrl: 'https://flagcdn.com/w20/fi.png' },
{ id: 66, name: 'França', flagUrl: 'https://flagcdn.com/w20/fr.png' },
{ id: 67, name: 'Guatemala', flagUrl: 'https://flagcdn.com/w20/gt.png' },
{ id: 68, name: 'Guiana', flagUrl: 'https://flagcdn.com/w20/gf.png' },
{ id: 69, name: 'Guiné', flagUrl: 'https://flagcdn.com/w20/gn.png' },
{ id: 70, name: 'Guiné-Bissau', flagUrl: 'https://flagcdn.com/w20/gw.png' },
{ id: 71, name: 'Haiti', flagUrl: 'https://flagcdn.com/w20/ht.png' },
{ id: 72, name: 'Honduras', flagUrl: 'https://flagcdn.com/w20/hn.png' },
{ id: 73, name: 'Hungria', flagUrl: 'https://flagcdn.com/w20/hu.png' },
{ id: 74, name: 'Iêmen', flagUrl: 'https://flagcdn.com/w20/ye.png' },
{
id: 75,
name: 'Ilhas Marshall',
flagUrl: 'https://flagcdn.com/w20/mh.png',
},
{
id: 76,
name: 'Ilhas Salomão',
flagUrl: 'https://flagcdn.com/w20/sb.png',
},
{ id: 77, name: 'Índia', flagUrl: 'https://flagcdn.com/w20/in.png' },
{ id: 78, name: 'Indonésia', flagUrl: 'https://flagcdn.com/w20/id.png' },
{ id: 79, name: 'Irã', flagUrl: 'https://flagcdn.com/w20/ir.png' },
{ id: 80, name: 'Iraque', flagUrl: 'https://flagcdn.com/w20/iq.png' },
{ id: 81, name: 'Irlanda', flagUrl: 'https://flagcdn.com/w20/ie.png' },
{ id: 82, name: 'Islândia', flagUrl: 'https://flagcdn.com/w20/is.png' },
{ id: 83, name: 'Israel', flagUrl: 'https://flagcdn.com/w20/il.png' },
{ id: 84, name: 'Itália', flagUrl: 'https://flagcdn.com/w20/it.png' },
{ id: 85, name: 'Jamaica', flagUrl: 'https://flagcdn.com/w20/jm.png' },
{ id: 86, name: 'Japão', flagUrl: 'https://flagcdn.com/w20/jp.png' },
{ id: 87, name: 'Jordânia', flagUrl: 'https://flagcdn.com/w20/jo.png' },
{ id: 88, name: 'Kosovo', flagUrl: 'https://flagcdn.com/w20/xk.png' },
{ id: 89, name: 'Kuwait', flagUrl: 'https://flagcdn.com/w20/kw.png' },
{ id: 90, name: 'Quirguistão', flagUrl: 'https://flagcdn.com/w20/kg.png' },
{ id: 91, name: 'Laos', flagUrl: 'https://flagcdn.com/w20/la.png' },
{ id: 92, name: 'Letônia', flagUrl: 'https://flagcdn.com/w20/lv.png' },
{ id: 93, name: 'Líbano', flagUrl: 'https://flagcdn.com/w20/lb.png' },
{ id: 94, name: 'Lesoto', flagUrl: 'https://flagcdn.com/w20/ls.png' },
{ id: 95, name: 'Libéria', flagUrl: 'https://flagcdn.com/w20/lr.png' },
{ id: 96, name: 'Líbia', flagUrl: 'https://flagcdn.com/w20/ly.png' },
{
id: 97,
name: 'Liechtenstein',
flagUrl: 'https://flagcdn.com/w20/li.png',
},
{ id: 98, name: 'Lituânia', flagUrl: 'https://flagcdn.com/w20/lt.png' },
{ id: 99, name: 'Luxemburgo', flagUrl: 'https://flagcdn.com/w20/lu.png' },
{
id: 100,
name: 'Macedônia do Norte',
flagUrl: 'https://flagcdn.com/w20/mk.png',
},
{ id: 101, name: 'Madagascar', flagUrl: 'https://flagcdn.com/w20/mg.png' },
{ id: 102, name: 'Malawi', flagUrl: 'https://flagcdn.com/w20/mw.png' },
{ id: 103, name: 'Malásia', flagUrl: 'https://flagcdn.com/w20/my.png' },
{ id: 104, name: 'Maldivas', flagUrl: 'https://flagcdn.com/w20/mv.png' },
{ id: 105, name: 'Mali', flagUrl: 'https://flagcdn.com/w20/ml.png' },
{ id: 106, name: 'Malta', flagUrl: 'https://flagcdn.com/w20/mt.png' },
{ id: 107, name: 'Mauritânia', flagUrl: 'https://flagcdn.com/w20/mr.png' },
{ id: 108, name: 'Maurício', flagUrl: 'https://flagcdn.com/w20/mu.png' },
{ id: 109, name: 'México', flagUrl: 'https://flagcdn.com/w20/mx.png' },
{ id: 110, name: 'Micronésia', flagUrl: 'https://flagcdn.com/w20/fm.png' },
{ id: 111, name: 'Moldávia', flagUrl: 'https://flagcdn.com/w20/md.png' },
{ id: 112, name: 'Mônaco', flagUrl: 'https://flagcdn.com/w20/mc.png' },
{ id: 113, name: 'Mongólia', flagUrl: 'https://flagcdn.com/w20/mn.png' },
{ id: 114, name: 'Montenegro', flagUrl: 'https://flagcdn.com/w20/me.png' },
{ id: 115, name: 'Marrocos', flagUrl: 'https://flagcdn.com/w20/ma.png' },
{ id: 116, name: 'Moçambique', flagUrl: 'https://flagcdn.com/w20/mz.png' },
{ id: 117, name: 'Myanmar', flagUrl: 'https://flagcdn.com/w20/mm.png' },
{ id: 118, name: 'Namíbia', flagUrl: 'https://flagcdn.com/w20/na.png' },
{ id: 119, name: 'Nauru', flagUrl: 'https://flagcdn.com/w20/nr.png' },
{ id: 120, name: 'Nepal', flagUrl: 'https://flagcdn.com/w20/np.png' },
{
id: 121,
name: 'Países Baixos',
flagUrl: 'https://flagcdn.com/w20/nl.png',
},
{
id: 122,
name: 'Nova Zelândia',
flagUrl: 'https://flagcdn.com/w20/nz.png',
},
{ id: 123, name: 'Nicarágua', flagUrl: 'https://flagcdn.com/w20/ni.png' },
{ id: 124, name: 'Níger', flagUrl: 'https://flagcdn.com/w20/ne.png' },
{ id: 125, name: 'Nigéria', flagUrl: 'https://flagcdn.com/w20/ng.png' },
{ id: 126, name: 'Noruega', flagUrl: 'https://flagcdn.com/w20/no.png' },
{ id: 127, name: 'Omã', flagUrl: 'https://flagcdn.com/w20/om.png' },
{ id: 128, name: 'Paquistão', flagUrl: 'https://flagcdn.com/w20/pk.png' },
{ id: 129, name: 'Palau', flagUrl: 'https://flagcdn.com/w20/pw.png' },
{ id: 130, name: 'Palestina', flagUrl: 'https://flagcdn.com/w20/ps.png' },
{ id: 131, name: 'Panamá', flagUrl: 'https://flagcdn.com/w20/pa.png' },
{
id: 132,
name: 'Papua Nova Guiné',
flagUrl: 'https://flagcdn.com/w20/pg.png',
},
{ id: 133, name: 'Paraguai', flagUrl: 'https://flagcdn.com/w20/py.png' },
{ id: 134, name: 'Peru', flagUrl: 'https://flagcdn.com/w20/pe.png' },
{ id: 135, name: 'Polônia', flagUrl: 'https://flagcdn.com/w20/pl.png' },
{ id: 136, name: 'Portugal', flagUrl: 'https://flagcdn.com/w20/pt.png' },
{ id: 137, name: 'Reino Unido', flagUrl: 'https://flagcdn.com/w20/gb.png' },
{
id: 138,
name: 'República Centro-Africana',
flagUrl: 'https://flagcdn.com/w20/cf.png',
},
{
id: 139,
name: 'República Dominicana',
flagUrl: 'https://flagcdn.com/w20/do.png',
},
{ id: 140, name: 'Romênia', flagUrl: 'https://flagcdn.com/w20/ro.png' },
{ id: 141, name: 'Ruanda', flagUrl: 'https://flagcdn.com/w20/rw.png' },
{ id: 142, name: 'Rússia', flagUrl: 'https://flagcdn.com/w20/ru.png' },
{
id: 143,
name: 'São Cristóvão e Nevis',
flagUrl: 'https://flagcdn.com/w20/kn.png',
},
{ id: 144, name: 'São Marino', flagUrl: 'https://flagcdn.com/w20/sm.png' },
{
id: 145,
name: 'São Tomé e Príncipe',
flagUrl: 'https://flagcdn.com/w20/st.png',
},
{
id: 146,
name: 'São Vicente e Granadinas',
flagUrl: 'https://flagcdn.com/w20/vc.png',
},
{ id: 147, name: 'Santa Lúcia', flagUrl: 'https://flagcdn.com/w20/lc.png' },
{ id: 148, name: 'Senegal', flagUrl: 'https://flagcdn.com/w20/sn.png' },
{ id: 149, name: 'Sérvia', flagUrl: 'https://flagcdn.com/w20/rs.png' },
{ id: 150, name: 'Seychelles', flagUrl: 'https://flagcdn.com/w20/sc.png' },
{ id: 151, name: 'Singapura', flagUrl: 'https://flagcdn.com/w20/sg.png' },
{ id: 152, name: 'Síria', flagUrl: 'https://flagcdn.com/w20/sy.png' },
{ id: 153, name: 'Somália', flagUrl: 'https://flagcdn.com/w20/so.png' },
{ id: 154, name: 'Sri Lanka', flagUrl: 'https://flagcdn.com/w20/lk.png' },
{ id: 155, name: 'Sudão', flagUrl: 'https://flagcdn.com/w20/sd.png' },
{
id: 156,
name: 'Sudão do Sul',
flagUrl: 'https://flagcdn.com/w20/ss.png',
},
{ id: 157, name: 'Suriname', flagUrl: 'https://flagcdn.com/w20/sr.png' },
{ id: 158, name: 'Suécia', flagUrl: 'https://flagcdn.com/w20/se.png' },
{ id: 159, name: 'Suíça', flagUrl: 'https://flagcdn.com/w20/ch.png' },
{ id: 160, name: 'Tajiquistão', flagUrl: 'https://flagcdn.com/w20/tj.png' },
{ id: 161, name: 'Tailândia', flagUrl: 'https://flagcdn.com/w20/th.png' },
{ id: 162, name: 'Timor-Leste', flagUrl: 'https://flagcdn.com/w20/tl.png' },
{ id: 163, name: 'Togo', flagUrl: 'https://flagcdn.com/w20/tg.png' },
{ id: 164, name: 'Tonga', flagUrl: 'https://flagcdn.com/w20/to.png' },
{
id: 165,
name: 'Trinidad e Tobago',
flagUrl: 'https://flagcdn.com/w20/tt.png',
},
{ id: 166, name: 'Tunísia', flagUrl: 'https://flagcdn.com/w20/tn.png' },
{ id: 167, name: 'Turquia', flagUrl: 'https://flagcdn.com/w20/tr.png' },
{
id: 168,
name: 'Turcomenistão',
flagUrl: 'https://flagcdn.com/w20/tm.png',
},
{ id: 169, name: 'Tuvalu', flagUrl: 'https://flagcdn.com/w20/tv.png' },
{ id: 170, name: 'Ucrânia', flagUrl: 'https://flagcdn.com/w20/ua.png' },
{ id: 171, name: 'Uganda', flagUrl: 'https://flagcdn.com/w20/ug.png' },
{ id: 172, name: 'Uruguai', flagUrl: 'https://flagcdn.com/w20/uy.png' },
{ id: 173, name: 'Uzbequistão', flagUrl: 'https://flagcdn.com/w20/uz.png' },
{ id: 174, name: 'Vanuatu', flagUrl: 'https://flagcdn.com/w20/vu.png' },
{ id: 175, name: 'Vaticano', flagUrl: 'https://flagcdn.com/w20/va.png' },
{ id: 176, name: 'Venezuela', flagUrl: 'https://flagcdn.com/w20/ve.png' },
{ id: 177, name: 'Vietnã', flagUrl: 'https://flagcdn.com/w20/vn.png' },
{ id: 178, name: 'Zâmbia', flagUrl: 'https://flagcdn.com/w20/zm.png' },
{ id: 179, name: 'Zimbábue', flagUrl: 'https://flagcdn.com/w20/zw.png' },
{
id: 180,
name: 'São Bartolomeu',
flagUrl: 'https://flagcdn.com/w20/bl.png',
},
{
id: 181,
name: 'Santa Helena, Ascensão e Tristão da Cunha',
flagUrl: 'https://flagcdn.com/w20/sh.png',
},
{
id: 182,
name: 'Território Britânico do Oceano Índico',
flagUrl: 'https://flagcdn.com/w20/io.png',
},
{
id: 183,
name: 'Ilhas Cayman',
flagUrl: 'https://flagcdn.com/w20/ky.png',
},
{
id: 184,
name: 'Ilhas Cocos (Keeling)',
flagUrl: 'https://flagcdn.com/w20/cc.png',
},
{ id: 185, name: 'Ilhas Cook', flagUrl: 'https://flagcdn.com/w20/ck.png' },
{ id: 186, name: 'Ilhas Feroé', flagUrl: 'https://flagcdn.com/w20/fo.png' },
{
id: 187,
name: 'Ilhas Georgianas do Sul e Sandwich do Sul',
flagUrl: 'https://flagcdn.com/w20/gs.png',
},
{
id: 188,
name: 'Ilhas Heard e Ilhas McDonald',
flagUrl: 'https://flagcdn.com/w20/hm.png',
},
{
id: 189,
name: 'Ilhas Malvinas',
flagUrl: 'https://flagcdn.com/w20/fk.png',
},
{
id: 190,
name: 'Ilhas Marianas do Norte',
flagUrl: 'https://flagcdn.com/w20/mp.png',
},
{
id: 191,
name: 'Ilhas Menores dos Estados Unidos',
flagUrl: 'https://flagcdn.com/w20/us.png',
},
{
id: 192,
name: 'Ilhas Pitcairn',
flagUrl: 'https://flagcdn.com/w20/pn.png',
},
{
id: 193,
name: 'Ilhas Virgens Americanas',
flagUrl: 'https://flagcdn.com/w20/vi.png',
},
{
id: 194,
name: 'Ilhas Virgens Britânicas',
flagUrl: 'https://flagcdn.com/w20/vg.png',
},
{
id: 195,
name: 'Samoa Americana',
flagUrl: 'https://flagcdn.com/w20/as.png',
},
];
loadData(event?: PageEvent): void {
if (typeof sessionStorage !== 'undefined') {
const storedData = sessionStorage.getItem('aceitesSearch');
......@@ -219,10 +559,12 @@ export class AceitesComponent implements OnInit {
//
openAddBercoForm() {
this._dialog.open(AceiteAddComponent,{autoFocus: true, // Foca no primeiro campo interativo do formulário
this._dialog.open(AceiteAddComponent, {
autoFocus: true, // Foca no primeiro campo interativo do formulário
disableClose: true, // Impede que o diálogo feche ao clicar fora
width: '600px', // Define a largura do diálogo});
});}
});
}
getBercoById(data: any) {
this._dialog.open(VisualizacaoAceiteComponent, {
......@@ -250,4 +592,93 @@ export class AceitesComponent implements OnInit {
this.cdr.detectChanges();
});
}
public saveDataInCSV(name: string): void {
this._aceiteService.getAllAceitesSemPaginacao().subscribe({
next: (aceites: any[]) => {
console.log('✅ Aceites recebidos:', aceites); // LOGA TODOS OS ACEITES ORIGINAIS
const data = aceites.map(a => {
const userRaw = a.user || '';
let idUsuario = '';
let email = '';
console.log('🔍 Usuário bruto:', userRaw); // LOGA STRING DO USUÁRIO
// Extrai ID e email do campo "Usuário"
const match = userRaw.match(/User\(id=(\d+),\s*email=([^)]+)\)/);
if (match) {
idUsuario = match[1];
email = match[2];
} else if (userRaw.match(/User\(id=(\d+)\)/)) {
idUsuario = userRaw.match(/User\(id=(\d+)\)/)[1];
}
// Categoria
let categoriaLabel = 'Não informado';
switch (+a.categoria) {
case 1:
categoriaLabel = 'Granel Sólido';
break;
case 2:
categoriaLabel = 'Granel Líquido';
break;
case 3:
categoriaLabel = 'Carga Geral';
break;
}
// Flag
let flagLabel = '';
if (a.flag && !isNaN(+a.flag)) {
const flagObj = this.countries.find(c => c.id === +a.flag);
flagLabel = flagObj ? flagObj.name : a.flag;
} else {
flagLabel = a.flag || 'Não informado';
}
const row = {
Nome: a.nome,
IMO: a.imo,
'ID Usuário': idUsuario,
Email: email,
Categoria: categoriaLabel,
Flag: flagLabel,
Observações: a.obs,
Pontal: a.pontal,
'Moldagem Quilha': a.mfold_quilha,
'Ponte Mfold': a.ponte_mfold,
'Calado Entrada': a.calado_entrada,
'Calado Saída': a.calado_saida,
'Data Aceite': a.dataAccept,
'Data Criação': a.data_create,
};
return row;
});
console.log('📋 Dados finais para CSV:', data); // LOGA O ARRAY COMPLETO FINAL
const csvContent = this._csvService.saveDataInCSV(data);
console.log('📝 Conteúdo CSV:', csvContent); // LOGA O TEXTO CSV GERADO
const hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
hiddenElement.target = '_blank';
hiddenElement.download = name + '.csv';
hiddenElement.click();
},
error: (err) => {
this._coreService.openSnackBar('Erro ao exportar CSV');
console.error('❌ Erro ao exportar CSV:', err);
}
});
}
}
......@@ -28,6 +28,7 @@
</p>
</div>
</mat-card-content>
</mat-card>
<ng-container *ngIf="data.path">
......@@ -73,11 +74,21 @@
{{ berco.nome }}
</div>
</div>
}
<p *ngIf="data.bercosSelecionados?.length > 0 " class="field full-width" appearance="outline">
<strong>Preferências de Berços do Usuário:</strong>
<span *ngIf="data.bercosSelecionados?.length > 0; else semPreferencias">
<span *ngFor="let berco of data.bercosSelecionados; let last = last">
{{ berco.nome || berco }}
<span *ngIf="!last">, </span>
</span>
</span>
<ng-template #semPreferencias>
Nenhuma preferência informada.
</ng-template>
</p>
</div>
<div *ngSwitchCase="'NE'">
<p class="field full-width" appearance="outline">
Status: <span [ngStyle]="{ color: 'red' }">Aceite Negado</span>
......
......@@ -8,7 +8,12 @@
[secondaryButtonAction]="openSearchBercoForm.bind(this)"
>
</app-add-search>
<div class="main-body">
<button mat-raised-button color="primary" style="background-color: #43a047; color: #fff; margin: 12px 0;" (click)="saveDataInCSV('aceites')">
<mat-icon>download</mat-icon>
Exportar Excel
</button>
<div class="table-container">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
......
......@@ -27,6 +27,7 @@ import { BercoSearchComponent } from '../berco-search/berco-search.component';
import { JwtDecoderService } from '../../../jwt-decoder.service';
import { AuthService } from '../../../auth.service';
import { jwtDecode } from 'jwt-decode';
import { CsvService } from '../../../csv.service';
interface BercoData {
id: number;
......@@ -95,10 +96,12 @@ export class BercosComponent implements OnInit {
private _coreService: CoreService,
private jwtDecoderService: JwtDecoderService,
private authService: AuthService,
private cdr: ChangeDetectorRef
) {}
private cdr: ChangeDetectorRef,
private _csvService: CsvService
) { }
ngOnInit(): void { this.validationToken();
ngOnInit(): void {
this.validationToken();
}
ngAfterViewInit(): void {
......@@ -209,12 +212,13 @@ export class BercosComponent implements OnInit {
}
openAddBercoForm() {
this._dialog.open(BercoAddComponent,{autoFocus: true, // Foca no primeiro campo interativo do formulário
this._dialog.open(BercoAddComponent, {
autoFocus: true, // Foca no primeiro campo interativo do formulário
disableClose: true, // Impede que o diálogo feche ao clicar fora
width: '500px', // Define a largura do diálogo});
});
this.cdr.detectChanges();
}
}
openSearchBercoForm() {
this._dialog.open(BercoSearchComponent);
......@@ -223,7 +227,7 @@ export class BercosComponent implements OnInit {
if (storedData) {
const dataSource = JSON.parse(storedData); // Converte o JSON em um objeto
console.log('Dados recuperados do sessionStorage:', dataSource);
this.dataSource= dataSource;
this.dataSource = dataSource;
this.cdr.detectChanges();
// Atualiza a tabela com os dados
} else {
......@@ -241,4 +245,75 @@ export class BercosComponent implements OnInit {
width: '800px', // Define a largura do diálogo
});
}
public saveDataInCSV(name: string): void {
this._bercoService.getAllAceitesSemPaginacao().subscribe({
next: (aceites: any[]) => {
console.log('✅ Aceites recebidos:', aceites); // LOGA TODOS OS ACEITES ORIGINAIS
const data = aceites.map(a => {
const userRaw = a.user || '';
let idUsuario = '';
let email = '';
console.log('🔍 Usuário bruto:', userRaw); // LOGA STRING DO USUÁRIO
// Extrai ID e email do campo "Usuário"
const match = userRaw.match(/User\(id=(\d+),\s*email=([^)]+)\)/);
if (match) {
idUsuario = match[1];
email = match[2];
} else if (userRaw.match(/User\(id=(\d+)\)/)) {
idUsuario = userRaw.match(/User\(id=(\d+)\)/)[1];
}
// Categoria
let categoriaLabel = 'Não informado';
switch (+a.categoria) {
case 1:
categoriaLabel = 'Granel Sólido';
break;
case 2:
categoriaLabel = 'Granel Líquido';
break;
case 3:
categoriaLabel = 'Carga Geral';
break;
}
const row = {
Nome: a.nome,
DWT: a.dwt || '',
'Boca Máx': a.boca_max || '',
'Calado Máx': a.calado_max || '',
'Categoria': categoriaLabel,
Profundidade: a.profundidade || '',
Largura: a.largura || '',
'LOA Máx': a.loa_max || '',
'Comprimento Estrutural': a.compri_estrutural || '',
'Comprimento Útil': a.compri_util || '',
};
return row;
});
console.log('📋 Dados finais para CSV:', data); // LOGA O ARRAY COMPLETO FINAL
const csvContent = this._csvService.saveDataInCSV(data);
console.log('📝 Conteúdo CSV:', csvContent); // LOGA O TEXTO CSV GERADO
const hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
hiddenElement.target = '_blank';
hiddenElement.download = name + '.csv';
hiddenElement.click();
},
error: (err) => {
this._coreService.openSnackBar('Erro ao exportar CSV');
console.error('❌ Erro ao exportar CSV:', err);
}
});
}
}
<app-add-search
[title]="'Black List'"
[primaryButtonText]="'Adicionar Navio'"
[primaryButtonColor]="'primary'"
[primaryButtonAction]="openAddEmpForm.bind(this)"
>
<app-add-search [title]="'Black List'" [primaryButtonText]="'Adicionar Navio'" [primaryButtonColor]="'primary'"
[primaryButtonAction]="openAddEmpForm.bind(this)">
</app-add-search>
<!-- Botão Exportar Excel Verde -->
<div class="main-body">
<button mat-raised-button color="primary" style="background-color: #43a047; color: #fff; margin: 12px 0;"
(click)="saveDataInCSV('aceites')">
<mat-icon>download</mat-icon>
Exportar Excel
</button>
<div class="table-container" style="overflow-x: auto">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
......@@ -42,26 +44,32 @@
<!-- Flag Column -->
<ng-container matColumnDef="flag">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Flag</th>
<td mat-cell *matCellDef="let row">{{ row.flag || "Null" }}</td>
<th mat-header-cell *matHeaderCellDef>Flag</th>
<td mat-cell *matCellDef="let row">
<ng-container *ngIf="countries[+row.flag]; else flagNotAvailable">
<img [src]="countries[+row.flag].flagUrl" width="20" height="15"
alt="{{ countries[+row.flag].name }} flag"
style="margin-right: 8px" />
<span>{{ countries[+row.flag]?.name }}</span>
</ng-container>
<ng-template #flagNotAvailable>Não informado</ng-template>
</td>
</ng-container>
<!-- Action Column -->
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef>Action</th>
<td mat-cell *matCellDef="let row" style="white-space: nowrap">
<button mat-icon-button (click)="openEditForm(row)" *ngIf="user.role === 'COMPANY'"
mat-icon-button
color="accent"
>
<button mat-icon-button (click)="openEditForm(row)" *ngIf="user.role === 'COMPANY'" mat-icon-button
color="accent">
<mat-icon style="color: coral">edit</mat-icon>
</button>
<button mat-icon-button color="primary" (click)="getAceiteById(row)">
<mat-icon>visibility</mat-icon>
</button>
<button mat-icon-button color="warn" (click)="deleteEmployee(row.id)" *ngIf="user.role === 'COMPANY'"
mat-icon-button
color="accent">
mat-icon-button color="accent">
<mat-icon>delete</mat-icon>
</button>
......@@ -73,29 +81,17 @@
</table>
</div>
<!-- Add paginator reference #paginator="matPaginator" -->
<mat-paginator
#paginator
[length]="totalItems"
[pageSize]="pageSize"
(page)="loadData($event)"
>
</mat-paginator>
<!-- Add paginator reference #paginator="matPaginator" -->
<mat-paginator #paginator [length]="totalItems" [pageSize]="pageSize" (page)="loadData($event)">
</mat-paginator>
<!-- Buttons for navigating to the first and last page -->
<button
mat-button
(click)="paginator.firstPage()"
[disabled]="paginator.pageIndex === 0"
>
Primeira Página
</button>
<!-- Buttons for navigating to the first and last page -->
<button mat-button (click)="paginator.firstPage()" [disabled]="paginator.pageIndex === 0">
Primeira Página
</button>
<button
mat-button
(click)="paginator.lastPage()"
[disabled]="paginator.pageIndex === paginator.getNumberOfPages() - 1"
>
Última Página
</button>
<button mat-button (click)="paginator.lastPage()"
[disabled]="paginator.pageIndex === paginator.getNumberOfPages() - 1">
Última Página
</button>
</div>
......@@ -28,6 +28,7 @@ import { BlackListAddComponent } from '../../crud-blackList/black-list-add/black
import { BlackListEdit } from '../black-list-edit/black-list-edit.component';
import { BlackListService } from '../../../services/Blacklists/black-list.service';
import { VisualizacaoBlackListComponent } from '../visualizacao-black-list/visualizacao-black-list.component';
import { CsvService } from '../../../csv.service';
interface NavioData {
id: number;
......@@ -98,8 +99,9 @@ export class BlackListComponent {
private authService: AuthService,
private _coreService: CoreService,
private cdr: ChangeDetectorRef,
private _csvService: CsvService // Injetando o serviço CSV'
) {}
) { }
ngOnInit(): void {
this.validationToken();
}
......@@ -182,7 +184,7 @@ export class BlackListComponent {
}
addBlackList(data:any){
addBlackList(data: any) {
this._dialog.open(BlackListAddComponent, {
data,
autoFocus: true, // Foca no primeiro campo interativo do formulário
......@@ -194,12 +196,13 @@ export class BlackListComponent {
}
openAddEmpForm() {
this._dialog.open(BlackListAddComponent,{autoFocus: true, // Foca no primeiro campo interativo do formulário
this._dialog.open(BlackListAddComponent, {
autoFocus: true, // Foca no primeiro campo interativo do formulário
disableClose: true, // Impede que o diálogo feche ao clicar fora
width: '600px', // Define a largura do diálogo}));
})
this.cdr.detectChanges();
}
}
getAceiteById(data: any) {
......@@ -211,4 +214,424 @@ export class BlackListComponent {
this.cdr.detectChanges();
}
public saveDataInCSV(name: string): void {
this._navioService.getAllBlackListSemPaginacao().subscribe({
next: (aceites: any[]) => {
console.log('✅ Aceites recebidos:', aceites); // LOGA TODOS OS ACEITES ORIGINAIS
const data = aceites.map(a => {
const userRaw = a.user || '';
let idUsuario = '';
let email = '';
console.log('🔍 Usuário bruto:', userRaw); // LOGA STRING DO USUÁRIO
// Extrai ID e email do campo "Usuário"
const match = userRaw.match(/User\(id=(\d+),\s*email=([^)]+)\)/);
if (match) {
idUsuario = match[1];
email = match[2];
} else if (userRaw.match(/User\(id=(\d+)\)/)) {
idUsuario = userRaw.match(/User\(id=(\d+)\)/)[1];
}
// Categoria
let categoriaLabel = 'Não informado';
switch (+a.categoria) {
case 1:
categoriaLabel = 'Granel Sólido';
break;
case 2:
categoriaLabel = 'Granel Líquido';
break;
case 3:
categoriaLabel = 'Carga Geral';
break;
}
const row = {
IMO: a.imo,
Nome: a.nome,
Motivo: a.reason,
LOA: a.loa,
Boca: a.boca,
DWT: a.dwt,
Pontal: a.pontal,
Categoria: (() => {
switch (a.categoria) {
case "1":
return "Granel Sólido";
case "2":
return "Granel Líquido";
case "3":
return "Carga Geral";
default:
return "Não informado";
}
})()
};
return row;
});
console.log('📋 Dados finais para CSV:', data); // LOGA O ARRAY COMPLETO FINAL
const csvContent = this._csvService.saveDataInCSV(data);
console.log('📝 Conteúdo CSV:', csvContent); // LOGA O TEXTO CSV GERADO
const hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
hiddenElement.target = '_blank';
hiddenElement.download = name + '.csv';
hiddenElement.click();
},
error: (err) => {
this._coreService.openSnackBar('Erro ao exportar CSV');
console.error('❌ Erro ao exportar CSV:', err);
}
});
}
countries = [
{ id: 1, name: 'Afeganistão', flagUrl: 'https://flagcdn.com/w20/af.png' },
{ id: 2, name: 'África do Sul', flagUrl: 'https://flagcdn.com/w20/za.png' },
{ id: 3, name: 'Albânia', flagUrl: 'https://flagcdn.com/w20/al.png' },
{ id: 4, name: 'Alemanha', flagUrl: 'https://flagcdn.com/w20/de.png' },
{ id: 5, name: 'Andorra', flagUrl: 'https://flagcdn.com/w20/ad.png' },
{ id: 6, name: 'Angola', flagUrl: 'https://flagcdn.com/w20/ao.png' },
{
id: 7,
name: 'Antígua e Barbuda',
flagUrl: 'https://flagcdn.com/w20/ag.png',
},
{
id: 8,
name: 'Arábia Saudita',
flagUrl: 'https://flagcdn.com/w20/sa.png',
},
{ id: 9, name: 'Argélia', flagUrl: 'https://flagcdn.com/w20/dz.png' },
{ id: 10, name: 'Argentina', flagUrl: 'https://flagcdn.com/w20/ar.png' },
{ id: 11, name: 'Armênia', flagUrl: 'https://flagcdn.com/w20/am.png' },
{ id: 12, name: 'Austrália', flagUrl: 'https://flagcdn.com/w20/au.png' },
{ id: 13, name: 'Áustria', flagUrl: 'https://flagcdn.com/w20/at.png' },
{ id: 14, name: 'Azerbaijão', flagUrl: 'https://flagcdn.com/w20/az.png' },
{ id: 15, name: 'Bahamas', flagUrl: 'https://flagcdn.com/w20/bs.png' },
{ id: 16, name: 'Bahrein', flagUrl: 'https://flagcdn.com/w20/bh.png' },
{ id: 17, name: 'Bangladesh', flagUrl: 'https://flagcdn.com/w20/bd.png' },
{ id: 18, name: 'Barbados', flagUrl: 'https://flagcdn.com/w20/bb.png' },
{ id: 19, name: 'Bélgica', flagUrl: 'https://flagcdn.com/w20/be.png' },
{ id: 20, name: 'Belize', flagUrl: 'https://flagcdn.com/w20/bz.png' },
{ id: 21, name: 'Benin', flagUrl: 'https://flagcdn.com/w20/bj.png' },
{ id: 22, name: 'Bielorrússia', flagUrl: 'https://flagcdn.com/w20/by.png' },
{ id: 23, name: 'Bolívia', flagUrl: 'https://flagcdn.com/w20/bo.png' },
{
id: 24,
name: 'Bósnia e Herzegovina',
flagUrl: 'https://flagcdn.com/w20/ba.png',
},
{ id: 25, name: 'Botswana', flagUrl: 'https://flagcdn.com/w20/bw.png' },
{ id: 26, name: 'Brasil', flagUrl: 'https://flagcdn.com/w20/br.png' },
{ id: 27, name: 'Brunei', flagUrl: 'https://flagcdn.com/w20/bn.png' },
{ id: 28, name: 'Bulgária', flagUrl: 'https://flagcdn.com/w20/bg.png' },
{ id: 29, name: 'Burkina Faso', flagUrl: 'https://flagcdn.com/w20/bf.png' },
{ id: 30, name: 'Burundi', flagUrl: 'https://flagcdn.com/w20/bi.png' },
{ id: 31, name: 'Butão', flagUrl: 'https://flagcdn.com/w20/bt.png' },
{ id: 32, name: 'Cabo Verde', flagUrl: 'https://flagcdn.com/w20/cv.png' },
{ id: 33, name: 'Camboja', flagUrl: 'https://flagcdn.com/w20/kh.png' },
{ id: 34, name: 'Camarões', flagUrl: 'https://flagcdn.com/w20/cm.png' },
{ id: 35, name: 'Canadá', flagUrl: 'https://flagcdn.com/w20/ca.png' },
{ id: 36, name: 'Catar', flagUrl: 'https://flagcdn.com/w20/qa.png' },
{ id: 37, name: 'Cazaquistão', flagUrl: 'https://flagcdn.com/w20/kz.png' },
{ id: 38, name: 'Chade', flagUrl: 'https://flagcdn.com/w20/td.png' },
{ id: 39, name: 'Chile', flagUrl: 'https://flagcdn.com/w20/cl.png' },
{ id: 40, name: 'China', flagUrl: 'https://flagcdn.com/w20/cn.png' },
{ id: 41, name: 'Chipre', flagUrl: 'https://flagcdn.com/w20/cy.png' },
{ id: 42, name: 'Colômbia', flagUrl: 'https://flagcdn.com/w20/co.png' },
{ id: 43, name: 'Comores', flagUrl: 'https://flagcdn.com/w20/km.png' },
{ id: 44, name: 'Congo', flagUrl: 'https://flagcdn.com/w20/cg.png' },
{
id: 45,
name: 'Costa do Marfim',
flagUrl: 'https://flagcdn.com/w20/ci.png',
},
{ id: 46, name: 'Costa Rica', flagUrl: 'https://flagcdn.com/w20/cr.png' },
{ id: 47, name: 'Croácia', flagUrl: 'https://flagcdn.com/w20/hr.png' },
{ id: 48, name: 'Cuba', flagUrl: 'https://flagcdn.com/w20/cu.png' },
{ id: 49, name: 'Dinamarca', flagUrl: 'https://flagcdn.com/w20/dk.png' },
{ id: 50, name: 'Dominica', flagUrl: 'https://flagcdn.com/w20/dm.png' },
{ id: 51, name: 'Egito', flagUrl: 'https://flagcdn.com/w20/eg.png' },
{ id: 52, name: 'El Salvador', flagUrl: 'https://flagcdn.com/w20/sv.png' },
{
id: 53,
name: 'Emirados Árabes Unidos',
flagUrl: 'https://flagcdn.com/w20/ae.png',
},
{ id: 54, name: 'Equador', flagUrl: 'https://flagcdn.com/w20/ec.png' },
{ id: 55, name: 'Eritreia', flagUrl: 'https://flagcdn.com/w20/er.png' },
{ id: 56, name: 'Eslováquia', flagUrl: 'https://flagcdn.com/w20/sk.png' },
{ id: 57, name: 'Eslovênia', flagUrl: 'https://flagcdn.com/w20/si.png' },
{ id: 58, name: 'Espanha', flagUrl: 'https://flagcdn.com/w20/es.png' },
{
id: 59,
name: 'Estados Unidos',
flagUrl: 'https://flagcdn.com/w20/us.png',
},
{ id: 60, name: 'Estônia', flagUrl: 'https://flagcdn.com/w20/ee.png' },
{ id: 61, name: 'Eswatini', flagUrl: 'https://flagcdn.com/w20/sz.png' },
{ id: 62, name: 'Etiópia', flagUrl: 'https://flagcdn.com/w20/et.png' },
{ id: 63, name: 'Fiji', flagUrl: 'https://flagcdn.com/w20/fj.png' },
{ id: 64, name: 'Filipinas', flagUrl: 'https://flagcdn.com/w20/ph.png' },
{ id: 65, name: 'Finlândia', flagUrl: 'https://flagcdn.com/w20/fi.png' },
{ id: 66, name: 'França', flagUrl: 'https://flagcdn.com/w20/fr.png' },
{ id: 67, name: 'Guatemala', flagUrl: 'https://flagcdn.com/w20/gt.png' },
{ id: 68, name: 'Guiana', flagUrl: 'https://flagcdn.com/w20/gf.png' },
{ id: 69, name: 'Guiné', flagUrl: 'https://flagcdn.com/w20/gn.png' },
{ id: 70, name: 'Guiné-Bissau', flagUrl: 'https://flagcdn.com/w20/gw.png' },
{ id: 71, name: 'Haiti', flagUrl: 'https://flagcdn.com/w20/ht.png' },
{ id: 72, name: 'Honduras', flagUrl: 'https://flagcdn.com/w20/hn.png' },
{ id: 73, name: 'Hungria', flagUrl: 'https://flagcdn.com/w20/hu.png' },
{ id: 74, name: 'Iêmen', flagUrl: 'https://flagcdn.com/w20/ye.png' },
{
id: 75,
name: 'Ilhas Marshall',
flagUrl: 'https://flagcdn.com/w20/mh.png',
},
{
id: 76,
name: 'Ilhas Salomão',
flagUrl: 'https://flagcdn.com/w20/sb.png',
},
{ id: 77, name: 'Índia', flagUrl: 'https://flagcdn.com/w20/in.png' },
{ id: 78, name: 'Indonésia', flagUrl: 'https://flagcdn.com/w20/id.png' },
{ id: 79, name: 'Irã', flagUrl: 'https://flagcdn.com/w20/ir.png' },
{ id: 80, name: 'Iraque', flagUrl: 'https://flagcdn.com/w20/iq.png' },
{ id: 81, name: 'Irlanda', flagUrl: 'https://flagcdn.com/w20/ie.png' },
{ id: 82, name: 'Islândia', flagUrl: 'https://flagcdn.com/w20/is.png' },
{ id: 83, name: 'Israel', flagUrl: 'https://flagcdn.com/w20/il.png' },
{ id: 84, name: 'Itália', flagUrl: 'https://flagcdn.com/w20/it.png' },
{ id: 85, name: 'Jamaica', flagUrl: 'https://flagcdn.com/w20/jm.png' },
{ id: 86, name: 'Japão', flagUrl: 'https://flagcdn.com/w20/jp.png' },
{ id: 87, name: 'Jordânia', flagUrl: 'https://flagcdn.com/w20/jo.png' },
{ id: 88, name: 'Kosovo', flagUrl: 'https://flagcdn.com/w20/xk.png' },
{ id: 89, name: 'Kuwait', flagUrl: 'https://flagcdn.com/w20/kw.png' },
{ id: 90, name: 'Quirguistão', flagUrl: 'https://flagcdn.com/w20/kg.png' },
{ id: 91, name: 'Laos', flagUrl: 'https://flagcdn.com/w20/la.png' },
{ id: 92, name: 'Letônia', flagUrl: 'https://flagcdn.com/w20/lv.png' },
{ id: 93, name: 'Líbano', flagUrl: 'https://flagcdn.com/w20/lb.png' },
{ id: 94, name: 'Lesoto', flagUrl: 'https://flagcdn.com/w20/ls.png' },
{ id: 95, name: 'Libéria', flagUrl: 'https://flagcdn.com/w20/lr.png' },
{ id: 96, name: 'Líbia', flagUrl: 'https://flagcdn.com/w20/ly.png' },
{
id: 97,
name: 'Liechtenstein',
flagUrl: 'https://flagcdn.com/w20/li.png',
},
{ id: 98, name: 'Lituânia', flagUrl: 'https://flagcdn.com/w20/lt.png' },
{ id: 99, name: 'Luxemburgo', flagUrl: 'https://flagcdn.com/w20/lu.png' },
{
id: 100,
name: 'Macedônia do Norte',
flagUrl: 'https://flagcdn.com/w20/mk.png',
},
{ id: 101, name: 'Madagascar', flagUrl: 'https://flagcdn.com/w20/mg.png' },
{ id: 102, name: 'Malawi', flagUrl: 'https://flagcdn.com/w20/mw.png' },
{ id: 103, name: 'Malásia', flagUrl: 'https://flagcdn.com/w20/my.png' },
{ id: 104, name: 'Maldivas', flagUrl: 'https://flagcdn.com/w20/mv.png' },
{ id: 105, name: 'Mali', flagUrl: 'https://flagcdn.com/w20/ml.png' },
{ id: 106, name: 'Malta', flagUrl: 'https://flagcdn.com/w20/mt.png' },
{ id: 107, name: 'Mauritânia', flagUrl: 'https://flagcdn.com/w20/mr.png' },
{ id: 108, name: 'Maurício', flagUrl: 'https://flagcdn.com/w20/mu.png' },
{ id: 109, name: 'México', flagUrl: 'https://flagcdn.com/w20/mx.png' },
{ id: 110, name: 'Micronésia', flagUrl: 'https://flagcdn.com/w20/fm.png' },
{ id: 111, name: 'Moldávia', flagUrl: 'https://flagcdn.com/w20/md.png' },
{ id: 112, name: 'Mônaco', flagUrl: 'https://flagcdn.com/w20/mc.png' },
{ id: 113, name: 'Mongólia', flagUrl: 'https://flagcdn.com/w20/mn.png' },
{ id: 114, name: 'Montenegro', flagUrl: 'https://flagcdn.com/w20/me.png' },
{ id: 115, name: 'Marrocos', flagUrl: 'https://flagcdn.com/w20/ma.png' },
{ id: 116, name: 'Moçambique', flagUrl: 'https://flagcdn.com/w20/mz.png' },
{ id: 117, name: 'Myanmar', flagUrl: 'https://flagcdn.com/w20/mm.png' },
{ id: 118, name: 'Namíbia', flagUrl: 'https://flagcdn.com/w20/na.png' },
{ id: 119, name: 'Nauru', flagUrl: 'https://flagcdn.com/w20/nr.png' },
{ id: 120, name: 'Nepal', flagUrl: 'https://flagcdn.com/w20/np.png' },
{
id: 121,
name: 'Países Baixos',
flagUrl: 'https://flagcdn.com/w20/nl.png',
},
{
id: 122,
name: 'Nova Zelândia',
flagUrl: 'https://flagcdn.com/w20/nz.png',
},
{ id: 123, name: 'Nicarágua', flagUrl: 'https://flagcdn.com/w20/ni.png' },
{ id: 124, name: 'Níger', flagUrl: 'https://flagcdn.com/w20/ne.png' },
{ id: 125, name: 'Nigéria', flagUrl: 'https://flagcdn.com/w20/ng.png' },
{ id: 126, name: 'Noruega', flagUrl: 'https://flagcdn.com/w20/no.png' },
{ id: 127, name: 'Omã', flagUrl: 'https://flagcdn.com/w20/om.png' },
{ id: 128, name: 'Paquistão', flagUrl: 'https://flagcdn.com/w20/pk.png' },
{ id: 129, name: 'Palau', flagUrl: 'https://flagcdn.com/w20/pw.png' },
{ id: 130, name: 'Palestina', flagUrl: 'https://flagcdn.com/w20/ps.png' },
{ id: 131, name: 'Panamá', flagUrl: 'https://flagcdn.com/w20/pa.png' },
{
id: 132,
name: 'Papua Nova Guiné',
flagUrl: 'https://flagcdn.com/w20/pg.png',
},
{ id: 133, name: 'Paraguai', flagUrl: 'https://flagcdn.com/w20/py.png' },
{ id: 134, name: 'Peru', flagUrl: 'https://flagcdn.com/w20/pe.png' },
{ id: 135, name: 'Polônia', flagUrl: 'https://flagcdn.com/w20/pl.png' },
{ id: 136, name: 'Portugal', flagUrl: 'https://flagcdn.com/w20/pt.png' },
{ id: 137, name: 'Reino Unido', flagUrl: 'https://flagcdn.com/w20/gb.png' },
{
id: 138,
name: 'República Centro-Africana',
flagUrl: 'https://flagcdn.com/w20/cf.png',
},
{
id: 139,
name: 'República Dominicana',
flagUrl: 'https://flagcdn.com/w20/do.png',
},
{ id: 140, name: 'Romênia', flagUrl: 'https://flagcdn.com/w20/ro.png' },
{ id: 141, name: 'Ruanda', flagUrl: 'https://flagcdn.com/w20/rw.png' },
{ id: 142, name: 'Rússia', flagUrl: 'https://flagcdn.com/w20/ru.png' },
{
id: 143,
name: 'São Cristóvão e Nevis',
flagUrl: 'https://flagcdn.com/w20/kn.png',
},
{ id: 144, name: 'São Marino', flagUrl: 'https://flagcdn.com/w20/sm.png' },
{
id: 145,
name: 'São Tomé e Príncipe',
flagUrl: 'https://flagcdn.com/w20/st.png',
},
{
id: 146,
name: 'São Vicente e Granadinas',
flagUrl: 'https://flagcdn.com/w20/vc.png',
},
{ id: 147, name: 'Santa Lúcia', flagUrl: 'https://flagcdn.com/w20/lc.png' },
{ id: 148, name: 'Senegal', flagUrl: 'https://flagcdn.com/w20/sn.png' },
{ id: 149, name: 'Sérvia', flagUrl: 'https://flagcdn.com/w20/rs.png' },
{ id: 150, name: 'Seychelles', flagUrl: 'https://flagcdn.com/w20/sc.png' },
{ id: 151, name: 'Singapura', flagUrl: 'https://flagcdn.com/w20/sg.png' },
{ id: 152, name: 'Síria', flagUrl: 'https://flagcdn.com/w20/sy.png' },
{ id: 153, name: 'Somália', flagUrl: 'https://flagcdn.com/w20/so.png' },
{ id: 154, name: 'Sri Lanka', flagUrl: 'https://flagcdn.com/w20/lk.png' },
{ id: 155, name: 'Sudão', flagUrl: 'https://flagcdn.com/w20/sd.png' },
{
id: 156,
name: 'Sudão do Sul',
flagUrl: 'https://flagcdn.com/w20/ss.png',
},
{ id: 157, name: 'Suriname', flagUrl: 'https://flagcdn.com/w20/sr.png' },
{ id: 158, name: 'Suécia', flagUrl: 'https://flagcdn.com/w20/se.png' },
{ id: 159, name: 'Suíça', flagUrl: 'https://flagcdn.com/w20/ch.png' },
{ id: 160, name: 'Tajiquistão', flagUrl: 'https://flagcdn.com/w20/tj.png' },
{ id: 161, name: 'Tailândia', flagUrl: 'https://flagcdn.com/w20/th.png' },
{ id: 162, name: 'Timor-Leste', flagUrl: 'https://flagcdn.com/w20/tl.png' },
{ id: 163, name: 'Togo', flagUrl: 'https://flagcdn.com/w20/tg.png' },
{ id: 164, name: 'Tonga', flagUrl: 'https://flagcdn.com/w20/to.png' },
{
id: 165,
name: 'Trinidad e Tobago',
flagUrl: 'https://flagcdn.com/w20/tt.png',
},
{ id: 166, name: 'Tunísia', flagUrl: 'https://flagcdn.com/w20/tn.png' },
{ id: 167, name: 'Turquia', flagUrl: 'https://flagcdn.com/w20/tr.png' },
{
id: 168,
name: 'Turcomenistão',
flagUrl: 'https://flagcdn.com/w20/tm.png',
},
{ id: 169, name: 'Tuvalu', flagUrl: 'https://flagcdn.com/w20/tv.png' },
{ id: 170, name: 'Ucrânia', flagUrl: 'https://flagcdn.com/w20/ua.png' },
{ id: 171, name: 'Uganda', flagUrl: 'https://flagcdn.com/w20/ug.png' },
{ id: 172, name: 'Uruguai', flagUrl: 'https://flagcdn.com/w20/uy.png' },
{ id: 173, name: 'Uzbequistão', flagUrl: 'https://flagcdn.com/w20/uz.png' },
{ id: 174, name: 'Vanuatu', flagUrl: 'https://flagcdn.com/w20/vu.png' },
{ id: 175, name: 'Vaticano', flagUrl: 'https://flagcdn.com/w20/va.png' },
{ id: 176, name: 'Venezuela', flagUrl: 'https://flagcdn.com/w20/ve.png' },
{ id: 177, name: 'Vietnã', flagUrl: 'https://flagcdn.com/w20/vn.png' },
{ id: 178, name: 'Zâmbia', flagUrl: 'https://flagcdn.com/w20/zm.png' },
{ id: 179, name: 'Zimbábue', flagUrl: 'https://flagcdn.com/w20/zw.png' },
{
id: 180,
name: 'São Bartolomeu',
flagUrl: 'https://flagcdn.com/w20/bl.png',
},
{
id: 181,
name: 'Santa Helena, Ascensão e Tristão da Cunha',
flagUrl: 'https://flagcdn.com/w20/sh.png',
},
{
id: 182,
name: 'Território Britânico do Oceano Índico',
flagUrl: 'https://flagcdn.com/w20/io.png',
},
{
id: 183,
name: 'Ilhas Cayman',
flagUrl: 'https://flagcdn.com/w20/ky.png',
},
{
id: 184,
name: 'Ilhas Cocos (Keeling)',
flagUrl: 'https://flagcdn.com/w20/cc.png',
},
{ id: 185, name: 'Ilhas Cook', flagUrl: 'https://flagcdn.com/w20/ck.png' },
{ id: 186, name: 'Ilhas Feroé', flagUrl: 'https://flagcdn.com/w20/fo.png' },
{
id: 187,
name: 'Ilhas Georgianas do Sul e Sandwich do Sul',
flagUrl: 'https://flagcdn.com/w20/gs.png',
},
{
id: 188,
name: 'Ilhas Heard e Ilhas McDonald',
flagUrl: 'https://flagcdn.com/w20/hm.png',
},
{
id: 189,
name: 'Ilhas Malvinas',
flagUrl: 'https://flagcdn.com/w20/fk.png',
},
{
id: 190,
name: 'Ilhas Marianas do Norte',
flagUrl: 'https://flagcdn.com/w20/mp.png',
},
{
id: 191,
name: 'Ilhas Menores dos Estados Unidos',
flagUrl: 'https://flagcdn.com/w20/us.png',
},
{
id: 192,
name: 'Ilhas Pitcairn',
flagUrl: 'https://flagcdn.com/w20/pn.png',
},
{
id: 193,
name: 'Ilhas Virgens Americanas',
flagUrl: 'https://flagcdn.com/w20/vi.png',
},
{
id: 194,
name: 'Ilhas Virgens Britânicas',
flagUrl: 'https://flagcdn.com/w20/vg.png',
},
{
id: 195,
name: 'Samoa Americana',
flagUrl: 'https://flagcdn.com/w20/as.png',
},
];
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SearchBlackComponent } from './search-black.component';
describe('SearchBlackComponent', () => {
let component: SearchBlackComponent;
let fixture: ComponentFixture<SearchBlackComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SearchBlackComponent]
})
.compileComponents();
fixture = TestBed.createComponent(SearchBlackComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component } from '@angular/core';
@Component({
selector: 'app-search-black',
standalone: true,
imports: [],
templateUrl: './search-black.component.html',
styleUrl: './search-black.component.scss'
})
export class SearchBlackComponent {
}
......@@ -35,18 +35,24 @@
</div>
-->
<div class="column" style="flex: 1 1 30%; margin-bottom: 10px;">
<p><strong>Mfold Quilha:</strong> {{ navioInfo.mfold_quilha || 'Não informado' }}</p>
<p><strong>Mfold Quilha:</strong>
{{ navioInfo.mfold_quilha !== null && navioInfo.mfold_quilha !== undefined ? navioInfo.mfold_quilha : 'Não informado' }}
</p>
</div>
<div class="column" style="flex: 1 1 30%; margin-bottom: 10px;">
<p><strong>Categoria:</strong>
{{ navioInfo.categoria === 1 ? 'Granel Sólido' : (navioInfo.categoria === 2 ? 'Granel Líquido' : (navioInfo.categoria === 3 ? 'Carga Geral' : 'Não informado')) }}
{{
+navioInfo.categoria === 1 ? 'Granel Sólido' :
(+navioInfo.categoria === 2 ? 'Granel Líquido' :
(+navioInfo.categoria === 3 ? 'Carga Geral' : 'Não informado'))
}}
</p>
</div>
<div class="column" style="flex: 1 1 30%; margin-bottom: 10px;">
<p><strong>Flag:</strong>
<ng-container *ngIf="navioInfo.flag; else flagNotAvailable">
<img [src]="countries[navioInfo.flag].flagUrl" width="20" height="15" alt="{{ countries[navioInfo.flag].name }} flag" style="margin-right: 8px" />
<p>{{ countries[navioInfo.flag]?.name }}</p>
<ng-container *ngIf="countries[+navioInfo.flag]; else flagNotAvailable">
<img [src]="countries[+navioInfo.flag].flagUrl" width="20" height="15" alt="{{ countries[+navioInfo.flag].name }} flag" style="margin-right: 8px" />
<span>{{ countries[+navioInfo.flag]?.name }}</span>
</ng-container>
<ng-template #flagNotAvailable>Não informado</ng-template>
</p>
......
......@@ -46,7 +46,10 @@ export class VisualizacaoBlackListComponent implements OnInit {
// Adicione a lógica para salvar as informações de entrada
}
getFlagUrl(flagId: number): string | null {
const country = this.countries.find(c => c.id === flagId);
return country ? country.flagUrl : null;
}
countries = [
{ id: 1, name: 'Afeganistão', flagUrl: 'https://flagcdn.com/w20/af.png' },
{ id: 2, name: 'África do Sul', flagUrl: 'https://flagcdn.com/w20/za.png' },
......
......@@ -7,25 +7,14 @@
<div class="row">
<mat-form-field class="field full-width" appearance="outline">
<mat-label>IMO</mat-label>
<input
matInput
type="number"
(keydown)="preventNegative($event)"
min="0"
formControlName="imo"
/>
<input matInput type="number" (keydown)="preventNegative($event)" min="0" formControlName="imo" />
<mat-error *ngIf="empForm.get('imo')?.invalid">{{
getErrorMessage("imo")
}}</mat-error>
</mat-form-field>
<mat-form-field class="field full-width" appearance="outline">
<mat-label>MMSI</mat-label>
<input
matInput
type="number"
formControlName="mmsi"
(keydown)="preventNegative($event)"
/>
<input matInput type="number" formControlName="mmsi" (keydown)="preventNegative($event)" />
<mat-error *ngIf="empForm.get('mmsi')?.invalid">{{
getErrorMessage("mmsi")
}}</mat-error>
......@@ -41,28 +30,16 @@
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>LOA</mat-label>
<input
matInput
type="text"
(keydown)="preventNegative($event)"
min="0"
formControlName="loa"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }"
/>
<input matInput type="text" (keydown)="preventNegative($event)" min="0" formControlName="loa"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }" />
<mat-error *ngIf="empForm.get('loa')?.invalid">{{
getErrorMessage("loa")
}}</mat-error>
</mat-form-field>
<mat-form-field class="field small" appearance="outline">
<mat-label>Boca</mat-label>
<input
matInput
type="text"
(keydown)="preventNegative($event)"
min="0"
formControlName="boca"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }"
/>
<input matInput type="text" (keydown)="preventNegative($event)" min="0" formControlName="boca"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }" />
<mat-error *ngIf="empForm.get('boca')?.invalid">{{
getErrorMessage("boca")
}}</mat-error>
......@@ -71,66 +48,49 @@
<div class="row">
<mat-form-field class="field large" appearance="outline">
<mat-label>DWT</mat-label>
<input
matInput
type="text"
(keydown)="preventNegative($event)"
min="0"
formControlName="dwt"
[currencyMask]="{ prefix: 'Tons ', thousands: '.', decimal: ',' }"
/>
<input matInput type="text" (keydown)="preventNegative($event)" min="0" formControlName="dwt"
[currencyMask]="{ prefix: 'Tons ', thousands: '.', decimal: ',' }" />
<mat-error *ngIf="empForm.get('dwt')?.invalid">{{
getErrorMessage("dwt")
}}</mat-error>
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Pontal</mat-label>
<input
matInput
type="text"
(keydown)="preventNegative($event)"
min="0"
formControlName="pontal"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }"
/>
<input matInput type="text" (keydown)="preventNegative($event)" min="0" formControlName="pontal"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }" />
<mat-error *ngIf="empForm.get('pontal')?.invalid">{{
getErrorMessage("pontal")
}}</mat-error>
</mat-form-field>
<mat-form-field class="field small" appearance="outline">
<mat-form-field class="field small" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Ponte Mfold</mat-label>
<input
matInput
type="text"
(keydown)="preventNegative($event)"
min="0"
formControlName="ponte_mfold"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }"
/>
<input matInput type="text" (keydown)="preventNegative($event)" min="0" formControlName="ponte_mfold"
[currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }" />
<mat-error *ngIf="empForm.get('ponte_mfold')?.invalid">{{
getErrorMessage("ponte_mfold")
}}</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field large" appearance="outline">
<mat-form-field class="field small" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Ponte Mfold (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: '',thousands: '.', decimal: ',' }"
formControlName="ponte_mfold">
<mat-error *ngIf="empForm.get('ponte_mfold')?.invalid">{{ getErrorMessage('ponte_mfold') }}</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field large" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Mfold Quilha</mat-label>
<input
matInput
type="text"
(keydown)="preventNegative($event)"
min="0"
formControlName="mfold_quilha"
[currencyMask]="{ prefix: '', thousands: '.', decimal: ',' }"
/>
<input matInput type="text" (keydown)="preventNegative($event)" min="0" formControlName="mfold_quilha"
[currencyMask]="{ prefix: '', thousands: '.', decimal: ',' }" />
<mat-error *ngIf="empForm.get('mfold_quilha')?.invalid">{{
getErrorMessage("mfold_quilha")
}}</mat-error>
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Categoria</mat-label>
<mat-select formControlName="categoria">
<mat-select formControlName="categoria" (selectionChange)="onCategoriaChange($event.value)">
<mat-option *ngFor="let cat of categoria" [value]="cat.id">
{{ cat.nome }}
</mat-option>
......@@ -141,28 +101,14 @@
<mat-label>Flag</mat-label>
<mat-select formControlName="flag">
<mat-select-trigger>
<img
*ngIf="selectedCountry"
[src]="selectedCountry.flagUrl"
width="20"
height="15"
alt="{{ selectedCountry.name }} flag"
style="margin-right: 8px"
/>
<img *ngIf="selectedCountry" [src]="selectedCountry.flagUrl" width="20" height="15"
alt="{{ selectedCountry.name }} flag" style="margin-right: 8px" />
{{ selectedCountry?.name }}
</mat-select-trigger>
<mat-option
*ngFor="let country of countries"
[value]="country.id"
(onSelectionChange)="onCountrySelected(country)"
>
<img
[src]="country.flagUrl"
width="20"
height="15"
alt="{{ country.name }} flag"
style="margin-right: 8px"
/>
<mat-option *ngFor="let country of countries" [value]="country.id"
(onSelectionChange)="onCountrySelected(country)">
<img [src]="country.flagUrl" width="20" height="15" alt="{{ country.name }} flag"
style="margin-right: 8px" />
{{ country.name }}
</mat-option>
</mat-select>
......@@ -182,13 +128,7 @@
</div>
<div class="row file-upload-container">
<mat-label style="color:cadetblue">Adicione o documente Q88 da embarcação</mat-label>
<input
type="file"
class="file-input"
(change)="onFileSelected($event)"
#fileUpload
style="display: none"
/>
<input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload style="display: none" />
<div class="file-upload-content">
<div class="file-info">
......@@ -196,12 +136,7 @@
</div>
<div class="upload-button-wrapper">
<button
mat-mini-fab
color="primary"
class="upload-btn"
(click)="fileUpload.click()"
>
<button mat-mini-fab color="primary" class="upload-btn" (click)="fileUpload.click()">
<mat-icon>attach_file</mat-icon>
</button>
</div>
......@@ -209,24 +144,14 @@
<div class="uploaded-image-container" *ngIf="imageUrl">
<img [src]="imageUrl" alt="Uploaded Image" class="uploaded-image" />
<button
mat-mini-fab
color="warn"
class="remove-image-btn"
(click)="removeImage()"
>
<button mat-mini-fab color="warn" class="remove-image-btn" (click)="removeImage()">
<mat-icon>close</mat-icon>
</button>
</div>
</div>
</div>
<div mat-dialog-actions class="action">
<button
mat-raised-button
type="button"
color="warn"
[mat-dialog-close]="false"
>
<button mat-raised-button type="button" color="warn" [mat-dialog-close]="false">
Cancelar
</button>
<button mat-raised-button color="primary" type="submit">Salvar</button>
......
......@@ -16,6 +16,7 @@ import { MatDialogModule } from '@angular/material/dialog';
import { NaviosComponent } from '../navios/navios.component';
import { ToastrService } from 'ngx-toastr';
import { NgxCurrencyDirective } from 'ngx-currency';
import { BercosService } from '../../../services/bercos/bercos.service';
@Component({
selector: 'app-navio-add',
......@@ -55,7 +56,8 @@ export class NavioAddComponent implements OnInit {
private _empService: NavioService,
private _dialogRef: MatDialogRef<NavioAddComponent>,
@Inject(MAT_DIALOG_DATA) public data: any,
private toastService: ToastrService
private toastService: ToastrService,
private _bercoService: BercosService, // Injetando o serviço de berços
) {
this.empForm = this._fb.group({
imo: ['', Validators.required],
......@@ -71,6 +73,24 @@ export class NavioAddComponent implements OnInit {
flag: ['', Validators.required],
obs: [''],
});
this.empForm.get('categoria')?.valueChanges.subscribe(catId => {
const cat = this.categoria.find((c: any) => c.id === catId);
if (cat && cat.nome === 'Granel Líquido') {
this.empForm.get('mfold_quilha')?.setValidators([Validators.required]);
this.empForm.get('ponte_mfold')?.setValidators([Validators.required]);
} else {
this.empForm.get('mfold_quilha')?.clearValidators();
this.empForm.get('ponte_mfold')?.clearValidators();
}
this.empForm.get('mfold_quilha')?.updateValueAndValidity();
this.empForm.get('ponte_mfold')?.updateValueAndValidity();
});
}
selectedCategoriaNome: string = '';
onCategoriaChange(catId: any) {
const cat = this.categoria.find((c: any) => c.id === catId);
this.selectedCategoriaNome = cat ? cat.nome : '';
}
countries = [
......@@ -422,8 +442,17 @@ export class NavioAddComponent implements OnInit {
event.preventDefault();
}
}
bercosDisponiveis: any[] = [];
ngOnInit(): void {
this._bercoService.getBercosListSemPaginacao().subscribe({
next: (res) => {
this.bercosDisponiveis = Array.isArray(res) ? res : [];
},
error: () => {
this.bercosDisponiveis = [];
}
});
if (this.data) {
this.empForm.patchValue(this.data.empForm);
}
......
......@@ -64,7 +64,7 @@
getErrorMessage("pontal")
}}</mat-error>
</mat-form-field>
<mat-form-field class="field small" appearance="outline">
<mat-form-field class="field small" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Ponte Mfold (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }"
formControlName="ponte_mfold" />
......@@ -75,7 +75,7 @@
</div>
<div class="row">
<mat-form-field class="field large" appearance="outline">
<mat-form-field class="field large" appearance="outline" *ngIf="selectedCategoriaNome === 'Granel Líquido'">
<mat-label>Mfold Quilha (m)</mat-label>
<input matInput type="text" [currencyMask]="{ prefix: ' ', thousands: '.', decimal: ',' }"
formControlName="mfold_quilha" />
......@@ -86,14 +86,12 @@
<mat-form-field class="field medium" appearance="outline">
<mat-label>Categoria</mat-label>
<mat-select formControlName="categoria">
<mat-option [value]="1">Granel Sólido</mat-option>
<mat-option [value]="2">Granel Líquido</mat-option>
<mat-option [value]="3">Carga Geral</mat-option>
<mat-select formControlName="categoria" (selectionChange)="onCategoriaChange($event.value)">
<mat-option *ngFor="let cat of categoria" [value]="cat.id">
{{ cat.nome }}
</mat-option>
</mat-select>
<mat-error *ngIf="empForm.get('categoria')?.invalid">
{{ getErrorMessage("categoria") }}
</mat-error>
<mat-error *ngIf="empForm.get('categoria')?.invalid">{{ getErrorMessage('categoria') }}</mat-error>
</mat-form-field>
<mat-form-field class="field small" appearance="outline">
<mat-label>Flag</mat-label>
......
......@@ -40,12 +40,17 @@ import { NgxCurrencyDirective } from 'ngx-currency';
styleUrl: './navio-edit.component.scss',
})
export class NavioEditComponent implements OnInit {
empForm: FormGroup;
fileName = '';
imageUrl: string | ArrayBuffer | null = '';
selectedFile: File | null = null;
categoria: number[] = [1, 2];
categoria = [
{ id: 1, nome: 'Granel Sólido' },
{ id: 2, nome: 'Granel Líquido' },
{ id: 3, nome: 'Carga Geral' }
];
constructor(
private _fb: FormBuilder,
private _empService: NavioService,
......@@ -68,9 +73,22 @@ export class NavioEditComponent implements OnInit {
flag: [Number(this.data?.flag) || '', Validators.required],
obs: [this.data?.obs || ''],
});
this.empForm.get('categoria')?.valueChanges.subscribe(catId => {
const cat = this.categoria.find((c: any) => c.id === catId);
if (cat && cat.nome === 'Granel Líquido') {
this.empForm.get('mfold_quilha')?.setValidators([Validators.required]);
} else {
this.empForm.get('mfold_quilha')?.clearValidators();
}
this.empForm.get('mfold_quilha')?.updateValueAndValidity();
});
}
selectedCategoriaNome: string = '';
onCategoriaChange(catId: any) {
const cat = this.categoria.find((c: any) => c.id === catId);
this.selectedCategoriaNome = cat ? cat.nome : '';
}
countries = [
{ id: 1, name: 'Afeganistão', flagUrl: 'https://flagcdn.com/w20/af.png' },
{ id: 2, name: 'África do Sul', flagUrl: 'https://flagcdn.com/w20/za.png' },
......@@ -413,6 +431,7 @@ export class NavioEditComponent implements OnInit {
onCountrySelected(country: { name: string; flagUrl: string }) {
this.selectedCountry = country;
}
preventNegative(event: KeyboardEvent): void {
if (event.key === '-' || event.key === '+' || event.key === 'e') {
event.preventDefault();
......
......@@ -20,6 +20,17 @@
}}</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field class="field medium" appearance="outline">
<mat-label>Data de Início</mat-label>
<input matInput type="date" formControlName="dataInicio" />
</mat-form-field>
<mat-form-field class="field medium" appearance="outline">
<mat-label>Data de Fim</mat-label>
<input matInput type="date" formControlName="dataFim" />
</mat-form-field>
</div>
<!--
<mat-form-field class="field medium" appearance="outline">
<mat-label>Categoria</mat-label>
......
......@@ -59,8 +59,8 @@ export class NavioSearchComponent implements OnInit {
) {
this.empForm = this._fb.group({
imo: [''],
categoria: [''],
flag: [''],
dataInicio: [''],
dataFim: [''],
});
}
countries = [
......@@ -450,10 +450,10 @@ export class NavioSearchComponent implements OnInit {
if (this.empForm.valid) {
const searchCriteria = {
imo: this.empForm.value.imo,
categoria: this.empForm.value.categoria,
flag: this.empForm.value.flag,
dataInicio: this.empForm.value.dataInicio,
dataFim: this.empForm.value.dataFim,
};
console.log('Search Criteria:', searchCriteria);
this._empService.searchNavios(searchCriteria).subscribe({
next: (val: any) => {
this.toastService.success('Busca realizada com sucesso');
......
......@@ -10,6 +10,10 @@
</app-add-search>
<div class="main-body">
<button mat-raised-button color="primary" style="background-color: #43a047; color: #fff; margin: 12px 0;" (click)="saveDataInCSV('aceites')">
<mat-icon>download</mat-icon>
Exportar Excel
</button>
<div class="table-container" style="overflow-x: auto">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
......
......@@ -30,6 +30,7 @@ import { AuthService } from '../../../auth.service';
import { jwtDecode } from 'jwt-decode';
import { BlackListAddComponent } from '../../crud-blackList/black-list-add/black-list-add.component';
import { ToastrService } from 'ngx-toastr';
import { CsvService } from '../../../csv.service';
interface NavioData {
id: number;
imo: number;
......@@ -101,9 +102,10 @@ export class NaviosComponent implements OnInit {
private _coreService: CoreService,
private cdr: ChangeDetectorRef,
private toastService: ToastrService,
private _csvService: CsvService,
) {}
) { }
ngOnInit(): void {
this.validationToken();
}
......@@ -559,7 +561,7 @@ export class NaviosComponent implements OnInit {
}
addBlackList(data:any){
addBlackList(data: any) {
this._dialog.open(BlackListAddComponent, {
data,
autoFocus: true, // Foca no primeiro campo interativo do formulário
......@@ -570,7 +572,7 @@ export class NaviosComponent implements OnInit {
}
openAddEmpForm() {
this._dialog.open(NavioAddComponent,{
this._dialog.open(NavioAddComponent, {
autoFocus: true, // Foca no primeiro campo interativo do formulário
disableClose: true, // Impede que o diálogo feche ao clicar fora
width: '600px', // Define a largura do diálogo
......@@ -597,7 +599,7 @@ export class NaviosComponent implements OnInit {
} else {
console.error('sessionStorage não está disponível.');
}
}
}
......@@ -608,4 +610,73 @@ export class NaviosComponent implements OnInit {
width: '600px', // Define a largura do diálogo
});
}
public saveDataInCSV(name: string): void {
this._navioService.getAllAceitesSemPaginacao().subscribe({
next: (aceites: any[]) => {
const data = aceites.map(a => {
const userRaw = a.user || '';
let idUsuario = '';
let email = '';
// Extrai ID e email do campo "Usuário"
const match = userRaw.match(/User\(id=(\d+),\s*email=([^)]+)\)/);
if (match) {
idUsuario = match[1];
email = match[2];
} else if (userRaw.match(/User\(id=(\d+)\)/)) {
idUsuario = userRaw.match(/User\(id=(\d+)\)/)[1];
}
// Categoria
let categoriaLabel = 'Não informado';
switch (+a.categoria) {
case 1:
categoriaLabel = 'Granel Sólido';
break;
case 2:
categoriaLabel = 'Granel Líquido';
break;
case 3:
categoriaLabel = 'Carga Geral';
break;
}
// Flag
let flagLabel = '';
if (a.flag && !isNaN(+a.flag)) {
const flagObj = this.countries.find(c => c.id === +a.flag);
flagLabel = flagObj ? flagObj.name : a.flag;
} else {
flagLabel = a.flag || 'Não informado';
}
return {
Nome: a.nome,
IMO: a.imo,
'ID Usuário': idUsuario,
Email: email,
Categoria: categoriaLabel,
Flag: flagLabel,
Observações: a.obs,
Pontal: a.pontal,
'Moldagem Quilha': a.mfold_quilha,
};
});
const csvContent = this._csvService.saveDataInCSV(data);
const hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
hiddenElement.target = '_blank';
hiddenElement.download = name + '.csv';
hiddenElement.click();
},
error: (err) => {
this._coreService.openSnackBar('Erro ao exportar CSV');
console.error(err);
}
});
}
}
......@@ -37,7 +37,11 @@
</div>
<div class="column" style="flex: 1 1 30%; margin-bottom: 10px;">
<p><strong>Categoria:</strong>
{{ data.categoria === 1 ? 'Granel Sólido' : (data.categoria === 2 ? 'Granel Líquido' : (data.categoria === 3 ? 'Carga Geral' : 'Não informado')) }}
{{
+data.categoria === 1 ? 'Granel Sólido' :
(+data.categoria === 2 ? 'Granel Líquido' :
(+data.categoria === 3 ? 'Carga Geral' : 'Não informado'))
}}
</p>
</div>
<div class="column" style="flex: 1 1 30%; margin-bottom: 10px;">
......
<div class="grid-container">
<h1 class="mat-h1">Dashboard</h1>
<!-- Botão para Baixar Dados em CSV -->
<button mat-raised-button color="primary" style="background-color: #43a047; color: #fff; margin-bottom: 16px;"
(click)="saveDataInCSV('dashboard-dados')">
<mat-icon>download</mat-icon>
Baixar Dados CSV
</button>
<!-- Grid para os Gráficos -->
<mat-grid-list [cols]="isSmallScreen ? 1 : 3" gutterSize="16px">
<mat-grid-tile>
......
......@@ -9,7 +9,7 @@ import { ChartModule } from 'primeng/chart';
import { HttpClientModule } from '@angular/common/http'; // Import necessário para requisições HTTP
import { NavioSearchComponent } from '../crud-navios/navio-search/navio-search.component';
import { NavioService } from '../../services/navio.service';
import { CsvService } from '../../csv.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
......@@ -43,7 +43,9 @@ export class DashboardComponent implements OnInit {
onResize() {
this.isSmallScreen = window.innerWidth < 768;
}
constructor(private navioService: NavioService) {}
constructor(private navioService: NavioService,
private _csvService: CsvService // Injetando o serviço CSV
) {}
ngOnInit(): void {
// Consumindo o serviço para obter os dados do dashboard
......@@ -93,4 +95,27 @@ export class DashboardComponent implements OnInit {
};
});
}
public saveDataInCSV(name: string): void {
// organize o data com base na response e deixe nesse formato {"titulo": "valor"}
const data: Array<any> = [
{ "Indicador": "Total de Navios", "Valor": this.totalNavios },
{ "Indicador": "Total de Usuários", "Valor": this.totalUsuarios },
{ "Indicador": "Total de Berços", "Valor": this.totalBercos },
{ "Indicador": "Total de Aceites", "Valor": this.totalAceites },
{ "Indicador": "Total Aceitos", "Valor": this.dataDoughnut?.datasets[0]?.data[0] ?? 0 },
{ "Indicador": "Total Não Aceitos", "Valor": this.dataDoughnut?.datasets[0]?.data[1] ?? 0 },
{ "Indicador": "Total Não Especificados", "Valor": this.dataBar?.datasets[0]?.data[2] ?? 0 },
{ "Indicador": "Navios na Black-list", "Valor": this.dataDoughnut?.datasets[0]?.data[2] ?? 0 }
];
console.log(data);
let csvContent = this._csvService.saveDataInCSV(data);
var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
hiddenElement.target = '_blank';
hiddenElement.download = name + '.csv';
hiddenElement.click();
}
}
......@@ -26,9 +26,9 @@
<td mat-cell *matCellDef="let row">
{{
row.role === 'COMPANY'
? 'ADMIN'
? 'Agente do Porto'
: row.role === 'CANDIDATE'
? 'USUÁRIO'
? 'Agente do Navio'
: 'Desconhecido'
}}
</td>
......
......@@ -86,4 +86,9 @@ export class BlackListService {
return throwError(error);
}));
}
getAllBlackListSemPaginacao(): Observable<any[]> {
return this._http.get<any>(`${this.apiUrl}/sem-paginacao`).pipe(
map((res: any) => res._embedded?.blackListResponseList || [])
);
}
}
......@@ -19,7 +19,14 @@ export class AceiteService {
constructor(private _http: HttpClient) { }
getAllAceitesSemPaginacao(): Observable<any[]> {
return this._http.get<any>(`${this.apiUrl}/sem-paginacao`).pipe(
map((res: any) => {
// Ajuste conforme a estrutura do seu backend
return res._embedded?.acceptResponseList || [];
})
);
}
addAceite(data: any, foto: File | null): Observable<any> {
console.log(JSON.stringify(JSON.stringify(data)));
console.log(foto);
......@@ -83,13 +90,12 @@ export class AceiteService {
if (data.imo) {
params = params.set('imo', data.imo);
}
if (data.status) {
params = params.set('status', data.status);
if (data.dataInicio) {
params = params.set('dataInicio', data.dataInicio);
}
if (data.nome) {
params = params.set('nome', data.nome);
if (data.dataFim) {
params = params.set('dataFim', data.dataFim);
}
// Faz a requisição GET com os parâmetros
return this._http.get<any>(`${this.apiUrl}/custom`, { params }).pipe(
tap((res: any) => {
......
......@@ -79,7 +79,7 @@ export class BercosService {
}
getBercosListSemPaginacao(): Observable<any> {
return this._http.get<any>(this.apiUrl).pipe(
return this._http.get<any>(`${this.apiUrl}/sem-paginacao`).pipe(
tap((res: any) => {
console.log('Lista completa de berços:', res);
}),
......@@ -112,4 +112,12 @@ export class BercosService {
})
);
}
getAllAceitesSemPaginacao(): Observable<any[]> {
return this._http.get<any>(`${this.apiUrl}/sem-paginacao`).pipe(
map((res: any) => {
// Ajuste conforme a estrutura do seu backend
return res._embedded?.bercoResponseList || [];
})
);
}
}
......@@ -5,7 +5,7 @@ import {
HttpParams,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { catchError, map, tap } from 'rxjs/operators';
import { environment } from '../../environments/.env'; // Importa o environment
@Injectable({
......@@ -15,7 +15,7 @@ export class NavioService {
users: any[] = [];
private apiUrl = environment.API_URL + '/api/vessels';
private apiUrlDash = environment.API_URL + '/statistics/all';
constructor(private _http: HttpClient) {}
constructor(private _http: HttpClient) { }
addEmployee1(data: any, foto: File): Observable<any> {
console.log(JSON.stringify(JSON.stringify(data)));
......@@ -72,11 +72,11 @@ export class NavioService {
if (data.imo) {
params = params.set('imo', data.imo);
}
if (data.status) {
params = params.set('status', data.status);
if (data.dataInicio) {
params = params.set('dataInicio', data.dataInicio);
}
if (data.nome) {
params = params.set('nome', data.nome);
if (data.dataFim) {
params = params.set('dataFim', data.dataFim);
}
// Faz a requisição GET com os parâmetros
......@@ -172,6 +172,13 @@ export class NavioService {
})
);
}
getAllAceitesSemPaginacao(): Observable<any[]> {
return this._http.get<any>(`${this.apiUrl}/sem-paginacao`).pipe(
map((res: any) => res._embedded?.vesselResponseList || [])
);
}
}
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { catchError, Observable, tap, throwError } from 'rxjs';
import { catchError, map, Observable, tap, throwError } from 'rxjs';
import { environment } from '../../../environments/.env'; // Importa o environment
@Injectable({
......@@ -42,4 +42,12 @@ export class UserService {
})
);
}
getAllAceitesSemPaginacao(): Observable<any[]> {
return this._http.get<any>(`${this.apiUrl}/sem-paginacao`).pipe(
map((res: any) => {
// Ajuste conforme a estrutura do seu backend
return res._embedded?.acceptResponseList || [];
})
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment