lib-portal-angular 0.0.87 → 0.0.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/components.module.mjs +65 -40
- package/esm2022/lib/components/csv-importer/csv-importer.component.mjs +92 -0
- package/esm2022/lib/components/data-excel-exporter/IExcelExportConfig.mjs +2 -0
- package/esm2022/lib/components/data-excel-exporter/data-excel-exporter.component.mjs +126 -0
- package/esm2022/lib/components/data-excel-import/data-excel-importer.component.mjs +198 -0
- package/esm2022/lib/components/multi-select/multi-select.component.mjs +162 -114
- package/esm2022/lib/components/pdf-data-handler/argenta-pdf-data-handler.component.mjs +147 -0
- package/esm2022/lib/components/pdf-data-handler/function/formatToBrazilianNumber.mjs +7 -0
- package/esm2022/lib/components/pdf-data-handler/function/parseBrazilianNumber.mjs +9 -0
- package/esm2022/lib/components/pdf-data-handler/interface/DataRow.mjs +2 -0
- package/esm2022/lib/components/pdf-data-handler/interface/PdfExportConfig.mjs +2 -0
- package/esm2022/lib/components/pdf-data-handler/interface/PdfTableStyles.mjs +2 -0
- package/esm2022/lib/components/pdf-data-handler/interface/RowCalculation.mjs +2 -0
- package/esm2022/lib/components/pdf-data-handler/interface/TotalizerConfig.mjs +2 -0
- package/esm2022/lib/components/pdf-download/argenta-pdf-download.component.mjs +51 -0
- package/esm2022/public-api.mjs +36 -5
- package/fesm2022/lib-portal-angular.mjs +1093 -422
- package/fesm2022/lib-portal-angular.mjs.map +1 -1
- package/lib/components/components.module.d.ts +10 -5
- package/lib/components/csv-importer/csv-importer.component.d.ts +19 -0
- package/lib/components/data-excel-exporter/IExcelExportConfig.d.ts +21 -0
- package/lib/components/data-excel-exporter/data-excel-exporter.component.d.ts +9 -0
- package/lib/components/data-excel-import/data-excel-importer.component.d.ts +44 -0
- package/lib/components/multi-select/multi-select.component.d.ts +20 -9
- package/lib/components/pdf-data-handler/argenta-pdf-data-handler.component.d.ts +15 -0
- package/lib/components/pdf-data-handler/function/formatToBrazilianNumber.d.ts +1 -0
- package/lib/components/pdf-data-handler/function/parseBrazilianNumber.d.ts +1 -0
- package/lib/components/pdf-data-handler/interface/DataRow.d.ts +3 -0
- package/lib/components/pdf-data-handler/interface/PdfExportConfig.d.ts +12 -0
- package/lib/components/pdf-data-handler/interface/PdfTableStyles.d.ts +28 -0
- package/lib/components/pdf-data-handler/interface/RowCalculation.d.ts +4 -0
- package/lib/components/pdf-data-handler/interface/TotalizerConfig.d.ts +8 -0
- package/lib/components/pdf-download/argenta-pdf-download.component.d.ts +13 -0
- package/package.json +1 -1
- package/public-api.d.ts +34 -3
@@ -1,18 +1,20 @@
|
|
1
1
|
import * as i0 from '@angular/core';
|
2
|
-
import { Injectable, EventEmitter, Component, Input, Output, ChangeDetectionStrategy, HostListener, ViewChild, forwardRef, Directive, ViewContainerRef, NgModule, createComponent } from '@angular/core';
|
2
|
+
import { Injectable, EventEmitter, Component, Input, Output, ChangeDetectionStrategy, HostListener, ViewChild, forwardRef, Directive, ViewEncapsulation, ViewContainerRef, NgModule, createComponent } from '@angular/core';
|
3
3
|
import * as i1 from '@angular/common';
|
4
4
|
import { CommonModule } from '@angular/common';
|
5
5
|
import * as i2 from '@angular/forms';
|
6
6
|
import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
7
|
-
import * as
|
7
|
+
import * as i4 from 'lucide-angular';
|
8
8
|
import { LucideAngularModule, icons } from 'lucide-angular';
|
9
9
|
import hljs from 'highlight.js';
|
10
10
|
import * as i1$1 from '@ng-bootstrap/ng-bootstrap';
|
11
11
|
import { Subject, of, Subscription, Observable } from 'rxjs';
|
12
|
-
import { debounceTime,
|
13
|
-
import * as
|
12
|
+
import { debounceTime, distinctUntilChanged, switchMap, tap, map, catchError, takeUntil } from 'rxjs/operators';
|
13
|
+
import * as i1$2 from '@angular/common/http';
|
14
14
|
import { HttpParams } from '@angular/common/http';
|
15
|
-
import
|
15
|
+
import jsPDF from 'jspdf';
|
16
|
+
import 'jspdf-autotable';
|
17
|
+
import * as XLSX from 'xlsx';
|
16
18
|
import { NgSelectModule } from '@ng-select/ng-select';
|
17
19
|
import * as CryptoJS from 'crypto-js';
|
18
20
|
|
@@ -1151,7 +1153,7 @@ class CalendarArgentaComponent {
|
|
1151
1153
|
return this.locales[this.locale]?.daysOfWeek || this.locales['en'].daysOfWeek;
|
1152
1154
|
}
|
1153
1155
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalendarArgentaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1154
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CalendarArgentaComponent, selector: "argenta-calendar", inputs: { id: "id", placeholder: "placeholder", label: "label", minDate: "minDate", maxDate: "maxDate", locale: "locale", useTime: "useTime", initialDate: "initialDate", rangeMode: "rangeMode", startDate: "startDate", endDate: "endDate", closeButtonLabel: "closeButtonLabel" }, outputs: { rangeChange: "rangeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"form-group\">\n <label [for]=\"id\" [ngClass]=\"'label-styles'\">{{ label }}</label>\n <div class=\"input-wrapper\">\n <input\n id=\"{{ id }}\"\n type=\"text\"\n class=\"custom-input\"\n [attr.placeholder]=\"rangeMode && useTime ? 'dd/MM/yyyy HH:mm - dd/MM/yyyy HH:mm' : \n rangeMode && !useTime ? 'dd/MM/yyyy - dd/MM/yyyy' :(!rangeMode && useTime ? 'dd/MM/yyyy HH:mm' : 'dd/MM/yyyy')\"\n [value]=\"inputDate\"\n (input)=\"onInputChange($event)\"\n (keypress)=\"handleKeyPress($event)\"\n (click)=\"toggleCalendar()\"\n />\n <lucide-icon name=\"calendar\" class=\"calendar-icon\"></lucide-icon>\n </div>\n\n <div *ngIf=\"invalidDate\" class=\"error-message\">\n {{ locales[locale].invalidDateMessage }}\n <span *ngIf=\"useTime\"> HH:mm.</span>\n </div>\n\n <div class=\"calendar-wrapper\">\n <div class=\"calendar-container\" [ngClass]=\"{ open: isCalendarVisible }\">\n <div class=\"calendar\">\n <div class=\"calendar-header\">\n <button (click)=\"prevMonth()\">‹</button>\n <span>{{ months[currentMonth] }} {{ currentYear }}</span>\n <button (click)=\"nextMonth()\">›</button>\n </div>\n\n <div class=\"calendar-body\">\n <div class=\"calendar-day-names\">\n <span *ngFor=\"let day of daysOfWeek\">{{ day }}</span>\n </div>\n\n <div class=\"calendar-days\">\n <span\n *ngFor=\"let day of daysInMonth; let i = index\"\n [class.today]=\"isToday(day)\"\n [class.selected]=\"isSelected(day)\"\n [class.in-range]=\"isInRange(day)\"\n [class.disabled]=\"isDateDisabled(day)\"\n (click)=\"day ? selectDate(day) : null\"\n >\n {{ day ? day : \"\" }}\n </span>\n </div>\n </div>\n\n <!-- Inputs para inser\u00E7\u00E3o das horas -->\n <div *ngIf=\"useTime\" class=\"time-inputs\">\n <!-- Campo de hora de in\u00EDcio -->\n <div *ngIf=\"rangeMode\" class=\"time-input\">\n <label>{{ locales[locale]?.startTimeLabel || 'Hora de In\u00EDcio' }}</label> <!-- Usando tradu\u00E7\u00E3o -->\n <input type=\"time\" [(ngModel)]=\"startTime\" (change)=\"onTimeChange('start')\" />\n </div>\n\n <!-- Campo de hora de fim -->\n <div *ngIf=\"rangeMode\" class=\"time-input\">\n <label>{{ locales[locale]?.endTimeLabel || 'Hora de Fim' }}</label> <!-- Usando tradu\u00E7\u00E3o -->\n <input type=\"time\" [(ngModel)]=\"endTime\" (change)=\"onTimeChange('end')\" />\n </div>\n\n <!-- Campo de hora \u00FAnica (se n\u00E3o for range) -->\n <div *ngIf=\"!rangeMode\" class=\"time-input\">\n <label>{{ locales[locale]?.startTimeLabel || 'Hora' }}</label> <!-- Usando o label de in\u00EDcio -->\n <input type=\"time\" [(ngModel)]=\"selectedTime\" (change)=\"onTimeChange('single')\" />\n </div>\n </div>\n\n <!-- Bot\u00E3o de fechar o calend\u00E1rio -->\n <button class=\"close-button\" (click)=\"closeCalendar()\">{{ closeButtonLabel }}</button>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.calendar-container{overflow:hidden;max-height:0;transition:max-height .4s ease;position:absolute;top:100%;left:0;z-index:9999;background-color:#fff;box-shadow:0 4px 12px #0000001a;width:auto;max-width:none}.calendar-wrapper{position:relative}@media (max-width: 300px){.calendar-container{width:100vw;left:0}}.calendar-container.open{max-height:500px}.calendar{display:inline-block;border:1px solid #ccc;border-radius:8px;padding:10px;width:450px;font-family:var(--font-family);transition:max-height .4s ease;background-color:#fdfdfd}.calendar .calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;font-weight:700}.calendar .calendar-header button{background-color:var(--primary-color);color:var(--text-color);border:none;padding:8px 12px;cursor:pointer;border-radius:8px;font-size:1.2rem;transition:background-color .2s}.calendar .calendar-header button:hover{background-color:var(--secondary-color)}.calendar .calendar-header span{font-size:1.4rem;color:var(--primary-color);text-align:center;flex-grow:1}.calendar .calendar-body{display:grid;grid-template-columns:repeat(7,1fr);gap:7px}.calendar .calendar-body .calendar-day-names{display:contents}.calendar .calendar-body .calendar-day-names span{text-align:center;font-weight:700;margin-bottom:5px;font-size:.9rem}.calendar .calendar-body .calendar-day-names span:nth-child(1){color:#ff8080}.calendar .calendar-body .calendar-day-names span:nth-child(7){color:#555}.calendar .calendar-body .calendar-days{display:contents}.calendar .calendar-body .calendar-days span{display:flex;justify-content:center;align-items:center;margin:1px;padding:10px;height:45px;width:45px;cursor:pointer;border-radius:50%;transition:background-color .2s,color .2s ease}.calendar .calendar-body .calendar-days span.today{background-color:var(--secondary-color);color:var(--text-color)}.calendar .calendar-body .calendar-days span.selected{background-color:var(--primary-color);color:var(--text-color)}.calendar .calendar-body .calendar-days span.disabled{background-color:#e9ecef;color:#999;cursor:not-allowed}.calendar .calendar-body .calendar-days span:hover:not(.disabled){background-color:var(--secondary-color);color:var(--text-color)}.custom-input{font-family:var(--font-family);color:#333;font-size:.9rem;height:46px;padding:.5rem .75rem;border:1px solid #ccc;border-radius:4px;width:100%;box-sizing:border-box}.custom-input:focus{outline:none;border-color:#ccc}.custom-input::placeholder{font-size:14px;color:#d3d3d3}.label-styles{font-weight:400;font-family:var(--font-family);font-size:16px;line-height:19.36px;text-align:left;margin-top:1rem;margin-bottom:.5rem}.error-message{position:relative;background-color:#ff8080;color:#fff;padding:10px;border-radius:8px;font-size:.9rem;max-width:250px;margin-top:5px}.error-message:after{content:\"\";position:absolute;top:100%;left:20px;border-width:10px;border-style:solid;border-color:#ff8080 transparent transparent transparent}.input-wrapper{position:relative;display:inline-block;width:100%}.input-wrapper .custom-input{width:100%;padding-right:40px;box-sizing:border-box}.input-wrapper .calendar-icon{position:absolute;top:50%;right:10px;transform:translateY(-50%);pointer-events:none;color:#b8b8b8}.calendar-days{display:contents}.calendar-days span{display:flex;justify-content:center;align-items:center;margin:1px;padding:10px;height:45px;width:45px;cursor:pointer;border-radius:50%;transition:background-color .2s,color .2s ease}.calendar-days span.today{background-color:var(--secondary-color);color:var(--text-color);text-decoration:underline}.calendar-days span.selected{background-color:var(--primary-color);color:var(--text-color)}.calendar-days span.in-range{background-color:#fd9;color:#000}.calendar-days span.disabled{background-color:#e9ecef;color:#999;cursor:not-allowed}.calendar-days span:hover:not(.disabled){background-color:var(--secondary-color);color:var(--text-color)}.calendar-body{position:relative}.close-button{float:right;margin-top:10px;background-color:#fff3cd;color:#383838;border:none;padding:6px 12px;cursor:pointer;border-radius:20px;font-size:12px;font-weight:500;transition:all .2s ease}.close-button:hover{background-color:#e9ebec;box-shadow:0 2px 4px #eeebeb26}.close-button:active{transform:translateY(1px)}.time-inputs{display:flex;justify-content:space-between;margin-top:10px}.time-input{display:flex;flex-direction:column;width:45%}.time-input label{font-size:.9rem;margin-bottom:5px}.time-input input{padding:8px;font-size:.9rem;border:1px solid #ccc;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type:
|
1156
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CalendarArgentaComponent, selector: "argenta-calendar", inputs: { id: "id", placeholder: "placeholder", label: "label", minDate: "minDate", maxDate: "maxDate", locale: "locale", useTime: "useTime", initialDate: "initialDate", rangeMode: "rangeMode", startDate: "startDate", endDate: "endDate", closeButtonLabel: "closeButtonLabel" }, outputs: { rangeChange: "rangeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"form-group\">\n <label [for]=\"id\" [ngClass]=\"'label-styles'\">{{ label }}</label>\n <div class=\"input-wrapper\">\n <input\n id=\"{{ id }}\"\n type=\"text\"\n class=\"custom-input\"\n [attr.placeholder]=\"rangeMode && useTime ? 'dd/MM/yyyy HH:mm - dd/MM/yyyy HH:mm' : \n rangeMode && !useTime ? 'dd/MM/yyyy - dd/MM/yyyy' :(!rangeMode && useTime ? 'dd/MM/yyyy HH:mm' : 'dd/MM/yyyy')\"\n [value]=\"inputDate\"\n (input)=\"onInputChange($event)\"\n (keypress)=\"handleKeyPress($event)\"\n (click)=\"toggleCalendar()\"\n />\n <lucide-icon name=\"calendar\" class=\"calendar-icon\"></lucide-icon>\n </div>\n\n <div *ngIf=\"invalidDate\" class=\"error-message\">\n {{ locales[locale].invalidDateMessage }}\n <span *ngIf=\"useTime\"> HH:mm.</span>\n </div>\n\n <div class=\"calendar-wrapper\">\n <div class=\"calendar-container\" [ngClass]=\"{ open: isCalendarVisible }\">\n <div class=\"calendar\">\n <div class=\"calendar-header\">\n <button (click)=\"prevMonth()\">‹</button>\n <span>{{ months[currentMonth] }} {{ currentYear }}</span>\n <button (click)=\"nextMonth()\">›</button>\n </div>\n\n <div class=\"calendar-body\">\n <div class=\"calendar-day-names\">\n <span *ngFor=\"let day of daysOfWeek\">{{ day }}</span>\n </div>\n\n <div class=\"calendar-days\">\n <span\n *ngFor=\"let day of daysInMonth; let i = index\"\n [class.today]=\"isToday(day)\"\n [class.selected]=\"isSelected(day)\"\n [class.in-range]=\"isInRange(day)\"\n [class.disabled]=\"isDateDisabled(day)\"\n (click)=\"day ? selectDate(day) : null\"\n >\n {{ day ? day : \"\" }}\n </span>\n </div>\n </div>\n\n <!-- Inputs para inser\u00E7\u00E3o das horas -->\n <div *ngIf=\"useTime\" class=\"time-inputs\">\n <!-- Campo de hora de in\u00EDcio -->\n <div *ngIf=\"rangeMode\" class=\"time-input\">\n <label>{{ locales[locale]?.startTimeLabel || 'Hora de In\u00EDcio' }}</label> <!-- Usando tradu\u00E7\u00E3o -->\n <input type=\"time\" [(ngModel)]=\"startTime\" (change)=\"onTimeChange('start')\" />\n </div>\n\n <!-- Campo de hora de fim -->\n <div *ngIf=\"rangeMode\" class=\"time-input\">\n <label>{{ locales[locale]?.endTimeLabel || 'Hora de Fim' }}</label> <!-- Usando tradu\u00E7\u00E3o -->\n <input type=\"time\" [(ngModel)]=\"endTime\" (change)=\"onTimeChange('end')\" />\n </div>\n\n <!-- Campo de hora \u00FAnica (se n\u00E3o for range) -->\n <div *ngIf=\"!rangeMode\" class=\"time-input\">\n <label>{{ locales[locale]?.startTimeLabel || 'Hora' }}</label> <!-- Usando o label de in\u00EDcio -->\n <input type=\"time\" [(ngModel)]=\"selectedTime\" (change)=\"onTimeChange('single')\" />\n </div>\n </div>\n\n <!-- Bot\u00E3o de fechar o calend\u00E1rio -->\n <button class=\"close-button\" (click)=\"closeCalendar()\">{{ closeButtonLabel }}</button>\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.calendar-container{overflow:hidden;max-height:0;transition:max-height .4s ease;position:absolute;top:100%;left:0;z-index:9999;background-color:#fff;box-shadow:0 4px 12px #0000001a;width:auto;max-width:none}.calendar-wrapper{position:relative}@media (max-width: 300px){.calendar-container{width:100vw;left:0}}.calendar-container.open{max-height:500px}.calendar{display:inline-block;border:1px solid #ccc;border-radius:8px;padding:10px;width:450px;font-family:var(--font-family);transition:max-height .4s ease;background-color:#fdfdfd}.calendar .calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;font-weight:700}.calendar .calendar-header button{background-color:var(--primary-color);color:var(--text-color);border:none;padding:8px 12px;cursor:pointer;border-radius:8px;font-size:1.2rem;transition:background-color .2s}.calendar .calendar-header button:hover{background-color:var(--secondary-color)}.calendar .calendar-header span{font-size:1.4rem;color:var(--primary-color);text-align:center;flex-grow:1}.calendar .calendar-body{display:grid;grid-template-columns:repeat(7,1fr);gap:7px}.calendar .calendar-body .calendar-day-names{display:contents}.calendar .calendar-body .calendar-day-names span{text-align:center;font-weight:700;margin-bottom:5px;font-size:.9rem}.calendar .calendar-body .calendar-day-names span:nth-child(1){color:#ff8080}.calendar .calendar-body .calendar-day-names span:nth-child(7){color:#555}.calendar .calendar-body .calendar-days{display:contents}.calendar .calendar-body .calendar-days span{display:flex;justify-content:center;align-items:center;margin:1px;padding:10px;height:45px;width:45px;cursor:pointer;border-radius:50%;transition:background-color .2s,color .2s ease}.calendar .calendar-body .calendar-days span.today{background-color:var(--secondary-color);color:var(--text-color)}.calendar .calendar-body .calendar-days span.selected{background-color:var(--primary-color);color:var(--text-color)}.calendar .calendar-body .calendar-days span.disabled{background-color:#e9ecef;color:#999;cursor:not-allowed}.calendar .calendar-body .calendar-days span:hover:not(.disabled){background-color:var(--secondary-color);color:var(--text-color)}.custom-input{font-family:var(--font-family);color:#333;font-size:.9rem;height:46px;padding:.5rem .75rem;border:1px solid #ccc;border-radius:4px;width:100%;box-sizing:border-box}.custom-input:focus{outline:none;border-color:#ccc}.custom-input::placeholder{font-size:14px;color:#d3d3d3}.label-styles{font-weight:400;font-family:var(--font-family);font-size:16px;line-height:19.36px;text-align:left;margin-top:1rem;margin-bottom:.5rem}.error-message{position:relative;background-color:#ff8080;color:#fff;padding:10px;border-radius:8px;font-size:.9rem;max-width:250px;margin-top:5px}.error-message:after{content:\"\";position:absolute;top:100%;left:20px;border-width:10px;border-style:solid;border-color:#ff8080 transparent transparent transparent}.input-wrapper{position:relative;display:inline-block;width:100%}.input-wrapper .custom-input{width:100%;padding-right:40px;box-sizing:border-box}.input-wrapper .calendar-icon{position:absolute;top:50%;right:10px;transform:translateY(-50%);pointer-events:none;color:#b8b8b8}.calendar-days{display:contents}.calendar-days span{display:flex;justify-content:center;align-items:center;margin:1px;padding:10px;height:45px;width:45px;cursor:pointer;border-radius:50%;transition:background-color .2s,color .2s ease}.calendar-days span.today{background-color:var(--secondary-color);color:var(--text-color);text-decoration:underline}.calendar-days span.selected{background-color:var(--primary-color);color:var(--text-color)}.calendar-days span.in-range{background-color:#fd9;color:#000}.calendar-days span.disabled{background-color:#e9ecef;color:#999;cursor:not-allowed}.calendar-days span:hover:not(.disabled){background-color:var(--secondary-color);color:var(--text-color)}.calendar-body{position:relative}.close-button{float:right;margin-top:10px;background-color:#fff3cd;color:#383838;border:none;padding:6px 12px;cursor:pointer;border-radius:20px;font-size:12px;font-weight:500;transition:all .2s ease}.close-button:hover{background-color:#e9ebec;box-shadow:0 2px 4px #eeebeb26}.close-button:active{transform:translateY(1px)}.time-inputs{display:flex;justify-content:space-between;margin-top:10px}.time-input{display:flex;flex-direction:column;width:45%}.time-input label{font-size:.9rem;margin-bottom:5px}.time-input input{padding:8px;font-size:.9rem;border:1px solid #ccc;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] }); }
|
1155
1157
|
}
|
1156
1158
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CalendarArgentaComponent, decorators: [{
|
1157
1159
|
type: Component,
|
@@ -1525,192 +1527,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
1525
1527
|
type: Output
|
1526
1528
|
}] } });
|
1527
1529
|
|
1528
|
-
class DragDropListComponent {
|
1529
|
-
constructor() {
|
1530
|
-
this.nonSelectedList = [];
|
1531
|
-
this.nonSelectedButtonClick = new EventEmitter();
|
1532
|
-
this.nonSelectedInputChanged = new EventEmitter();
|
1533
|
-
this.selectedList = [];
|
1534
|
-
this.selectedButtonClick = new EventEmitter();
|
1535
|
-
this.selectedInputChanged = new EventEmitter();
|
1536
|
-
this.nonSelectedListInputSubject = new Subject();
|
1537
|
-
this.selectedListInputSubject = new Subject();
|
1538
|
-
this.ButtonClasses = ButtonClasses; // Adicione a enumeração ao componente
|
1539
|
-
this.draggedItem = null;
|
1540
|
-
this.nonSelectedListInputSubject.pipe(debounceTime(2000)).subscribe((value) => {
|
1541
|
-
this.nonSelectedInputChanged.emit(value);
|
1542
|
-
});
|
1543
|
-
this.selectedListInputSubject.pipe(debounceTime(2000)).subscribe((value) => {
|
1544
|
-
this.selectedInputChanged.emit(value);
|
1545
|
-
});
|
1546
|
-
}
|
1547
|
-
onDragStart(item) {
|
1548
|
-
this.draggedItem = item;
|
1549
|
-
}
|
1550
|
-
onDragOver(event) {
|
1551
|
-
event.preventDefault();
|
1552
|
-
}
|
1553
|
-
onDrop(list, event) {
|
1554
|
-
event.preventDefault();
|
1555
|
-
if (this.draggedItem) {
|
1556
|
-
const index = list.indexOf(this.draggedItem);
|
1557
|
-
if (index === -1) {
|
1558
|
-
this.removeItem(this.draggedItem);
|
1559
|
-
list.push(this.draggedItem);
|
1560
|
-
}
|
1561
|
-
this.draggedItem = null;
|
1562
|
-
}
|
1563
|
-
}
|
1564
|
-
removeItem(item) {
|
1565
|
-
[this.nonSelectedList, this.selectedList].forEach((list) => {
|
1566
|
-
const index = list.indexOf(item);
|
1567
|
-
if (index !== -1) {
|
1568
|
-
list.splice(index, 1);
|
1569
|
-
}
|
1570
|
-
});
|
1571
|
-
}
|
1572
|
-
nonSelectedListInputChange(event) {
|
1573
|
-
this.nonSelectedListInputSubject.next(event.target.value);
|
1574
|
-
}
|
1575
|
-
selectedListInputChange(event) {
|
1576
|
-
this.selectedListInputSubject.next(event.target.value);
|
1577
|
-
}
|
1578
|
-
selButtonClick() {
|
1579
|
-
this.selectedButtonClick.emit();
|
1580
|
-
}
|
1581
|
-
nonSelButtonClick() {
|
1582
|
-
this.nonSelectedButtonClick.emit();
|
1583
|
-
}
|
1584
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragDropListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1585
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DragDropListComponent, selector: "argenta-drag-drop-list", inputs: { nonSelectedTitle: "nonSelectedTitle", nonSelectedList: "nonSelectedList", nonSelectedButtonLabel: "nonSelectedButtonLabel", selectedTitle: "selectedTitle", selectedList: "selectedList", selectedButtonLabel: "selectedButtonLabel" }, outputs: { nonSelectedButtonClick: "nonSelectedButtonClick", nonSelectedInputChanged: "nonSelectedInputChanged", selectedButtonClick: "selectedButtonClick", selectedInputChanged: "selectedInputChanged" }, ngImport: i0, template: "<!-- Cont\u00EAiner externo para dar a apar\u00EAncia de grupo -->\n<div class=\"group-container\">\n <div class=\"container\">\n <!-- Lista 1 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(nonSelectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ nonSelectedTitle }}</h6>\n <div *ngIf=\"nonSelectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ nonSelectedButtonLabel }}\"\n (onButtonClick)=\"nonSelButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"nonSelectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of nonSelectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n\n <!-- Lista 2 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(selectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ selectedTitle }}</h6>\n <div *ngIf=\"selectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ selectedButtonLabel }}\"\n (onButtonClick)=\"selButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"selectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of selectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.group-container{display:flex;justify-content:center;padding:20px;background-color:#fff;border-radius:12px;box-shadow:0 4px 8px #0000001a;width:80%;margin:auto}.container{display:flex;gap:20px;width:100%}.list{flex:1;padding:10px;background-color:#f0f0f0;border-radius:8px;display:flex;flex-direction:column;align-items:flex-start;gap:10px}.list-input{width:100%;height:40px;margin-bottom:15px;border-radius:4px;border:1px solid #ccc;outline:none;font-size:1rem;resize:none}.item-card{width:100%;padding:15px;background-color:#fff;border-radius:8px;box-shadow:0 2px 5px #0003;cursor:move;display:flex;align-items:center;justify-content:center;text-align:center;font-family:var(--font-family);font-weight:500;font-size:1.1rem;color:#333}.row{display:flex;justify-content:space-between;align-items:center;width:100%;max-height:50px;height:50px}.align-end{display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "argenta-custom-button", inputs: ["type", "label", "btnClass", "fontSize", "disabled", "autofocus", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "name", "value", "permissions"], outputs: ["onButtonClick"] }] }); }
|
1586
|
-
}
|
1587
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragDropListComponent, decorators: [{
|
1588
|
-
type: Component,
|
1589
|
-
args: [{ selector: "argenta-drag-drop-list", template: "<!-- Cont\u00EAiner externo para dar a apar\u00EAncia de grupo -->\n<div class=\"group-container\">\n <div class=\"container\">\n <!-- Lista 1 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(nonSelectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ nonSelectedTitle }}</h6>\n <div *ngIf=\"nonSelectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ nonSelectedButtonLabel }}\"\n (onButtonClick)=\"nonSelButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"nonSelectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of nonSelectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n\n <!-- Lista 2 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(selectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ selectedTitle }}</h6>\n <div *ngIf=\"selectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ selectedButtonLabel }}\"\n (onButtonClick)=\"selButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"selectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of selectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.group-container{display:flex;justify-content:center;padding:20px;background-color:#fff;border-radius:12px;box-shadow:0 4px 8px #0000001a;width:80%;margin:auto}.container{display:flex;gap:20px;width:100%}.list{flex:1;padding:10px;background-color:#f0f0f0;border-radius:8px;display:flex;flex-direction:column;align-items:flex-start;gap:10px}.list-input{width:100%;height:40px;margin-bottom:15px;border-radius:4px;border:1px solid #ccc;outline:none;font-size:1rem;resize:none}.item-card{width:100%;padding:15px;background-color:#fff;border-radius:8px;box-shadow:0 2px 5px #0003;cursor:move;display:flex;align-items:center;justify-content:center;text-align:center;font-family:var(--font-family);font-weight:500;font-size:1.1rem;color:#333}.row{display:flex;justify-content:space-between;align-items:center;width:100%;max-height:50px;height:50px}.align-end{display:flex;justify-content:flex-end}\n"] }]
|
1590
|
-
}], ctorParameters: function () { return []; }, propDecorators: { nonSelectedTitle: [{
|
1591
|
-
type: Input
|
1592
|
-
}], nonSelectedList: [{
|
1593
|
-
type: Input
|
1594
|
-
}], nonSelectedButtonLabel: [{
|
1595
|
-
type: Input
|
1596
|
-
}], nonSelectedButtonClick: [{
|
1597
|
-
type: Output
|
1598
|
-
}], nonSelectedInputChanged: [{
|
1599
|
-
type: Output
|
1600
|
-
}], selectedTitle: [{
|
1601
|
-
type: Input
|
1602
|
-
}], selectedList: [{
|
1603
|
-
type: Input
|
1604
|
-
}], selectedButtonLabel: [{
|
1605
|
-
type: Input
|
1606
|
-
}], selectedButtonClick: [{
|
1607
|
-
type: Output
|
1608
|
-
}], selectedInputChanged: [{
|
1609
|
-
type: Output
|
1610
|
-
}] } });
|
1611
|
-
|
1612
|
-
class DynamicModalComponent {
|
1613
|
-
constructor() {
|
1614
|
-
this.modalTitle = "Modal Title";
|
1615
|
-
this.modalSizeClass = "";
|
1616
|
-
this.modalId = "dynamicModal"; // ID único para cada modal
|
1617
|
-
}
|
1618
|
-
openModal() {
|
1619
|
-
const modalElement = document.getElementById(this.modalId);
|
1620
|
-
if (modalElement) {
|
1621
|
-
modalElement.classList.add("show");
|
1622
|
-
modalElement.setAttribute("aria-hidden", "false");
|
1623
|
-
modalElement.style.display = "block";
|
1624
|
-
document.body.classList.add("modal-open");
|
1625
|
-
// Adiciona o backdrop manualmente se não existir
|
1626
|
-
if (!document.querySelector(`.modal-backdrop[data-modal-id="${this.modalId}"]`)) {
|
1627
|
-
const backdrop = document.createElement("div");
|
1628
|
-
backdrop.className = "modal-backdrop fade show";
|
1629
|
-
backdrop.setAttribute("data-modal-id", this.modalId);
|
1630
|
-
document.body.appendChild(backdrop);
|
1631
|
-
}
|
1632
|
-
}
|
1633
|
-
}
|
1634
|
-
closeModal() {
|
1635
|
-
const modalElement = document.getElementById(this.modalId);
|
1636
|
-
if (modalElement) {
|
1637
|
-
modalElement.classList.remove("show");
|
1638
|
-
modalElement.setAttribute("aria-hidden", "true");
|
1639
|
-
modalElement.style.display = "none";
|
1640
|
-
document.body.classList.remove("modal-open");
|
1641
|
-
document
|
1642
|
-
.querySelector(`.modal-backdrop[data-modal-id="${this.modalId}"]`)
|
1643
|
-
?.remove();
|
1644
|
-
}
|
1645
|
-
}
|
1646
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1647
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicModalComponent, selector: "argenta-dynamic-modal", inputs: { modalTitle: "modalTitle", modalSizeClass: "modalSizeClass", modalId: "modalId" }, ngImport: i0, template: "<div\n class=\"modal fade\"\n [id]=\"modalId\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"modalId + 'Label'\"\n aria-hidden=\"true\"\n>\n <div class=\"modal-dialog\" [ngClass]=\"modalSizeClass\">\n <div class=\"modal-content\">\n <div class=\"modal-header custom-header\">\n <h5 class=\"modal-title custom-modal-title\" [id]=\"modalId + 'Label'\">\n {{ modalTitle }}\n </h5>\n <button\n type=\"button\"\n class=\"custom-close-button\"\n (click)=\"closeModal()\"\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n <div class=\"modal-body custom-body\">\n <ng-content select=\"[modal-body]\"></ng-content>\n </div>\n <div class=\"modal-footer custom-footer\">\n <ng-content select=\"[modal-footer]\"></ng-content>\n </div>\n </div>\n </div>\n</div>\n", styles: [".custom-header{background-color:var(--primary-color)!important;color:var(--text-color)!important;font-size:1.25rem!important;font-family:var(--font-family)!important;padding:1rem;position:relative}.custom-header .custom-close-button{position:absolute;right:1rem;background:none;border:none;font-size:2.5rem;color:var(--text-color);cursor:pointer}.custom-header .custom-close-button:hover{color:var(--danger-color)}.custom-modal-title{color:var(--text-color)!important;font-size:1.8rem!important;font-family:var(--font-family)!important}.custom-body{background-color:#fff;padding:1rem}.custom-footer{background-color:#fff;padding:.75rem;display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
1648
|
-
}
|
1649
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicModalComponent, decorators: [{
|
1650
|
-
type: Component,
|
1651
|
-
args: [{ selector: "argenta-dynamic-modal", template: "<div\n class=\"modal fade\"\n [id]=\"modalId\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"modalId + 'Label'\"\n aria-hidden=\"true\"\n>\n <div class=\"modal-dialog\" [ngClass]=\"modalSizeClass\">\n <div class=\"modal-content\">\n <div class=\"modal-header custom-header\">\n <h5 class=\"modal-title custom-modal-title\" [id]=\"modalId + 'Label'\">\n {{ modalTitle }}\n </h5>\n <button\n type=\"button\"\n class=\"custom-close-button\"\n (click)=\"closeModal()\"\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n <div class=\"modal-body custom-body\">\n <ng-content select=\"[modal-body]\"></ng-content>\n </div>\n <div class=\"modal-footer custom-footer\">\n <ng-content select=\"[modal-footer]\"></ng-content>\n </div>\n </div>\n </div>\n</div>\n", styles: [".custom-header{background-color:var(--primary-color)!important;color:var(--text-color)!important;font-size:1.25rem!important;font-family:var(--font-family)!important;padding:1rem;position:relative}.custom-header .custom-close-button{position:absolute;right:1rem;background:none;border:none;font-size:2.5rem;color:var(--text-color);cursor:pointer}.custom-header .custom-close-button:hover{color:var(--danger-color)}.custom-modal-title{color:var(--text-color)!important;font-size:1.8rem!important;font-family:var(--font-family)!important}.custom-body{background-color:#fff;padding:1rem}.custom-footer{background-color:#fff;padding:.75rem;display:flex;justify-content:flex-end;gap:.5rem}\n"] }]
|
1652
|
-
}], propDecorators: { modalTitle: [{
|
1653
|
-
type: Input
|
1654
|
-
}], modalSizeClass: [{
|
1655
|
-
type: Input
|
1656
|
-
}], modalId: [{
|
1657
|
-
type: Input
|
1658
|
-
}] } });
|
1659
|
-
|
1660
|
-
class DynamicTableComponent {
|
1661
|
-
constructor() {
|
1662
|
-
this.itemsPerPageOptions = [10, 20, 50];
|
1663
|
-
this.showPageInfo = true;
|
1664
|
-
this.currentPage = 1;
|
1665
|
-
this.itemsPerPage = 10;
|
1666
|
-
}
|
1667
|
-
get totalItems() {
|
1668
|
-
return this.config.totalItems ?? this.config.data.length;
|
1669
|
-
}
|
1670
|
-
get paginatedData() {
|
1671
|
-
if (!this.config.pagination) {
|
1672
|
-
// Retorna todos os dados se a paginação estiver desativada
|
1673
|
-
return this.config.data;
|
1674
|
-
}
|
1675
|
-
const itemsPerPage = this.config.itemsPerPage || this.itemsPerPage;
|
1676
|
-
const startIndex = (this.currentPage - 1) * itemsPerPage;
|
1677
|
-
return this.config.data.slice(startIndex, startIndex + itemsPerPage);
|
1678
|
-
}
|
1679
|
-
ngOnInit() {
|
1680
|
-
if (!this.config || !this.config.columns || !this.config.data) {
|
1681
|
-
throw new Error("DynamicTableComponent: Configuração inválida.");
|
1682
|
-
}
|
1683
|
-
// Define valores padrão se não especificados
|
1684
|
-
this.config.showHeader = this.config.showHeader ?? true; // Exibe o cabeçalho por padrão
|
1685
|
-
this.config.pagination = this.config.pagination ?? true; // Ativa paginação por padrão
|
1686
|
-
this.itemsPerPage = this.config.itemsPerPage || 10;
|
1687
|
-
}
|
1688
|
-
onPageChange(newPage) {
|
1689
|
-
this.currentPage = newPage;
|
1690
|
-
}
|
1691
|
-
onItemsPerPageChange(event) {
|
1692
|
-
const target = event.target;
|
1693
|
-
this.itemsPerPage = +target.value;
|
1694
|
-
this.currentPage = 1; // Reinicia a paginação ao alterar os itens por página
|
1695
|
-
}
|
1696
|
-
// Getter para garantir que totalItems nunca seja undefined
|
1697
|
-
get safeTotalItems() {
|
1698
|
-
return this.totalItems || 0;
|
1699
|
-
}
|
1700
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1701
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicTableComponent, selector: "argenta-dynamic-table", inputs: { config: "config", itemsPerPageOptions: "itemsPerPageOptions", showPageInfo: "showPageInfo" }, ngImport: i0, template: "<table class=\"table\" [ngClass]=\"{ nested: config.isNested }\">\n <thead *ngIf=\"config.showHeader\">\n <tr>\n <th *ngFor=\"let column of config.columns\">{{ column.header }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of paginatedData\">\n <td *ngFor=\"let column of config.columns\">\n <ng-container [ngSwitch]=\"column.type\">\n <span *ngSwitchCase=\"'text'\">{{ row[column.key] }}</span>\n <ng-container *ngSwitchCase=\"'template'\">\n <ng-container\n *ngTemplateOutlet=\"\n column.template || null;\n context: { $implicit: row }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </td>\n </tr>\n </tbody>\n</table>\n\n<div\n class=\"text-center pagination-controls\"\n [ngClass]=\"{ nested: config.isNested }\"\n *ngIf=\"config.pagination\"\n>\n <custom-pagination\n [totalItems]=\"safeTotalItems\"\n [itemsPerPage]=\"itemsPerPage\"\n [currentPage]=\"currentPage\"\n [showPageInfo]=\"showPageInfo\"\n (pageChange)=\"onPageChange($event)\"\n >\n </custom-pagination>\n</div>\n", styles: ["@charset \"UTF-8\";.table{width:100%;border-collapse:collapse;border-spacing:0}.table{width:100%;border-collapse:separate;border-spacing:0;overflow:hidden}.table thead th{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);font-size:14px;font-weight:600;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center;line-height:2.5}.table thead th:first-child{border-top-left-radius:10px}.table thead th:last-child{border-top-right-radius:10px}.table.nested thead th{font-size:.7rem;padding:7px;line-height:.8}.table tbody td{font-family:var(--font-family);font-size:14px;color:#737b7b;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center}.table tbody td:first-child{text-align:left;padding-left:1.4rem}.table.nested tbody td:first-child{padding-left:1rem}.table tbody tr:hover{background-color:#f5f5f5!important;transition:background-color .3s ease}.table.nested tbody tr:hover{background-color:#f0f0f0!important}.pagination-controls{display:flex;justify-content:center;align-items:center;margin-top:1rem}.pagination-controls.nested{font-size:.7rem;transform:scale(.7);margin-top:.5rem}.data-table-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.left-section{display:flex;align-items:center}.items-per-page-label{font-family:var(--font-family);font-size:14px;color:#666;margin-right:.5rem}.custom-select{font-family:var(--font-family);font-size:14px;padding:.375rem 1.75rem .375rem .75rem;border:1px solid #ccc;border-radius:.25rem;appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 4 5\"><path fill=\"#666\" d=\"M2 0L0 2h4L2 0zM2 5l2-2H0l2 2z\"/></svg>') no-repeat right .75rem center/8px 10px}.custom-select:focus{border-color:#80bdff;outline:none;box-shadow:0 0 0 .2rem #007bff40}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: CustomPaginationComponent, selector: "custom-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "showPageInfo"], outputs: ["pageChange"] }] }); }
|
1702
|
-
}
|
1703
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicTableComponent, decorators: [{
|
1704
|
-
type: Component,
|
1705
|
-
args: [{ selector: "argenta-dynamic-table", template: "<table class=\"table\" [ngClass]=\"{ nested: config.isNested }\">\n <thead *ngIf=\"config.showHeader\">\n <tr>\n <th *ngFor=\"let column of config.columns\">{{ column.header }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of paginatedData\">\n <td *ngFor=\"let column of config.columns\">\n <ng-container [ngSwitch]=\"column.type\">\n <span *ngSwitchCase=\"'text'\">{{ row[column.key] }}</span>\n <ng-container *ngSwitchCase=\"'template'\">\n <ng-container\n *ngTemplateOutlet=\"\n column.template || null;\n context: { $implicit: row }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </td>\n </tr>\n </tbody>\n</table>\n\n<div\n class=\"text-center pagination-controls\"\n [ngClass]=\"{ nested: config.isNested }\"\n *ngIf=\"config.pagination\"\n>\n <custom-pagination\n [totalItems]=\"safeTotalItems\"\n [itemsPerPage]=\"itemsPerPage\"\n [currentPage]=\"currentPage\"\n [showPageInfo]=\"showPageInfo\"\n (pageChange)=\"onPageChange($event)\"\n >\n </custom-pagination>\n</div>\n", styles: ["@charset \"UTF-8\";.table{width:100%;border-collapse:collapse;border-spacing:0}.table{width:100%;border-collapse:separate;border-spacing:0;overflow:hidden}.table thead th{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);font-size:14px;font-weight:600;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center;line-height:2.5}.table thead th:first-child{border-top-left-radius:10px}.table thead th:last-child{border-top-right-radius:10px}.table.nested thead th{font-size:.7rem;padding:7px;line-height:.8}.table tbody td{font-family:var(--font-family);font-size:14px;color:#737b7b;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center}.table tbody td:first-child{text-align:left;padding-left:1.4rem}.table.nested tbody td:first-child{padding-left:1rem}.table tbody tr:hover{background-color:#f5f5f5!important;transition:background-color .3s ease}.table.nested tbody tr:hover{background-color:#f0f0f0!important}.pagination-controls{display:flex;justify-content:center;align-items:center;margin-top:1rem}.pagination-controls.nested{font-size:.7rem;transform:scale(.7);margin-top:.5rem}.data-table-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.left-section{display:flex;align-items:center}.items-per-page-label{font-family:var(--font-family);font-size:14px;color:#666;margin-right:.5rem}.custom-select{font-family:var(--font-family);font-size:14px;padding:.375rem 1.75rem .375rem .75rem;border:1px solid #ccc;border-radius:.25rem;appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 4 5\"><path fill=\"#666\" d=\"M2 0L0 2h4L2 0zM2 5l2-2H0l2 2z\"/></svg>') no-repeat right .75rem center/8px 10px}.custom-select:focus{border-color:#80bdff;outline:none;box-shadow:0 0 0 .2rem #007bff40}\n"] }]
|
1706
|
-
}], ctorParameters: function () { return []; }, propDecorators: { config: [{
|
1707
|
-
type: Input
|
1708
|
-
}], itemsPerPageOptions: [{
|
1709
|
-
type: Input
|
1710
|
-
}], showPageInfo: [{
|
1711
|
-
type: Input
|
1712
|
-
}] } });
|
1713
|
-
|
1714
1530
|
class FileUploadComponent {
|
1715
1531
|
constructor(authService) {
|
1716
1532
|
this.authService = authService;
|
@@ -2242,174 +2058,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
2242
2058
|
type: Output
|
2243
2059
|
}] } });
|
2244
2060
|
|
2245
|
-
class
|
2246
|
-
|
2247
|
-
|
2248
|
-
|
2249
|
-
|
2061
|
+
class MultiSelectComponent {
|
2062
|
+
onClickOutside(event) {
|
2063
|
+
const target = event.target;
|
2064
|
+
if (!target.closest(".custom-select-container")) {
|
2065
|
+
this.closeDropdown();
|
2066
|
+
}
|
2250
2067
|
}
|
2251
|
-
|
2252
|
-
this.
|
2253
|
-
this.
|
2068
|
+
constructor(authService, http, cdr) {
|
2069
|
+
this.authService = authService;
|
2070
|
+
this.http = http;
|
2071
|
+
this.cdr = cdr;
|
2072
|
+
this.label = "Multi Select";
|
2073
|
+
this.data = [];
|
2074
|
+
this.placeholder = "";
|
2075
|
+
this.id = "multiSelectId";
|
2076
|
+
this.bindLabel = "";
|
2077
|
+
this.bindValue = "";
|
2078
|
+
this.closeOnSelect = false;
|
2079
|
+
this.searchUrl = "";
|
2080
|
+
this.multiple = true;
|
2081
|
+
this.searchParams = {};
|
2082
|
+
this.keyupEvent = new EventEmitter();
|
2083
|
+
this.lastSearchTerm = "";
|
2084
|
+
this.backupData = [];
|
2085
|
+
this.allItems = [];
|
2086
|
+
this.items = of([]);
|
2087
|
+
this.filteredItems = of([]);
|
2088
|
+
this.searchTerms = new Subject();
|
2089
|
+
this.isOpen = false;
|
2090
|
+
this.onChangeCallback = () => { };
|
2091
|
+
this.onTouchedCallback = () => { };
|
2092
|
+
this.isCourseEntered = false;
|
2093
|
+
this.compareFn = (item1, item2) => {
|
2094
|
+
return item1 && item2
|
2095
|
+
? item1[this.bindValue] === item2[this.bindValue]
|
2096
|
+
: item1 === item2;
|
2097
|
+
};
|
2254
2098
|
}
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2099
|
+
ngOnInit() {
|
2100
|
+
this.filteredItems = this.searchTerms.pipe(debounceTime(700), // Reduz chamadas repetitivas
|
2101
|
+
distinctUntilChanged(), // Ignora termos repetidos consecutivos
|
2102
|
+
switchMap((term) => {
|
2103
|
+
// Sempre busca no back-end
|
2104
|
+
return this.search(term).pipe(tap((fetchedItems) => {
|
2105
|
+
this.updateData(fetchedItems);
|
2106
|
+
}), map((fetchedItems) => this.filterOutSelected(fetchedItems)));
|
2107
|
+
}));
|
2108
|
+
this.filteredItems.subscribe({
|
2109
|
+
next: (items) => { },
|
2110
|
+
error: (err) => console.error("Erro ao buscar no back-end:", err),
|
2111
|
+
});
|
2112
|
+
this.fetchInitialData().subscribe((data) => {
|
2113
|
+
this.updateData(data);
|
2114
|
+
});
|
2258
2115
|
}
|
2259
|
-
|
2260
|
-
|
2116
|
+
onInputChange(event) {
|
2117
|
+
const input = event.target.value.trim();
|
2118
|
+
this.searchTerms.next(input);
|
2119
|
+
if (input === "") {
|
2120
|
+
this.fetchInitialData().subscribe((data) => {
|
2121
|
+
this.allItems = data;
|
2122
|
+
this.filteredItems = of(this.filterOutSelected(this.allItems));
|
2123
|
+
});
|
2124
|
+
}
|
2261
2125
|
}
|
2262
|
-
|
2263
|
-
return
|
2126
|
+
search(term) {
|
2127
|
+
return this.http.get(`${this.searchUrl}`, { params: { term } }).pipe(map((response) => {
|
2128
|
+
const transformedItems = response.map((item) => ({
|
2129
|
+
[this.bindValue]: item[this.bindValue],
|
2130
|
+
[this.bindLabel]: item[this.bindLabel],
|
2131
|
+
}));
|
2132
|
+
this.allItems = transformedItems;
|
2133
|
+
this.filteredItems = of(this.filterOutSelected(this.allItems));
|
2134
|
+
this.cdr.markForCheck(); // Notifica o Angular sobre a alteração
|
2135
|
+
return transformedItems;
|
2136
|
+
}), catchError((error) => {
|
2137
|
+
console.error("Erro ao buscar no back-end:", error);
|
2138
|
+
this.filteredItems = of([]);
|
2139
|
+
return of([]);
|
2140
|
+
}));
|
2264
2141
|
}
|
2265
|
-
|
2266
|
-
return this.
|
2142
|
+
fetchInitialData() {
|
2143
|
+
return this.http.get(this.searchUrl).pipe(map((response) => {
|
2144
|
+
const transformedItems = response.map((item) => ({
|
2145
|
+
[this.bindValue]: item[this.bindValue],
|
2146
|
+
[this.bindLabel]: item[this.bindLabel],
|
2147
|
+
}));
|
2148
|
+
this.allItems = transformedItems;
|
2149
|
+
return this.allItems;
|
2150
|
+
}), catchError((error) => {
|
2151
|
+
console.error("Erro ao carregar dados iniciais:", error);
|
2152
|
+
return of([]);
|
2153
|
+
}));
|
2267
2154
|
}
|
2268
|
-
|
2269
|
-
|
2270
|
-
|
2271
|
-
|
2272
|
-
|
2273
|
-
|
2155
|
+
ngOnChanges(changes) {
|
2156
|
+
if (changes["selected"] && !changes["selected"].isFirstChange()) {
|
2157
|
+
this.addSelectedItemsToData();
|
2158
|
+
}
|
2159
|
+
}
|
2160
|
+
updateData(newData) {
|
2161
|
+
newData.forEach((item) => {
|
2162
|
+
const existsInList = this.allItems.some((listItem) => this.compareFn(listItem, item));
|
2163
|
+
if (!existsInList) {
|
2164
|
+
this.allItems.push(item);
|
2165
|
+
}
|
2274
2166
|
});
|
2275
|
-
|
2276
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: JsonViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
2277
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: JsonViewerComponent, selector: "argenta-json-viewer", inputs: { jsonData: "jsonData", isRoot: "isRoot", copyLabel: "copyLabel", showLabel: "showLabel", hideLabel: "hideLabel" }, ngImport: i0, template: "<div class=\"json-viewer-box\">\n <div class=\"toolbar\">\n <button\n *ngIf=\"isRoot\"\n class=\"action-button copy-button\"\n (click)=\"copyJson()\"\n >\n {{ copyLabel }}\n </button>\n <button\n *ngIf=\"isRoot\"\n class=\"action-button toggle-button\"\n (click)=\"toggleAll()\"\n >\n {{ allExpanded ? \"\u25BC \" + hideLabel : \"\u25BA \" + showLabel }}\n </button>\n </div>\n\n <div class=\"json-content\">\n <div *ngIf=\"isObject(jsonData)\">\n <div class=\"json-pair\" *ngFor=\"let key of objectKeys(jsonData)\">\n <span class=\"key\">\n {{ key }}:\n <button class=\"minimal-toggle-button\" (click)=\"toggleExpand(key)\">\n {{ isExpanded(key) ? \"\u25BC\" : \"\u25BA\" }}\n </button>\n </span>\n\n <div class=\"nested-json\" *ngIf=\"isExpanded(key)\">\n <argenta-json-viewer\n [jsonData]=\"jsonData[key]\"\n [isRoot]=\"false\"\n ></argenta-json-viewer>\n </div>\n <span *ngIf=\"!isExpanded(key) && isObject(jsonData[key])\">[...]</span>\n </div>\n </div>\n <span *ngIf=\"!isObject(jsonData)\">\n {{ jsonData }}\n </span>\n </div>\n</div>\n", styles: [".json-viewer-box{border:1px solid #ccc;padding:10px;border-radius:8px;font-family:Arial,sans-serif;background-color:#f9f9f9}.json-viewer-box .toolbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;padding-bottom:5px;border-bottom:1px solid #ddd}.json-viewer-box .action-button{background-color:#4caf50;color:#fff;border:none;padding:8px 16px;font-size:14px;border-radius:4px;cursor:pointer;transition:background-color .3s ease}.json-viewer-box .action-button:hover{background-color:#45a049}.json-viewer-box .minimal-toggle-button{background:none;border:none;color:#007bff;cursor:pointer;font-size:12px;margin-left:5px;padding:0;line-height:1}.json-viewer-box .minimal-toggle-button:hover{color:#0056b3}.json-viewer-box .json-content{margin-top:10px}.json-viewer-box .json-content .json-pair{margin-bottom:5px}.json-viewer-box .json-content .json-pair .key{font-weight:700;margin-right:5px;display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: JsonViewerComponent, selector: "argenta-json-viewer", inputs: ["jsonData", "isRoot", "copyLabel", "showLabel", "hideLabel"] }] }); }
|
2278
|
-
}
|
2279
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: JsonViewerComponent, decorators: [{
|
2280
|
-
type: Component,
|
2281
|
-
args: [{ selector: 'argenta-json-viewer', template: "<div class=\"json-viewer-box\">\n <div class=\"toolbar\">\n <button\n *ngIf=\"isRoot\"\n class=\"action-button copy-button\"\n (click)=\"copyJson()\"\n >\n {{ copyLabel }}\n </button>\n <button\n *ngIf=\"isRoot\"\n class=\"action-button toggle-button\"\n (click)=\"toggleAll()\"\n >\n {{ allExpanded ? \"\u25BC \" + hideLabel : \"\u25BA \" + showLabel }}\n </button>\n </div>\n\n <div class=\"json-content\">\n <div *ngIf=\"isObject(jsonData)\">\n <div class=\"json-pair\" *ngFor=\"let key of objectKeys(jsonData)\">\n <span class=\"key\">\n {{ key }}:\n <button class=\"minimal-toggle-button\" (click)=\"toggleExpand(key)\">\n {{ isExpanded(key) ? \"\u25BC\" : \"\u25BA\" }}\n </button>\n </span>\n\n <div class=\"nested-json\" *ngIf=\"isExpanded(key)\">\n <argenta-json-viewer\n [jsonData]=\"jsonData[key]\"\n [isRoot]=\"false\"\n ></argenta-json-viewer>\n </div>\n <span *ngIf=\"!isExpanded(key) && isObject(jsonData[key])\">[...]</span>\n </div>\n </div>\n <span *ngIf=\"!isObject(jsonData)\">\n {{ jsonData }}\n </span>\n </div>\n</div>\n", styles: [".json-viewer-box{border:1px solid #ccc;padding:10px;border-radius:8px;font-family:Arial,sans-serif;background-color:#f9f9f9}.json-viewer-box .toolbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;padding-bottom:5px;border-bottom:1px solid #ddd}.json-viewer-box .action-button{background-color:#4caf50;color:#fff;border:none;padding:8px 16px;font-size:14px;border-radius:4px;cursor:pointer;transition:background-color .3s ease}.json-viewer-box .action-button:hover{background-color:#45a049}.json-viewer-box .minimal-toggle-button{background:none;border:none;color:#007bff;cursor:pointer;font-size:12px;margin-left:5px;padding:0;line-height:1}.json-viewer-box .minimal-toggle-button:hover{color:#0056b3}.json-viewer-box .json-content{margin-top:10px}.json-viewer-box .json-content .json-pair{margin-bottom:5px}.json-viewer-box .json-content .json-pair .key{font-weight:700;margin-right:5px;display:flex;align-items:center}\n"] }]
|
2282
|
-
}], propDecorators: { jsonData: [{
|
2283
|
-
type: Input
|
2284
|
-
}], isRoot: [{
|
2285
|
-
type: Input
|
2286
|
-
}], copyLabel: [{
|
2287
|
-
type: Input
|
2288
|
-
}], showLabel: [{
|
2289
|
-
type: Input
|
2290
|
-
}], hideLabel: [{
|
2291
|
-
type: Input
|
2292
|
-
}] } });
|
2293
|
-
|
2294
|
-
class ModalComponent {
|
2295
|
-
constructor(activeModal) {
|
2296
|
-
this.activeModal = activeModal;
|
2297
|
-
this.onButtonClick = new EventEmitter(); // Novo evento
|
2298
|
-
}
|
2299
|
-
ngOnInit() {
|
2300
|
-
const componentRef = this.dynamicComponent.createComponent(this.component);
|
2301
|
-
const instance = componentRef.instance;
|
2302
|
-
if (this.componentInputs) {
|
2303
|
-
Object.keys(this.componentInputs).forEach(inputName => {
|
2304
|
-
instance[inputName] = this.componentInputs[inputName];
|
2305
|
-
});
|
2306
|
-
}
|
2307
|
-
}
|
2308
|
-
closeModal() {
|
2309
|
-
this.activeModal.close();
|
2310
|
-
}
|
2311
|
-
buttonClicked() {
|
2312
|
-
this.onButtonClick.emit(); // Emitindo o evento
|
2313
|
-
}
|
2314
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ModalComponent, deps: [{ token: i1$1.NgbActiveModal }], target: i0.ɵɵFactoryTarget.Component }); }
|
2315
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ModalComponent, selector: "argenta-modal", inputs: { title: "title", component: "component", componentInputs: "componentInputs", closeButtonLabel: "closeButtonLabel", buttonLabel: "buttonLabel" }, outputs: { onButtonClick: "onButtonClick" }, viewQueries: [{ propertyName: "dynamicComponent", first: true, predicate: ["dynamicComponent"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div class=\"modal-header custom-modal-header\">\n <h4 class=\"modal-title\">{{ title }}</h4>\n <p class=\"float-right close-modal\" (click)=\"closeModal()\">X</p>\n</div>\n<div class=\"modal-body\">\n <ng-container #dynamicComponent></ng-container>\n</div>\n<div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"closeModal()\">\n {{ closeButtonLabel }}\n </button>\n <button *ngIf=\"buttonLabel\" class=\"btn btn-custom\" (click)=\"buttonClicked()\">\n {{ buttonLabel }}\n </button>\n</div>\n", styles: [".modal-content{border-radius:15px;overflow:hidden}.custom-modal-header{background-color:var(--primary-color);color:var(--text-color);border-bottom:none;font-family:var(--font-family);display:flex;justify-content:space-between;align-items:center;padding:1rem}.modal-title{color:var(--text-color);font-size:20px}.close-modal{margin:0;cursor:pointer;font-size:1.5rem;color:var(--text-color)}.close-modal:hover{color:#ccc}.modal-footer{border-top:none}.btn-custom{background-color:var(--primary-color);color:var(--text-color);border-bottom:none}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
2316
|
-
}
|
2317
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ModalComponent, decorators: [{
|
2318
|
-
type: Component,
|
2319
|
-
args: [{ selector: 'argenta-modal', template: "<div class=\"modal-header custom-modal-header\">\n <h4 class=\"modal-title\">{{ title }}</h4>\n <p class=\"float-right close-modal\" (click)=\"closeModal()\">X</p>\n</div>\n<div class=\"modal-body\">\n <ng-container #dynamicComponent></ng-container>\n</div>\n<div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"closeModal()\">\n {{ closeButtonLabel }}\n </button>\n <button *ngIf=\"buttonLabel\" class=\"btn btn-custom\" (click)=\"buttonClicked()\">\n {{ buttonLabel }}\n </button>\n</div>\n", styles: [".modal-content{border-radius:15px;overflow:hidden}.custom-modal-header{background-color:var(--primary-color);color:var(--text-color);border-bottom:none;font-family:var(--font-family);display:flex;justify-content:space-between;align-items:center;padding:1rem}.modal-title{color:var(--text-color);font-size:20px}.close-modal{margin:0;cursor:pointer;font-size:1.5rem;color:var(--text-color)}.close-modal:hover{color:#ccc}.modal-footer{border-top:none}.btn-custom{background-color:var(--primary-color);color:var(--text-color);border-bottom:none}\n"] }]
|
2320
|
-
}], ctorParameters: function () { return [{ type: i1$1.NgbActiveModal }]; }, propDecorators: { title: [{
|
2321
|
-
type: Input
|
2322
|
-
}], component: [{
|
2323
|
-
type: Input
|
2324
|
-
}], componentInputs: [{
|
2325
|
-
type: Input
|
2326
|
-
}], closeButtonLabel: [{
|
2327
|
-
type: Input
|
2328
|
-
}], buttonLabel: [{
|
2329
|
-
type: Input
|
2330
|
-
}], onButtonClick: [{
|
2331
|
-
type: Output
|
2332
|
-
}], dynamicComponent: [{
|
2333
|
-
type: ViewChild,
|
2334
|
-
args: ['dynamicComponent', { read: ViewContainerRef, static: true }]
|
2335
|
-
}] } });
|
2336
|
-
|
2337
|
-
class MultiSelectComponent {
|
2338
|
-
constructor(authService, http) {
|
2339
|
-
this.authService = authService;
|
2340
|
-
this.http = http;
|
2341
|
-
this.label = 'Multi Select';
|
2342
|
-
this.data = []; // Accepts an array of generic objects
|
2343
|
-
this.placeholder = 'Select items';
|
2344
|
-
this.id = 'multiSelectId';
|
2345
|
-
this.bindLabel = ''; // Generic dynamic label
|
2346
|
-
this.bindValue = ''; // Generic dynamic value
|
2347
|
-
this.closeOnSelect = false; // New property to control dropdown close behavior
|
2348
|
-
this.searchUrl = ''; // URL for backend search
|
2349
|
-
this.multiple = true; // New property to control single or multiple selection
|
2350
|
-
this.searchParams = {}; // Parâmetros de busca dinâmicos
|
2351
|
-
this.keyupEvent = new EventEmitter();
|
2352
|
-
this.backupData = []; // Backup of the initial data
|
2353
|
-
this.allItems = []; // Store the combined list
|
2354
|
-
this.items = of([]); // Initialization of the property
|
2355
|
-
this.filteredItems = of([]); // Filtered items
|
2356
|
-
this.searchTerms = new Subject(); // For search debounce
|
2357
|
-
this.onChangeCallback = () => { };
|
2358
|
-
this.onTouchedCallback = () => { };
|
2359
|
-
this.isCourseEntered = false;
|
2360
|
-
this.compareFn = (item1, item2) => {
|
2361
|
-
return item1 && item2 ? item1[this.bindValue] === item2[this.bindValue] : item1 === item2;
|
2362
|
-
};
|
2363
|
-
}
|
2364
|
-
ngOnInit() {
|
2365
|
-
this.backupData = [...this.data]; // Backup initial data
|
2366
|
-
this.allItems = [...this.data]; // Initialize allItems with the initial data
|
2367
|
-
this.items = of(this.allItems);
|
2368
|
-
this.fetchInitialData().subscribe(data => {
|
2369
|
-
this.updateData(data);
|
2370
|
-
this.filteredItems = this.searchTerms.pipe(debounceTime(700), startWith(''), // Start with an empty search to load the original list
|
2371
|
-
switchMap(term => this.search(term)));
|
2372
|
-
// Adicionar itens selecionados à lista após buscar dados iniciais
|
2373
|
-
this.addSelectedItemsToData();
|
2374
|
-
});
|
2375
|
-
}
|
2376
|
-
ngOnChanges(changes) {
|
2377
|
-
if (changes['selected'] && !changes['selected'].isFirstChange()) {
|
2378
|
-
this.addSelectedItemsToData();
|
2379
|
-
}
|
2380
|
-
}
|
2381
|
-
fetchInitialData() {
|
2382
|
-
return this.http.get(this.searchUrl).pipe(map((response) => {
|
2383
|
-
if (response && response.length > 0) {
|
2384
|
-
return response.map((item) => ({
|
2385
|
-
[this.bindValue]: item[this.bindValue],
|
2386
|
-
[this.bindLabel]: item[this.bindLabel]
|
2387
|
-
}));
|
2388
|
-
}
|
2389
|
-
return [];
|
2390
|
-
}), catchError((error) => {
|
2391
|
-
console.error('Error fetching initial data from backend:', error);
|
2392
|
-
return of([]);
|
2393
|
-
}));
|
2394
|
-
}
|
2395
|
-
updateData(newData) {
|
2396
|
-
newData.forEach((item) => {
|
2397
|
-
const existsInList = this.allItems.some(listItem => this.compareFn(listItem, item));
|
2398
|
-
if (!existsInList) {
|
2399
|
-
this.allItems.push(item);
|
2400
|
-
}
|
2401
|
-
});
|
2402
|
-
this.items = of(this.allItems);
|
2167
|
+
this.filteredItems = of(this.allItems);
|
2403
2168
|
}
|
2404
2169
|
addSelectedItemsToData() {
|
2405
2170
|
if (this.selected) {
|
2406
2171
|
const selectedItems = this.multiple ? this.selected : [this.selected];
|
2407
2172
|
selectedItems.forEach((item) => {
|
2408
|
-
const existsInList = this.allItems.some(listItem => this.compareFn(listItem, item));
|
2173
|
+
const existsInList = this.allItems.some((listItem) => this.compareFn(listItem, item));
|
2409
2174
|
if (!existsInList) {
|
2410
2175
|
const newItem = {
|
2411
2176
|
[this.bindValue]: item[this.bindValue] || item,
|
2412
|
-
[this.bindLabel]: item[this.bindLabel] || item
|
2177
|
+
[this.bindLabel]: item[this.bindLabel] || item,
|
2413
2178
|
};
|
2414
2179
|
this.data.push(newItem);
|
2415
2180
|
this.allItems.push(newItem);
|
@@ -2436,60 +2201,15 @@ class MultiSelectComponent {
|
|
2436
2201
|
this.selected = event ? event : null;
|
2437
2202
|
}
|
2438
2203
|
this.onChangeCallback(this.selected);
|
2439
|
-
|
2440
|
-
|
2441
|
-
|
2442
|
-
|
2443
|
-
|
2444
|
-
|
2445
|
-
this.data.push(item);
|
2446
|
-
this.allItems.push(item); // Adicionar de volta aos itens disponíveis
|
2204
|
+
if (previousSelected && Array.isArray(previousSelected)) {
|
2205
|
+
const removedItems = previousSelected.filter((item) => !event.includes(item));
|
2206
|
+
removedItems.forEach((item) => {
|
2207
|
+
const existsInAllItems = this.allItems.some((listItem) => this.compareFn(listItem, item));
|
2208
|
+
if (!existsInAllItems) {
|
2209
|
+
this.allItems.push(item);
|
2447
2210
|
}
|
2448
2211
|
});
|
2449
|
-
|
2450
|
-
}
|
2451
|
-
onInputChange(event) {
|
2452
|
-
const input = event.target.value;
|
2453
|
-
this.searchTerms.next(input);
|
2454
|
-
}
|
2455
|
-
search(term) {
|
2456
|
-
if (!term.trim()) {
|
2457
|
-
// Se o termo de busca estiver vazio, retorna a lista completa
|
2458
|
-
return of(this.allItems);
|
2459
|
-
}
|
2460
|
-
// Filtra os itens localmente
|
2461
|
-
const filtered = this.allItems.filter((item) => item[this.bindLabel].toLowerCase().includes(term.toLowerCase()));
|
2462
|
-
if (filtered.length > 0) {
|
2463
|
-
console.log('Items filtered locally.');
|
2464
|
-
return of(filtered);
|
2465
|
-
}
|
2466
|
-
else if (this.searchUrl) {
|
2467
|
-
// Construir os parâmetros de busca dinamicamente
|
2468
|
-
const params = new URLSearchParams(this.searchParams);
|
2469
|
-
params.append('term', term);
|
2470
|
-
return this.http.get(`${this.searchUrl}?${params.toString()}`).pipe(map((response) => {
|
2471
|
-
if (response && response.length > 0) {
|
2472
|
-
// Transforma os itens do backend para o formato esperado pelo componente
|
2473
|
-
const transformedItems = response.map((item) => ({
|
2474
|
-
[this.bindValue]: item[this.bindValue],
|
2475
|
-
[this.bindLabel]: item[this.bindLabel]
|
2476
|
-
}));
|
2477
|
-
// Atualiza os dados com os novos itens buscados
|
2478
|
-
this.updateData(transformedItems);
|
2479
|
-
return this.allItems;
|
2480
|
-
}
|
2481
|
-
else {
|
2482
|
-
console.log('No items found in the backend search.');
|
2483
|
-
return this.allItems;
|
2484
|
-
}
|
2485
|
-
}), catchError((error) => {
|
2486
|
-
console.error('Error fetching from backend:', error);
|
2487
|
-
return of(this.allItems);
|
2488
|
-
}));
|
2489
|
-
}
|
2490
|
-
else {
|
2491
|
-
console.log('No search URL provided and no items found locally.');
|
2492
|
-
return of(this.allItems);
|
2212
|
+
this.items = of(this.allItems);
|
2493
2213
|
}
|
2494
2214
|
}
|
2495
2215
|
writeValue(value) {
|
@@ -2507,9 +2227,7 @@ class MultiSelectComponent {
|
|
2507
2227
|
registerOnTouched(fn) {
|
2508
2228
|
this.onTouchedCallback = fn;
|
2509
2229
|
}
|
2510
|
-
setDisabledState(isDisabled) {
|
2511
|
-
// No implementation needed for this example
|
2512
|
-
}
|
2230
|
+
setDisabledState(isDisabled) { }
|
2513
2231
|
hasPermission() {
|
2514
2232
|
if (!this.permissions || this.permissions.length === 0) {
|
2515
2233
|
return true;
|
@@ -2519,33 +2237,88 @@ class MultiSelectComponent {
|
|
2519
2237
|
}
|
2520
2238
|
catch (error) {
|
2521
2239
|
if (error instanceof Error) {
|
2522
|
-
console.error(
|
2240
|
+
console.error("Permission error:", error.message);
|
2523
2241
|
}
|
2524
2242
|
else {
|
2525
|
-
console.error(
|
2243
|
+
console.error("Unknown error occurred during permission check");
|
2526
2244
|
}
|
2527
2245
|
return true;
|
2528
2246
|
}
|
2529
2247
|
}
|
2530
|
-
|
2531
|
-
|
2248
|
+
toggleDropdown() {
|
2249
|
+
this.isOpen = !this.isOpen;
|
2250
|
+
}
|
2251
|
+
closeDropdown() {
|
2252
|
+
this.isOpen = false;
|
2253
|
+
}
|
2254
|
+
isSelected(item) {
|
2255
|
+
if (this.multiple) {
|
2256
|
+
return this.selected?.some((selectedItem) => this.compareFn(selectedItem, item));
|
2257
|
+
}
|
2258
|
+
else {
|
2259
|
+
return this.compareFn(this.selected, item);
|
2260
|
+
}
|
2261
|
+
}
|
2262
|
+
selectItem(item, event) {
|
2263
|
+
event.stopPropagation();
|
2264
|
+
if (!this.isSelected(item)) {
|
2265
|
+
if (this.multiple) {
|
2266
|
+
this.selected.push(item);
|
2267
|
+
}
|
2268
|
+
else {
|
2269
|
+
this.selected = [item];
|
2270
|
+
}
|
2271
|
+
}
|
2272
|
+
if (this.multiple) {
|
2273
|
+
this.allItems = this.allItems.filter((listItem) => !this.compareFn(listItem, item));
|
2274
|
+
}
|
2275
|
+
this.filteredItems = of(this.filterOutSelected(this.allItems));
|
2276
|
+
this.onSelectedChange(this.selected);
|
2277
|
+
if (this.closeOnSelect) {
|
2278
|
+
this.closeDropdown();
|
2279
|
+
}
|
2280
|
+
}
|
2281
|
+
filterByTerm(term) {
|
2282
|
+
return this.allItems.filter((item) => item[this.bindLabel]?.toLowerCase().includes(term.toLowerCase()));
|
2283
|
+
}
|
2284
|
+
filterOutSelected(items) {
|
2285
|
+
if (!this.multiple) {
|
2286
|
+
return items;
|
2287
|
+
}
|
2288
|
+
return items.filter((item) => !this.selected.some((selectedItem) => this.compareFn(selectedItem, item)));
|
2289
|
+
}
|
2290
|
+
removeSelectedItem(item, event) {
|
2291
|
+
event.stopPropagation();
|
2292
|
+
this.selected = this.selected.filter((selectedItem) => !this.compareFn(selectedItem, item));
|
2293
|
+
const existsInAllItems = this.allItems.some((listItem) => this.compareFn(listItem, item));
|
2294
|
+
if (!existsInAllItems) {
|
2295
|
+
this.allItems.push(item);
|
2296
|
+
}
|
2297
|
+
this.filteredItems = of(this.filterByTerm(this.lastSearchTerm || ""));
|
2298
|
+
this.onSelectedChange(this.selected);
|
2299
|
+
}
|
2300
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MultiSelectComponent, deps: [{ token: AuthService }, { token: i1$2.HttpClient }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
2301
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MultiSelectComponent, selector: "argenta-custom-multi-select", inputs: { label: "label", data: "data", placeholder: "placeholder", selected: "selected", id: "id", bindLabel: "bindLabel", bindValue: "bindValue", permissions: "permissions", closeOnSelect: "closeOnSelect", searchUrl: "searchUrl", multiple: "multiple", searchParams: "searchParams" }, outputs: { keyupEvent: "keyupEvent" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
|
2532
2302
|
{
|
2533
2303
|
provide: NG_VALUE_ACCESSOR,
|
2534
2304
|
useExisting: forwardRef(() => MultiSelectComponent),
|
2535
|
-
multi: true
|
2536
|
-
}
|
2537
|
-
], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"hasPermission()\" class=\"form-group\">\n <label [for]=\"id\" class=\"form-label\" style=\"margin-top: 1rem
|
2305
|
+
multi: true,
|
2306
|
+
},
|
2307
|
+
], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"hasPermission()\" class=\"form-group\">\n <label [for]=\"id\" class=\"form-label\" style=\"margin-top: 1rem\">\n {{ label }}\n </label>\n <div class=\"custom-select-container\" tabindex=\"0\">\n <!-- Input com itens selecionados -->\n <div class=\"custom-input\">\n <span class=\"selected-item\" *ngFor=\"let item of selected\">\n {{ item[bindLabel] }}\n <button\n class=\"remove-item-btn\"\n (click)=\"removeSelectedItem(item, $event)\"\n >\n \u00D7\n </button>\n </span>\n <input\n type=\"text\"\n class=\"input-field\"\n [id]=\"id\"\n [placeholder]=\"placeholder\"\n (focus)=\"toggleDropdown()\"\n (keyup)=\"onKeyUp($event)\"\n (input)=\"onInputChange($event)\"\n />\n <!-- \u00CDcone flutuante -->\n <lucide-icon\n [name]=\"isOpen ? 'align-justify' : 'chevron-down'\"\n class=\"dropdown-icon\"\n ></lucide-icon>\n </div>\n\n <!-- Dropdown suspenso -->\n <div *ngIf=\"isOpen\" class=\"dropdown\">\n <div\n *ngFor=\"let item of filteredItems | async\"\n class=\"dropdown-item\"\n [class.selected]=\"isSelected(item)\"\n (click)=\"selectItem(item, $event)\"\n >\n {{ item[bindLabel] }}\n </div>\n <div *ngIf=\"(filteredItems | async)?.length === 0\" class=\"empty-dropdown\">\n Nenhum item dispon\u00EDvel\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.custom-select-container{position:relative;display:flex;flex-direction:column;border:1px solid #ccc;border-radius:4px;padding:.5rem;background-color:#fff;color:#333;font-family:var(--font-family)}.custom-select-container .custom-input{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;width:100%;min-height:20px;cursor:text;background:none;border:none;outline:none;position:relative}.custom-select-container .custom-input .selected-item{display:flex;align-items:center;background-color:#f8f8f8;color:#333;border:1px solid #e0e0e0;border-radius:4px;padding:.15rem .4rem;font-size:.85rem}.custom-select-container .custom-input .selected-item .remove-item-btn{display:flex;align-items:center;justify-content:center;background-color:#c7c7c7;border:none;color:#4b4b4b;font-weight:700;cursor:pointer;font-size:.6rem;line-height:1;border-radius:50%;width:14px;height:14px;margin-left:.3rem;padding:0;position:relative}.custom-select-container .custom-input .selected-item .remove-item-btn span{transition:transform .2s ease,color .2s ease}.custom-select-container .custom-input .selected-item .remove-item-btn:hover{background-color:#8f8a8b;color:#fff}.custom-select-container .custom-input .selected-item .remove-item-btn:hover span{transform:scale(1.2);color:#fff}.custom-select-container .custom-input .selected-item .remove-item-btn:active{background-color:#767072}.custom-select-container .custom-input .input-field{flex:1;border:none;outline:none;font-size:.85rem;padding:.1rem 3rem .1rem .2rem;background:transparent;min-width:80px}.custom-select-container .custom-input .dropdown-icon{position:absolute;right:.1rem;top:50%;transform:translateY(-50%);font-size:1.2rem;color:#888;pointer-events:none}.dropdown{position:absolute;top:100%;left:0;right:0;max-height:200px;overflow-y:auto;background-color:#fff;border:1px solid #ccc;border-radius:4px;z-index:1000}.dropdown::-webkit-scrollbar{width:8px}.dropdown::-webkit-scrollbar-thumb{background-color:#ccc;border-radius:4px}.dropdown::-webkit-scrollbar-thumb:hover{background-color:#aaa}.dropdown::-webkit-scrollbar-track{background-color:#f1f1f1;border-radius:4px}.dropdown .dropdown-item{padding:.5rem;cursor:pointer}.dropdown .dropdown-item:hover{background-color:#f1f1f1}.dropdown .dropdown-item.selected{font-weight:700;background-color:#e9e9e9}.empty-dropdown{padding:1rem;text-align:center;color:#999;font-size:.9rem}@media (max-width: 768px){.custom-input .input-field{padding-right:4rem}.custom-input .dropdown-icon{right:.75rem}}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
2538
2308
|
}
|
2539
2309
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MultiSelectComponent, decorators: [{
|
2540
2310
|
type: Component,
|
2541
|
-
args: [{ selector:
|
2311
|
+
args: [{ selector: "argenta-custom-multi-select", encapsulation: ViewEncapsulation.None, providers: [
|
2542
2312
|
{
|
2543
2313
|
provide: NG_VALUE_ACCESSOR,
|
2544
2314
|
useExisting: forwardRef(() => MultiSelectComponent),
|
2545
|
-
multi: true
|
2546
|
-
}
|
2547
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"hasPermission()\" class=\"form-group\">\n <label [for]=\"id\" class=\"form-label\" style=\"margin-top: 1rem
|
2548
|
-
}], ctorParameters: function () { return [{ type: AuthService }, { type:
|
2315
|
+
multi: true,
|
2316
|
+
},
|
2317
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"hasPermission()\" class=\"form-group\">\n <label [for]=\"id\" class=\"form-label\" style=\"margin-top: 1rem\">\n {{ label }}\n </label>\n <div class=\"custom-select-container\" tabindex=\"0\">\n <!-- Input com itens selecionados -->\n <div class=\"custom-input\">\n <span class=\"selected-item\" *ngFor=\"let item of selected\">\n {{ item[bindLabel] }}\n <button\n class=\"remove-item-btn\"\n (click)=\"removeSelectedItem(item, $event)\"\n >\n \u00D7\n </button>\n </span>\n <input\n type=\"text\"\n class=\"input-field\"\n [id]=\"id\"\n [placeholder]=\"placeholder\"\n (focus)=\"toggleDropdown()\"\n (keyup)=\"onKeyUp($event)\"\n (input)=\"onInputChange($event)\"\n />\n <!-- \u00CDcone flutuante -->\n <lucide-icon\n [name]=\"isOpen ? 'align-justify' : 'chevron-down'\"\n class=\"dropdown-icon\"\n ></lucide-icon>\n </div>\n\n <!-- Dropdown suspenso -->\n <div *ngIf=\"isOpen\" class=\"dropdown\">\n <div\n *ngFor=\"let item of filteredItems | async\"\n class=\"dropdown-item\"\n [class.selected]=\"isSelected(item)\"\n (click)=\"selectItem(item, $event)\"\n >\n {{ item[bindLabel] }}\n </div>\n <div *ngIf=\"(filteredItems | async)?.length === 0\" class=\"empty-dropdown\">\n Nenhum item dispon\u00EDvel\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.custom-select-container{position:relative;display:flex;flex-direction:column;border:1px solid #ccc;border-radius:4px;padding:.5rem;background-color:#fff;color:#333;font-family:var(--font-family)}.custom-select-container .custom-input{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;width:100%;min-height:20px;cursor:text;background:none;border:none;outline:none;position:relative}.custom-select-container .custom-input .selected-item{display:flex;align-items:center;background-color:#f8f8f8;color:#333;border:1px solid #e0e0e0;border-radius:4px;padding:.15rem .4rem;font-size:.85rem}.custom-select-container .custom-input .selected-item .remove-item-btn{display:flex;align-items:center;justify-content:center;background-color:#c7c7c7;border:none;color:#4b4b4b;font-weight:700;cursor:pointer;font-size:.6rem;line-height:1;border-radius:50%;width:14px;height:14px;margin-left:.3rem;padding:0;position:relative}.custom-select-container .custom-input .selected-item .remove-item-btn span{transition:transform .2s ease,color .2s ease}.custom-select-container .custom-input .selected-item .remove-item-btn:hover{background-color:#8f8a8b;color:#fff}.custom-select-container .custom-input .selected-item .remove-item-btn:hover span{transform:scale(1.2);color:#fff}.custom-select-container .custom-input .selected-item .remove-item-btn:active{background-color:#767072}.custom-select-container .custom-input .input-field{flex:1;border:none;outline:none;font-size:.85rem;padding:.1rem 3rem .1rem .2rem;background:transparent;min-width:80px}.custom-select-container .custom-input .dropdown-icon{position:absolute;right:.1rem;top:50%;transform:translateY(-50%);font-size:1.2rem;color:#888;pointer-events:none}.dropdown{position:absolute;top:100%;left:0;right:0;max-height:200px;overflow-y:auto;background-color:#fff;border:1px solid #ccc;border-radius:4px;z-index:1000}.dropdown::-webkit-scrollbar{width:8px}.dropdown::-webkit-scrollbar-thumb{background-color:#ccc;border-radius:4px}.dropdown::-webkit-scrollbar-thumb:hover{background-color:#aaa}.dropdown::-webkit-scrollbar-track{background-color:#f1f1f1;border-radius:4px}.dropdown .dropdown-item{padding:.5rem;cursor:pointer}.dropdown .dropdown-item:hover{background-color:#f1f1f1}.dropdown .dropdown-item.selected{font-weight:700;background-color:#e9e9e9}.empty-dropdown{padding:1rem;text-align:center;color:#999;font-size:.9rem}@media (max-width: 768px){.custom-input .input-field{padding-right:4rem}.custom-input .dropdown-icon{right:.75rem}}\n"] }]
|
2318
|
+
}], ctorParameters: function () { return [{ type: AuthService }, { type: i1$2.HttpClient }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { onClickOutside: [{
|
2319
|
+
type: HostListener,
|
2320
|
+
args: ["document:click", ["$event"]]
|
2321
|
+
}], label: [{
|
2549
2322
|
type: Input
|
2550
2323
|
}], data: [{
|
2551
2324
|
type: Input
|
@@ -2703,7 +2476,7 @@ class SearchCustomerComponent {
|
|
2703
2476
|
this.searchTerm.emit(inputElement.value);
|
2704
2477
|
}
|
2705
2478
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SearchCustomerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
2706
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SearchCustomerComponent, selector: "argenta-search-customer", inputs: { placeholder: "placeholder", id: "id", disabled: "disabled", readonly: "readonly", autofocus: "autofocus" }, outputs: { searchTerm: "searchTerm" }, ngImport: i0, template: "<div class=\"search-container\">\n <span class=\"search-icon\" [ngClass]=\"'search-icon-green'\">\n <lucide-icon name=\"search\" [size]=\"16\"></lucide-icon>\n </span>\n <input\n [id]=\"id\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [autofocus]=\"autofocus\"\n (input)=\"onSearch($event)\"\n class=\"search-input custom-input\"\n />\n</div>\n", styles: [".search-container{display:flex;align-items:center;border:1px solid var(--primary-color);border-radius:8px;padding:5px;background-color:#f7f9fc}.search-icon{padding:0 10px;color:#b0b0b0}.search-input{border:none;outline:none;padding:8px;flex:1;background-color:transparent;font-family:var(--font-family);color:#333;font-size:.9rem;height:35px}.search-input::placeholder{color:#b0b0b0}.search-icon-green{color:var(--primary-color)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type:
|
2479
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SearchCustomerComponent, selector: "argenta-search-customer", inputs: { placeholder: "placeholder", id: "id", disabled: "disabled", readonly: "readonly", autofocus: "autofocus" }, outputs: { searchTerm: "searchTerm" }, ngImport: i0, template: "<div class=\"search-container\">\n <span class=\"search-icon\" [ngClass]=\"'search-icon-green'\">\n <lucide-icon name=\"search\" [size]=\"16\"></lucide-icon>\n </span>\n <input\n [id]=\"id\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [autofocus]=\"autofocus\"\n (input)=\"onSearch($event)\"\n class=\"search-input custom-input\"\n />\n</div>\n", styles: [".search-container{display:flex;align-items:center;border:1px solid var(--primary-color);border-radius:8px;padding:5px;background-color:#f7f9fc}.search-icon{padding:0 10px;color:#b0b0b0}.search-input{border:none;outline:none;padding:8px;flex:1;background-color:transparent;font-family:var(--font-family);color:#333;font-size:.9rem;height:35px}.search-input::placeholder{color:#b0b0b0}.search-icon-green{color:var(--primary-color)}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] }); }
|
2707
2480
|
}
|
2708
2481
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SearchCustomerComponent, decorators: [{
|
2709
2482
|
type: Component,
|
@@ -2947,7 +2720,7 @@ class SelectComponent {
|
|
2947
2720
|
<lucide-icon name="chevron-down" [size]="16" color="#5E6366" [strokeWidth]="1.75"></lucide-icon>
|
2948
2721
|
</div>
|
2949
2722
|
</div>
|
2950
|
-
`, isInline: true, styles: ["@charset \"UTF-8\";.form-group{font-family:var(--font-family);font-size:1rem;font-weight:700}.form-check-input{font-family:var(--font-family);color:#333;font-size:.9rem}.form-check-label{width:623px;height:19px;top:1608px;left:133px;gap:0px;opacity:0px;font-family:var(--font-family);font-size:16px;line-height:19.36px;text-align:left}.custom-select{font-family:var(--font-family);color:#333;font-size:1rem;font-weight:400;border:1px solid #ccc;border-radius:4px;padding:.5rem 2rem .5rem .5rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:none;background-repeat:no-repeat;background-position:right .5rem center}.custom-input{font-family:var(--font-family);color:#333;font-size:1rem;font-weight:400;border:1px solid #ccc;border-radius:4px;padding:.5rem}.form-label{font-family:var(--font-family);color:#333;font-size:1rem;font-weight:700}.label-styles{font-weight:400;font-family:var(--font-family);font-size:16px;line-height:19.36px;text-align:left;margin-top:1rem;margin-bottom:.5rem}.select-container{position:relative;display:inline-block;width:100%}.select-container lucide-icon{position:absolute;right:.75rem;top:50%;transform:translateY(-50%);pointer-events:none;color:#5e6366}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type:
|
2723
|
+
`, isInline: true, styles: ["@charset \"UTF-8\";.form-group{font-family:var(--font-family);font-size:1rem;font-weight:700}.form-check-input{font-family:var(--font-family);color:#333;font-size:.9rem}.form-check-label{width:623px;height:19px;top:1608px;left:133px;gap:0px;opacity:0px;font-family:var(--font-family);font-size:16px;line-height:19.36px;text-align:left}.custom-select{font-family:var(--font-family);color:#333;font-size:1rem;font-weight:400;border:1px solid #ccc;border-radius:4px;padding:.5rem 2rem .5rem .5rem;appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:none;background-repeat:no-repeat;background-position:right .5rem center}.custom-input{font-family:var(--font-family);color:#333;font-size:1rem;font-weight:400;border:1px solid #ccc;border-radius:4px;padding:.5rem}.form-label{font-family:var(--font-family);color:#333;font-size:1rem;font-weight:700}.label-styles{font-weight:400;font-family:var(--font-family);font-size:16px;line-height:19.36px;text-align:left;margin-top:1rem;margin-bottom:.5rem}.select-container{position:relative;display:inline-block;width:100%}.select-container lucide-icon{position:absolute;right:.75rem;top:50%;transform:translateY(-50%);pointer-events:none;color:#5e6366}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
2951
2724
|
}
|
2952
2725
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectComponent, decorators: [{
|
2953
2726
|
type: Component,
|
@@ -3287,7 +3060,7 @@ class DataTableComponent {
|
|
3287
3060
|
this.onButtonClick.emit(); // Emitindo o evento
|
3288
3061
|
}
|
3289
3062
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataTableComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: AuthService }, { token: RefreshService }], target: i0.ɵɵFactoryTarget.Component }); }
|
3290
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataTableComponent, selector: "argenta-list-data-table", inputs: { columns: "columns", hiddenColumns: "hiddenColumns", defaultItemsPerPage: "defaultItemsPerPage", itemsPerPageLabel: "itemsPerPageLabel", showActionColumn: "showActionColumn", actionColumnLabel: "actionColumnLabel", totalItems: "totalItems", fetchDataFunction: "fetchDataFunction", editPermissions: "editPermissions", deletePermissions: "deletePermissions", viewPermissions: "viewPermissions", showPageInfo: "showPageInfo", pageText: "pageText", ofText: "ofText", filterDescription: "filterDescription", buttonLabel: "buttonLabel", pagedData: "pagedData", initialFilterField: "initialFilterField", buttonList: "buttonList" }, outputs: { sortChange: "sortChange", pageChange: "pageChange", itemsPerPageChange: "itemsPerPageChange", onEditTable: "onEditTable", onDeleteTable: "onDeleteTable", onViewTable: "onViewTable", onButtonClick: "onButtonClick", filterFieldChange: "filterFieldChange" }, ngImport: i0, template: "<div class=\"data-table-header\" style=\"margin-top: 2.5rem\">\n <div class=\"left-section\">\n <div class=\"form-group\">\n <label for=\"itemsPerPageSelect\" class=\"items-per-page-label\">{{\n itemsPerPageLabel\n }}</label>\n <select\n id=\"itemsPerPageSelect\"\n class=\"form-control form-control-sm d-inline-block w-auto custom-select\"\n [(ngModel)]=\"defaultItemsPerPage\"\n (ngModelChange)=\"onItemsPerPageChange()\"\n >\n <option *ngFor=\"let option of itemsPerPageOptions\" [value]=\"option\">\n {{ option }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"right-section\">\n <div *ngIf=\"buttonList && buttonList.length > 0\" class=\"ng-button-row\">\n <ng-container *ngFor=\"let buttonTemplate of buttonList\">\n <ng-container\n *ngTemplateOutlet=\"buttonTemplate\"\n class=\"ng-button\"\n ></ng-container>\n </ng-container>\n </div>\n <button\n *ngIf=\"buttonLabel && buttonLabel.length > 0\"\n class=\"custom-button\"\n (click)=\"onNewButtonClick()\"\n >\n <lucide-icon name=\"plus\" [size]=\"28\" [strokeWidth]=\"1.75\"></lucide-icon>\n {{ buttonLabel }}\n </button>\n </div>\n</div>\n\n<div class=\"search-input-container\">\n <argenta-search-input\n id=\"search\"\n label=\"\"\n placeholder=\"Buscar\"\n [(ngModel)]=\"filterDescription\"\n (search)=\"onSearch($event)\"\n ></argenta-search-input>\n</div>\n\n<div class=\"table-responsive\" style=\"margin-top: 1rem\">\n <table class=\"table table-hover\">\n <thead>\n <tr>\n <ng-container *ngFor=\"let column of columns\">\n <th\n *ngIf=\"!isColumnHidden(column.prop)\"\n (click)=\"onSelectSearchField(column.prop)\"\n >\n {{ column.label }}\n <span>\n <i-lucide\n name=\"arrow-up\"\n [size]=\"14\"\n [class.selected]=\"\n column.isSearchSelected && sortDirection === 'asc'\n \"\n ></i-lucide>\n <i-lucide\n name=\"arrow-down\"\n [size]=\"14\"\n [class.selected]=\"\n column.isSearchSelected && sortDirection === 'desc'\n \"\n ></i-lucide>\n </span>\n </th>\n </ng-container>\n <th\n *ngIf=\"showActionColumn\"\n class=\"text-end\"\n style=\"padding-right: 6.3rem\"\n >\n {{ actionColumnLabel }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of pagedData; let i = index\">\n <ng-container *ngFor=\"let column of columns\">\n <td *ngIf=\"!isColumnHidden(column.prop)\">\n {{ getNestedProperty(item, column.prop) }}\n </td>\n </ng-container>\n <td *ngIf=\"showActionColumn\" class=\"text-end\">\n <div class=\"d-flex justify-content-end\">\n <div\n *ngIf=\"\n hasPermission(editPermissions) &&\n onEditTable.observers.length > 0\n \"\n (click)=\"handleAction('edit', item, i)\"\n class=\"clickable-icon\"\n style=\"margin-right: 1.5rem\"\n >\n <lucide-icon\n name=\"square-pen\"\n [size]=\"20\"\n color=\"#2CA58D\"\n [strokeWidth]=\"1.75\"\n ></lucide-icon>\n </div>\n <div\n *ngIf=\"\n hasPermission(viewPermissions) &&\n onViewTable.observers.length > 0\n \"\n (click)=\"handleAction('view', item, i)\"\n class=\"clickable-icon\"\n style=\"margin-right: 1.5rem\"\n >\n <lucide-icon\n name=\"user-round\"\n [size]=\"20\"\n color=\"#2CA58D\"\n [strokeWidth]=\"1.75\"\n ></lucide-icon>\n </div>\n <div\n *ngIf=\"\n hasPermission(deletePermissions) &&\n onDeleteTable.observers.length > 0\n \"\n (click)=\"handleAction('delete', item, i)\"\n class=\"clickable-icon\"\n style=\"margin-right: 1.5rem\"\n >\n <i-lucide\n name=\"trash-2\"\n [size]=\"20\"\n color=\"#F26E6E\"\n [strokeWidth]=\"1.75\"\n ></i-lucide>\n </div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n</div>\n\n<div class=\"text-center pagination-controls\">\n <custom-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"defaultItemsPerPage\"\n [currentPage]=\"currentPage\"\n [showPageInfo]=\"showPageInfo\"\n (pageChange)=\"onPageChange($event)\"\n >\n </custom-pagination>\n</div>\n", styles: ["@charset \"UTF-8\";.clickable-icon{cursor:pointer}:host{font-family:var(--font-family)}.data-table-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:-.2rem}.left-section,.right-section{display:flex;align-items:center}.search-input-container{display:flex;justify-content:flex-start}.left-section .form-group{display:flex;align-items:center}.items-per-page-label{font-family:var(--font-family);font-size:14px;color:#666;margin-right:.2rem}.custom-select{font-family:var(--font-family);font-size:14px;color:#666;background:#fff url('data:image/svg+xml;charset=US-ASCII,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 4 5\"><path fill=\"#666\" d=\"M2 0L0 2h4L2 0zM2 5l2-2H0l2 2z\"/></svg>') no-repeat right .75rem center/8px 10px;border:1px solid #ccc;border-radius:.25rem;padding:.375rem 1.75rem .375rem .75rem;appearance:none;-webkit-appearance:none;-moz-appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem #007bff40}.table{font-family:var(--font-family);font-size:var(--table-font-size, 14px);color:var(--table-font-color, #737b7b);border-collapse:separate;border-spacing:0;border-radius:8px;overflow:hidden}.table thead tr{height:60px}.table thead th{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);font-size:14px;font-weight:600;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center;line-height:2.5}.table thead th:first-child{text-align:left;padding-left:1.4rem}.table tbody td{font-family:var(--font-family);font-size:14px;color:#737b7b;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center}.table tbody td:first-child{text-align:left;padding-left:1.4rem}.table tbody tr:last-child td{border-bottom:.1rem solid #dcdcdc}.table tbody td{border-right:none;border-left:none}.table thead th:first-child{border-top-left-radius:0}.table thead th:last-child{border-top-right-radius:0}.table tbody tr:last-child td:first-child{border-bottom-left-radius:0}.table tbody tr:last-child td:last-child{border-bottom-right-radius:0}.btn-icon{width:24px;height:24px;background-size:cover;display:inline-block;cursor:pointer;margin-right:16px}.pagination-controls{display:flex;justify-content:center;align-items:center;margin-top:1rem}.custom-button{display:flex;align-items:center;padding:.5rem 1rem .5rem .5rem;border-radius:.25rem;transition:background-color .3s,border-color .3s,filter .3s;font-family:var(--font-family);font-size:16px;font-weight:600;height:40px;letter-spacing:.005em;text-align:left;color:#fff;background-color:var(--secondary-color);border:none;cursor:pointer}.custom-button lucide-icon{margin-right:.5rem}.custom-button:hover{box-shadow:0 0 0 .15rem var(--secondary-color)}.custom-button:active{background-color:var(--secondary-color)}.custom-button:focus{outline:none;box-shadow:0 0 0 .15rem var(--secondary-color)}.selected{color:var(--secondary-color);stroke-width:8}.ng-button-row{display:flex;gap:10px;margin-right:10px;margin-left:10px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: CustomPaginationComponent, selector: "custom-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "showPageInfo"], outputs: ["pageChange"] }, { kind: "component", type: SearchInputComponent, selector: "argenta-search-input", inputs: ["id", "label", "type", "placeholder", "value", "disabled", "readonly", "autofocus", "maxlength", "minlength", "required", "pattern", "debounceTime"], outputs: ["search", "inputChange", "change", "focus", "blur", "keyup", "keydown", "keypress"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3063
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataTableComponent, selector: "argenta-list-data-table", inputs: { columns: "columns", hiddenColumns: "hiddenColumns", defaultItemsPerPage: "defaultItemsPerPage", itemsPerPageLabel: "itemsPerPageLabel", showActionColumn: "showActionColumn", actionColumnLabel: "actionColumnLabel", totalItems: "totalItems", fetchDataFunction: "fetchDataFunction", editPermissions: "editPermissions", deletePermissions: "deletePermissions", viewPermissions: "viewPermissions", showPageInfo: "showPageInfo", pageText: "pageText", ofText: "ofText", filterDescription: "filterDescription", buttonLabel: "buttonLabel", pagedData: "pagedData", initialFilterField: "initialFilterField", buttonList: "buttonList" }, outputs: { sortChange: "sortChange", pageChange: "pageChange", itemsPerPageChange: "itemsPerPageChange", onEditTable: "onEditTable", onDeleteTable: "onDeleteTable", onViewTable: "onViewTable", onButtonClick: "onButtonClick", filterFieldChange: "filterFieldChange" }, ngImport: i0, template: "<div class=\"data-table-header\" style=\"margin-top: 2.5rem\">\n <div class=\"left-section\">\n <div class=\"form-group\">\n <label for=\"itemsPerPageSelect\" class=\"items-per-page-label\">{{\n itemsPerPageLabel\n }}</label>\n <select\n id=\"itemsPerPageSelect\"\n class=\"form-control form-control-sm d-inline-block w-auto custom-select\"\n [(ngModel)]=\"defaultItemsPerPage\"\n (ngModelChange)=\"onItemsPerPageChange()\"\n >\n <option *ngFor=\"let option of itemsPerPageOptions\" [value]=\"option\">\n {{ option }}\n </option>\n </select>\n </div>\n </div>\n <div class=\"right-section\">\n <div *ngIf=\"buttonList && buttonList.length > 0\" class=\"ng-button-row\">\n <ng-container *ngFor=\"let buttonTemplate of buttonList\">\n <ng-container\n *ngTemplateOutlet=\"buttonTemplate\"\n class=\"ng-button\"\n ></ng-container>\n </ng-container>\n </div>\n <button\n *ngIf=\"buttonLabel && buttonLabel.length > 0\"\n class=\"custom-button\"\n (click)=\"onNewButtonClick()\"\n >\n <lucide-icon name=\"plus\" [size]=\"28\" [strokeWidth]=\"1.75\"></lucide-icon>\n {{ buttonLabel }}\n </button>\n </div>\n</div>\n\n<div class=\"search-input-container\">\n <argenta-search-input\n id=\"search\"\n label=\"\"\n placeholder=\"Buscar\"\n [(ngModel)]=\"filterDescription\"\n (search)=\"onSearch($event)\"\n ></argenta-search-input>\n</div>\n\n<div class=\"table-responsive\" style=\"margin-top: 1rem\">\n <table class=\"table table-hover\">\n <thead>\n <tr>\n <ng-container *ngFor=\"let column of columns\">\n <th\n *ngIf=\"!isColumnHidden(column.prop)\"\n (click)=\"onSelectSearchField(column.prop)\"\n >\n {{ column.label }}\n <span>\n <i-lucide\n name=\"arrow-up\"\n [size]=\"14\"\n [class.selected]=\"\n column.isSearchSelected && sortDirection === 'asc'\n \"\n ></i-lucide>\n <i-lucide\n name=\"arrow-down\"\n [size]=\"14\"\n [class.selected]=\"\n column.isSearchSelected && sortDirection === 'desc'\n \"\n ></i-lucide>\n </span>\n </th>\n </ng-container>\n <th\n *ngIf=\"showActionColumn\"\n class=\"text-end\"\n style=\"padding-right: 6.3rem\"\n >\n {{ actionColumnLabel }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of pagedData; let i = index\">\n <ng-container *ngFor=\"let column of columns\">\n <td *ngIf=\"!isColumnHidden(column.prop)\">\n {{ getNestedProperty(item, column.prop) }}\n </td>\n </ng-container>\n <td *ngIf=\"showActionColumn\" class=\"text-end\">\n <div class=\"d-flex justify-content-end\">\n <div\n *ngIf=\"\n hasPermission(editPermissions) &&\n onEditTable.observers.length > 0\n \"\n (click)=\"handleAction('edit', item, i)\"\n class=\"clickable-icon\"\n style=\"margin-right: 1.5rem\"\n >\n <lucide-icon\n name=\"square-pen\"\n [size]=\"20\"\n color=\"#2CA58D\"\n [strokeWidth]=\"1.75\"\n ></lucide-icon>\n </div>\n <div\n *ngIf=\"\n hasPermission(viewPermissions) &&\n onViewTable.observers.length > 0\n \"\n (click)=\"handleAction('view', item, i)\"\n class=\"clickable-icon\"\n style=\"margin-right: 1.5rem\"\n >\n <lucide-icon\n name=\"user-round\"\n [size]=\"20\"\n color=\"#2CA58D\"\n [strokeWidth]=\"1.75\"\n ></lucide-icon>\n </div>\n <div\n *ngIf=\"\n hasPermission(deletePermissions) &&\n onDeleteTable.observers.length > 0\n \"\n (click)=\"handleAction('delete', item, i)\"\n class=\"clickable-icon\"\n style=\"margin-right: 1.5rem\"\n >\n <i-lucide\n name=\"trash-2\"\n [size]=\"20\"\n color=\"#F26E6E\"\n [strokeWidth]=\"1.75\"\n ></i-lucide>\n </div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n</div>\n\n<div class=\"text-center pagination-controls\">\n <custom-pagination\n [totalItems]=\"totalItems\"\n [itemsPerPage]=\"defaultItemsPerPage\"\n [currentPage]=\"currentPage\"\n [showPageInfo]=\"showPageInfo\"\n (pageChange)=\"onPageChange($event)\"\n >\n </custom-pagination>\n</div>\n", styles: ["@charset \"UTF-8\";.clickable-icon{cursor:pointer}:host{font-family:var(--font-family)}.data-table-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:-.2rem}.left-section,.right-section{display:flex;align-items:center}.search-input-container{display:flex;justify-content:flex-start}.left-section .form-group{display:flex;align-items:center}.items-per-page-label{font-family:var(--font-family);font-size:14px;color:#666;margin-right:.2rem}.custom-select{font-family:var(--font-family);font-size:14px;color:#666;background:#fff url('data:image/svg+xml;charset=US-ASCII,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 4 5\"><path fill=\"#666\" d=\"M2 0L0 2h4L2 0zM2 5l2-2H0l2 2z\"/></svg>') no-repeat right .75rem center/8px 10px;border:1px solid #ccc;border-radius:.25rem;padding:.375rem 1.75rem .375rem .75rem;appearance:none;-webkit-appearance:none;-moz-appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem #007bff40}.table{font-family:var(--font-family);font-size:var(--table-font-size, 14px);color:var(--table-font-color, #737b7b);border-collapse:separate;border-spacing:0;border-radius:8px;overflow:hidden}.table thead tr{height:60px}.table thead th{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);font-size:14px;font-weight:600;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center;line-height:2.5}.table thead th:first-child{text-align:left;padding-left:1.4rem}.table tbody td{font-family:var(--font-family);font-size:14px;color:#737b7b;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center}.table tbody td:first-child{text-align:left;padding-left:1.4rem}.table tbody tr:last-child td{border-bottom:.1rem solid #dcdcdc}.table tbody td{border-right:none;border-left:none}.table thead th:first-child{border-top-left-radius:0}.table thead th:last-child{border-top-right-radius:0}.table tbody tr:last-child td:first-child{border-bottom-left-radius:0}.table tbody tr:last-child td:last-child{border-bottom-right-radius:0}.btn-icon{width:24px;height:24px;background-size:cover;display:inline-block;cursor:pointer;margin-right:16px}.pagination-controls{display:flex;justify-content:center;align-items:center;margin-top:1rem}.custom-button{display:flex;align-items:center;padding:.5rem 1rem .5rem .5rem;border-radius:.25rem;transition:background-color .3s,border-color .3s,filter .3s;font-family:var(--font-family);font-size:16px;font-weight:600;height:40px;letter-spacing:.005em;text-align:left;color:#fff;background-color:var(--secondary-color);border:none;cursor:pointer}.custom-button lucide-icon{margin-right:.5rem}.custom-button:hover{box-shadow:0 0 0 .15rem var(--secondary-color)}.custom-button:active{background-color:var(--secondary-color)}.custom-button:focus{outline:none;box-shadow:0 0 0 .15rem var(--secondary-color)}.selected{color:var(--secondary-color);stroke-width:8}.ng-button-row{display:flex;gap:10px;margin-right:10px;margin-left:10px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: CustomPaginationComponent, selector: "custom-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "showPageInfo"], outputs: ["pageChange"] }, { kind: "component", type: SearchInputComponent, selector: "argenta-search-input", inputs: ["id", "label", "type", "placeholder", "value", "disabled", "readonly", "autofocus", "maxlength", "minlength", "required", "pattern", "debounceTime"], outputs: ["search", "inputChange", "change", "focus", "blur", "keyup", "keydown", "keypress"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3291
3064
|
}
|
3292
3065
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataTableComponent, decorators: [{
|
3293
3066
|
type: Component,
|
@@ -3591,10 +3364,888 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
3591
3364
|
type: Output
|
3592
3365
|
}] } });
|
3593
3366
|
|
3367
|
+
class JsonViewerComponent {
|
3368
|
+
constructor() {
|
3369
|
+
this.isRoot = true;
|
3370
|
+
this.allExpanded = true;
|
3371
|
+
this.expandedMap = new Map();
|
3372
|
+
}
|
3373
|
+
toggleAll() {
|
3374
|
+
this.allExpanded = !this.allExpanded;
|
3375
|
+
this.expandedMap.clear();
|
3376
|
+
}
|
3377
|
+
toggleExpand(key) {
|
3378
|
+
const currentState = this.isExpanded(key);
|
3379
|
+
this.expandedMap.set(key, !currentState);
|
3380
|
+
}
|
3381
|
+
isObject(val) {
|
3382
|
+
return val !== null && typeof val === 'object';
|
3383
|
+
}
|
3384
|
+
objectKeys(obj) {
|
3385
|
+
return Object.keys(obj);
|
3386
|
+
}
|
3387
|
+
isExpanded(key) {
|
3388
|
+
return this.expandedMap.has(key) ? this.expandedMap.get(key) : this.allExpanded;
|
3389
|
+
}
|
3390
|
+
copyJson() {
|
3391
|
+
const jsonString = JSON.stringify(this.jsonData, null, 2);
|
3392
|
+
navigator.clipboard.writeText(jsonString).then(() => {
|
3393
|
+
alert('JSON copiado com sucesso!');
|
3394
|
+
}).catch(err => {
|
3395
|
+
console.error('Error copying JSON to clipboard:', err);
|
3396
|
+
});
|
3397
|
+
}
|
3398
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: JsonViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3399
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: JsonViewerComponent, selector: "argenta-json-viewer", inputs: { jsonData: "jsonData", isRoot: "isRoot", copyLabel: "copyLabel", showLabel: "showLabel", hideLabel: "hideLabel" }, ngImport: i0, template: "<div class=\"json-viewer-box\">\n <div class=\"toolbar\">\n <button\n *ngIf=\"isRoot\"\n class=\"action-button copy-button\"\n (click)=\"copyJson()\"\n >\n {{ copyLabel }}\n </button>\n <button\n *ngIf=\"isRoot\"\n class=\"action-button toggle-button\"\n (click)=\"toggleAll()\"\n >\n {{ allExpanded ? \"\u25BC \" + hideLabel : \"\u25BA \" + showLabel }}\n </button>\n </div>\n\n <div class=\"json-content\">\n <div *ngIf=\"isObject(jsonData)\">\n <div class=\"json-pair\" *ngFor=\"let key of objectKeys(jsonData)\">\n <span class=\"key\">\n {{ key }}:\n <button class=\"minimal-toggle-button\" (click)=\"toggleExpand(key)\">\n {{ isExpanded(key) ? \"\u25BC\" : \"\u25BA\" }}\n </button>\n </span>\n\n <div class=\"nested-json\" *ngIf=\"isExpanded(key)\">\n <argenta-json-viewer\n [jsonData]=\"jsonData[key]\"\n [isRoot]=\"false\"\n ></argenta-json-viewer>\n </div>\n <span *ngIf=\"!isExpanded(key) && isObject(jsonData[key])\">[...]</span>\n </div>\n </div>\n <span *ngIf=\"!isObject(jsonData)\">\n {{ jsonData }}\n </span>\n </div>\n</div>\n", styles: [".json-viewer-box{border:1px solid #ccc;padding:10px;border-radius:8px;font-family:Arial,sans-serif;background-color:#f9f9f9}.json-viewer-box .toolbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;padding-bottom:5px;border-bottom:1px solid #ddd}.json-viewer-box .action-button{background-color:#4caf50;color:#fff;border:none;padding:8px 16px;font-size:14px;border-radius:4px;cursor:pointer;transition:background-color .3s ease}.json-viewer-box .action-button:hover{background-color:#45a049}.json-viewer-box .minimal-toggle-button{background:none;border:none;color:#007bff;cursor:pointer;font-size:12px;margin-left:5px;padding:0;line-height:1}.json-viewer-box .minimal-toggle-button:hover{color:#0056b3}.json-viewer-box .json-content{margin-top:10px}.json-viewer-box .json-content .json-pair{margin-bottom:5px}.json-viewer-box .json-content .json-pair .key{font-weight:700;margin-right:5px;display:flex;align-items:center}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: JsonViewerComponent, selector: "argenta-json-viewer", inputs: ["jsonData", "isRoot", "copyLabel", "showLabel", "hideLabel"] }] }); }
|
3400
|
+
}
|
3401
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: JsonViewerComponent, decorators: [{
|
3402
|
+
type: Component,
|
3403
|
+
args: [{ selector: 'argenta-json-viewer', template: "<div class=\"json-viewer-box\">\n <div class=\"toolbar\">\n <button\n *ngIf=\"isRoot\"\n class=\"action-button copy-button\"\n (click)=\"copyJson()\"\n >\n {{ copyLabel }}\n </button>\n <button\n *ngIf=\"isRoot\"\n class=\"action-button toggle-button\"\n (click)=\"toggleAll()\"\n >\n {{ allExpanded ? \"\u25BC \" + hideLabel : \"\u25BA \" + showLabel }}\n </button>\n </div>\n\n <div class=\"json-content\">\n <div *ngIf=\"isObject(jsonData)\">\n <div class=\"json-pair\" *ngFor=\"let key of objectKeys(jsonData)\">\n <span class=\"key\">\n {{ key }}:\n <button class=\"minimal-toggle-button\" (click)=\"toggleExpand(key)\">\n {{ isExpanded(key) ? \"\u25BC\" : \"\u25BA\" }}\n </button>\n </span>\n\n <div class=\"nested-json\" *ngIf=\"isExpanded(key)\">\n <argenta-json-viewer\n [jsonData]=\"jsonData[key]\"\n [isRoot]=\"false\"\n ></argenta-json-viewer>\n </div>\n <span *ngIf=\"!isExpanded(key) && isObject(jsonData[key])\">[...]</span>\n </div>\n </div>\n <span *ngIf=\"!isObject(jsonData)\">\n {{ jsonData }}\n </span>\n </div>\n</div>\n", styles: [".json-viewer-box{border:1px solid #ccc;padding:10px;border-radius:8px;font-family:Arial,sans-serif;background-color:#f9f9f9}.json-viewer-box .toolbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;padding-bottom:5px;border-bottom:1px solid #ddd}.json-viewer-box .action-button{background-color:#4caf50;color:#fff;border:none;padding:8px 16px;font-size:14px;border-radius:4px;cursor:pointer;transition:background-color .3s ease}.json-viewer-box .action-button:hover{background-color:#45a049}.json-viewer-box .minimal-toggle-button{background:none;border:none;color:#007bff;cursor:pointer;font-size:12px;margin-left:5px;padding:0;line-height:1}.json-viewer-box .minimal-toggle-button:hover{color:#0056b3}.json-viewer-box .json-content{margin-top:10px}.json-viewer-box .json-content .json-pair{margin-bottom:5px}.json-viewer-box .json-content .json-pair .key{font-weight:700;margin-right:5px;display:flex;align-items:center}\n"] }]
|
3404
|
+
}], propDecorators: { jsonData: [{
|
3405
|
+
type: Input
|
3406
|
+
}], isRoot: [{
|
3407
|
+
type: Input
|
3408
|
+
}], copyLabel: [{
|
3409
|
+
type: Input
|
3410
|
+
}], showLabel: [{
|
3411
|
+
type: Input
|
3412
|
+
}], hideLabel: [{
|
3413
|
+
type: Input
|
3414
|
+
}] } });
|
3415
|
+
|
3416
|
+
class ModalComponent {
|
3417
|
+
constructor(activeModal) {
|
3418
|
+
this.activeModal = activeModal;
|
3419
|
+
this.onButtonClick = new EventEmitter(); // Novo evento
|
3420
|
+
}
|
3421
|
+
ngOnInit() {
|
3422
|
+
const componentRef = this.dynamicComponent.createComponent(this.component);
|
3423
|
+
const instance = componentRef.instance;
|
3424
|
+
if (this.componentInputs) {
|
3425
|
+
Object.keys(this.componentInputs).forEach(inputName => {
|
3426
|
+
instance[inputName] = this.componentInputs[inputName];
|
3427
|
+
});
|
3428
|
+
}
|
3429
|
+
}
|
3430
|
+
closeModal() {
|
3431
|
+
this.activeModal.close();
|
3432
|
+
}
|
3433
|
+
buttonClicked() {
|
3434
|
+
this.onButtonClick.emit(); // Emitindo o evento
|
3435
|
+
}
|
3436
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ModalComponent, deps: [{ token: i1$1.NgbActiveModal }], target: i0.ɵɵFactoryTarget.Component }); }
|
3437
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ModalComponent, selector: "argenta-modal", inputs: { title: "title", component: "component", componentInputs: "componentInputs", closeButtonLabel: "closeButtonLabel", buttonLabel: "buttonLabel" }, outputs: { onButtonClick: "onButtonClick" }, viewQueries: [{ propertyName: "dynamicComponent", first: true, predicate: ["dynamicComponent"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div class=\"modal-header custom-modal-header\">\n <h4 class=\"modal-title\">{{ title }}</h4>\n <p class=\"float-right close-modal\" (click)=\"closeModal()\">X</p>\n</div>\n<div class=\"modal-body\">\n <ng-container #dynamicComponent></ng-container>\n</div>\n<div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"closeModal()\">\n {{ closeButtonLabel }}\n </button>\n <button *ngIf=\"buttonLabel\" class=\"btn btn-custom\" (click)=\"buttonClicked()\">\n {{ buttonLabel }}\n </button>\n</div>\n", styles: [".modal-content{border-radius:15px;overflow:hidden}.custom-modal-header{background-color:var(--primary-color);color:var(--text-color);border-bottom:none;font-family:var(--font-family);display:flex;justify-content:space-between;align-items:center;padding:1rem}.modal-title{color:var(--text-color);font-size:20px}.close-modal{margin:0;cursor:pointer;font-size:1.5rem;color:var(--text-color)}.close-modal:hover{color:#ccc}.modal-footer{border-top:none}.btn-custom{background-color:var(--primary-color);color:var(--text-color);border-bottom:none}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
3438
|
+
}
|
3439
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ModalComponent, decorators: [{
|
3440
|
+
type: Component,
|
3441
|
+
args: [{ selector: 'argenta-modal', template: "<div class=\"modal-header custom-modal-header\">\n <h4 class=\"modal-title\">{{ title }}</h4>\n <p class=\"float-right close-modal\" (click)=\"closeModal()\">X</p>\n</div>\n<div class=\"modal-body\">\n <ng-container #dynamicComponent></ng-container>\n</div>\n<div class=\"modal-footer\">\n <button class=\"btn btn-secondary\" (click)=\"closeModal()\">\n {{ closeButtonLabel }}\n </button>\n <button *ngIf=\"buttonLabel\" class=\"btn btn-custom\" (click)=\"buttonClicked()\">\n {{ buttonLabel }}\n </button>\n</div>\n", styles: [".modal-content{border-radius:15px;overflow:hidden}.custom-modal-header{background-color:var(--primary-color);color:var(--text-color);border-bottom:none;font-family:var(--font-family);display:flex;justify-content:space-between;align-items:center;padding:1rem}.modal-title{color:var(--text-color);font-size:20px}.close-modal{margin:0;cursor:pointer;font-size:1.5rem;color:var(--text-color)}.close-modal:hover{color:#ccc}.modal-footer{border-top:none}.btn-custom{background-color:var(--primary-color);color:var(--text-color);border-bottom:none}\n"] }]
|
3442
|
+
}], ctorParameters: function () { return [{ type: i1$1.NgbActiveModal }]; }, propDecorators: { title: [{
|
3443
|
+
type: Input
|
3444
|
+
}], component: [{
|
3445
|
+
type: Input
|
3446
|
+
}], componentInputs: [{
|
3447
|
+
type: Input
|
3448
|
+
}], closeButtonLabel: [{
|
3449
|
+
type: Input
|
3450
|
+
}], buttonLabel: [{
|
3451
|
+
type: Input
|
3452
|
+
}], onButtonClick: [{
|
3453
|
+
type: Output
|
3454
|
+
}], dynamicComponent: [{
|
3455
|
+
type: ViewChild,
|
3456
|
+
args: ['dynamicComponent', { read: ViewContainerRef, static: true }]
|
3457
|
+
}] } });
|
3458
|
+
|
3459
|
+
class DynamicModalComponent {
|
3460
|
+
constructor() {
|
3461
|
+
this.modalTitle = "Modal Title";
|
3462
|
+
this.modalSizeClass = "";
|
3463
|
+
this.modalId = "dynamicModal"; // ID único para cada modal
|
3464
|
+
}
|
3465
|
+
openModal() {
|
3466
|
+
const modalElement = document.getElementById(this.modalId);
|
3467
|
+
if (modalElement) {
|
3468
|
+
modalElement.classList.add("show");
|
3469
|
+
modalElement.setAttribute("aria-hidden", "false");
|
3470
|
+
modalElement.style.display = "block";
|
3471
|
+
document.body.classList.add("modal-open");
|
3472
|
+
// Adiciona o backdrop manualmente se não existir
|
3473
|
+
if (!document.querySelector(`.modal-backdrop[data-modal-id="${this.modalId}"]`)) {
|
3474
|
+
const backdrop = document.createElement("div");
|
3475
|
+
backdrop.className = "modal-backdrop fade show";
|
3476
|
+
backdrop.setAttribute("data-modal-id", this.modalId);
|
3477
|
+
document.body.appendChild(backdrop);
|
3478
|
+
}
|
3479
|
+
}
|
3480
|
+
}
|
3481
|
+
closeModal() {
|
3482
|
+
const modalElement = document.getElementById(this.modalId);
|
3483
|
+
if (modalElement) {
|
3484
|
+
modalElement.classList.remove("show");
|
3485
|
+
modalElement.setAttribute("aria-hidden", "true");
|
3486
|
+
modalElement.style.display = "none";
|
3487
|
+
document.body.classList.remove("modal-open");
|
3488
|
+
document
|
3489
|
+
.querySelector(`.modal-backdrop[data-modal-id="${this.modalId}"]`)
|
3490
|
+
?.remove();
|
3491
|
+
}
|
3492
|
+
}
|
3493
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3494
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicModalComponent, selector: "argenta-dynamic-modal", inputs: { modalTitle: "modalTitle", modalSizeClass: "modalSizeClass", modalId: "modalId" }, ngImport: i0, template: "<div\n class=\"modal fade\"\n [id]=\"modalId\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"modalId + 'Label'\"\n aria-hidden=\"true\"\n>\n <div class=\"modal-dialog\" [ngClass]=\"modalSizeClass\">\n <div class=\"modal-content\">\n <div class=\"modal-header custom-header\">\n <h5 class=\"modal-title custom-modal-title\" [id]=\"modalId + 'Label'\">\n {{ modalTitle }}\n </h5>\n <button\n type=\"button\"\n class=\"custom-close-button\"\n (click)=\"closeModal()\"\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n <div class=\"modal-body custom-body\">\n <ng-content select=\"[modal-body]\"></ng-content>\n </div>\n <div class=\"modal-footer custom-footer\">\n <ng-content select=\"[modal-footer]\"></ng-content>\n </div>\n </div>\n </div>\n</div>\n", styles: [".custom-header{background-color:var(--primary-color)!important;color:var(--text-color)!important;font-size:1.25rem!important;font-family:var(--font-family)!important;padding:1rem;position:relative}.custom-header .custom-close-button{position:absolute;right:1rem;background:none;border:none;font-size:2.5rem;color:var(--text-color);cursor:pointer}.custom-header .custom-close-button:hover{color:var(--danger-color)}.custom-modal-title{color:var(--text-color)!important;font-size:1.8rem!important;font-family:var(--font-family)!important}.custom-body{background-color:#fff;padding:1rem}.custom-footer{background-color:#fff;padding:.75rem;display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
3495
|
+
}
|
3496
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicModalComponent, decorators: [{
|
3497
|
+
type: Component,
|
3498
|
+
args: [{ selector: "argenta-dynamic-modal", template: "<div\n class=\"modal fade\"\n [id]=\"modalId\"\n tabindex=\"-1\"\n [attr.aria-labelledby]=\"modalId + 'Label'\"\n aria-hidden=\"true\"\n>\n <div class=\"modal-dialog\" [ngClass]=\"modalSizeClass\">\n <div class=\"modal-content\">\n <div class=\"modal-header custom-header\">\n <h5 class=\"modal-title custom-modal-title\" [id]=\"modalId + 'Label'\">\n {{ modalTitle }}\n </h5>\n <button\n type=\"button\"\n class=\"custom-close-button\"\n (click)=\"closeModal()\"\n aria-label=\"Close\"\n >\n ×\n </button>\n </div>\n <div class=\"modal-body custom-body\">\n <ng-content select=\"[modal-body]\"></ng-content>\n </div>\n <div class=\"modal-footer custom-footer\">\n <ng-content select=\"[modal-footer]\"></ng-content>\n </div>\n </div>\n </div>\n</div>\n", styles: [".custom-header{background-color:var(--primary-color)!important;color:var(--text-color)!important;font-size:1.25rem!important;font-family:var(--font-family)!important;padding:1rem;position:relative}.custom-header .custom-close-button{position:absolute;right:1rem;background:none;border:none;font-size:2.5rem;color:var(--text-color);cursor:pointer}.custom-header .custom-close-button:hover{color:var(--danger-color)}.custom-modal-title{color:var(--text-color)!important;font-size:1.8rem!important;font-family:var(--font-family)!important}.custom-body{background-color:#fff;padding:1rem}.custom-footer{background-color:#fff;padding:.75rem;display:flex;justify-content:flex-end;gap:.5rem}\n"] }]
|
3499
|
+
}], propDecorators: { modalTitle: [{
|
3500
|
+
type: Input
|
3501
|
+
}], modalSizeClass: [{
|
3502
|
+
type: Input
|
3503
|
+
}], modalId: [{
|
3504
|
+
type: Input
|
3505
|
+
}] } });
|
3506
|
+
|
3507
|
+
class DynamicTableComponent {
|
3508
|
+
constructor() {
|
3509
|
+
this.itemsPerPageOptions = [10, 20, 50];
|
3510
|
+
this.showPageInfo = true;
|
3511
|
+
this.currentPage = 1;
|
3512
|
+
this.itemsPerPage = 10;
|
3513
|
+
}
|
3514
|
+
get totalItems() {
|
3515
|
+
return this.config.totalItems ?? this.config.data.length;
|
3516
|
+
}
|
3517
|
+
get paginatedData() {
|
3518
|
+
if (!this.config.pagination) {
|
3519
|
+
// Retorna todos os dados se a paginação estiver desativada
|
3520
|
+
return this.config.data;
|
3521
|
+
}
|
3522
|
+
const itemsPerPage = this.config.itemsPerPage || this.itemsPerPage;
|
3523
|
+
const startIndex = (this.currentPage - 1) * itemsPerPage;
|
3524
|
+
return this.config.data.slice(startIndex, startIndex + itemsPerPage);
|
3525
|
+
}
|
3526
|
+
ngOnInit() {
|
3527
|
+
if (!this.config || !this.config.columns || !this.config.data) {
|
3528
|
+
throw new Error("DynamicTableComponent: Configuração inválida.");
|
3529
|
+
}
|
3530
|
+
// Define valores padrão se não especificados
|
3531
|
+
this.config.showHeader = this.config.showHeader ?? true; // Exibe o cabeçalho por padrão
|
3532
|
+
this.config.pagination = this.config.pagination ?? true; // Ativa paginação por padrão
|
3533
|
+
this.itemsPerPage = this.config.itemsPerPage || 10;
|
3534
|
+
}
|
3535
|
+
onPageChange(newPage) {
|
3536
|
+
this.currentPage = newPage;
|
3537
|
+
}
|
3538
|
+
onItemsPerPageChange(event) {
|
3539
|
+
const target = event.target;
|
3540
|
+
this.itemsPerPage = +target.value;
|
3541
|
+
this.currentPage = 1; // Reinicia a paginação ao alterar os itens por página
|
3542
|
+
}
|
3543
|
+
// Getter para garantir que totalItems nunca seja undefined
|
3544
|
+
get safeTotalItems() {
|
3545
|
+
return this.totalItems || 0;
|
3546
|
+
}
|
3547
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3548
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DynamicTableComponent, selector: "argenta-dynamic-table", inputs: { config: "config", itemsPerPageOptions: "itemsPerPageOptions", showPageInfo: "showPageInfo" }, ngImport: i0, template: "<table class=\"table\" [ngClass]=\"{ nested: config.isNested }\">\n <thead *ngIf=\"config.showHeader\">\n <tr>\n <th *ngFor=\"let column of config.columns\">{{ column.header }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of paginatedData\">\n <td *ngFor=\"let column of config.columns\">\n <ng-container [ngSwitch]=\"column.type\">\n <span *ngSwitchCase=\"'text'\">{{ row[column.key] }}</span>\n <ng-container *ngSwitchCase=\"'template'\">\n <ng-container\n *ngTemplateOutlet=\"\n column.template || null;\n context: { $implicit: row }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </td>\n </tr>\n </tbody>\n</table>\n\n<div\n class=\"text-center pagination-controls\"\n [ngClass]=\"{ nested: config.isNested }\"\n *ngIf=\"config.pagination\"\n>\n <custom-pagination\n [totalItems]=\"safeTotalItems\"\n [itemsPerPage]=\"itemsPerPage\"\n [currentPage]=\"currentPage\"\n [showPageInfo]=\"showPageInfo\"\n (pageChange)=\"onPageChange($event)\"\n >\n </custom-pagination>\n</div>\n", styles: ["@charset \"UTF-8\";.table{width:100%;border-collapse:collapse;border-spacing:0}.table{width:100%;border-collapse:separate;border-spacing:0;overflow:hidden}.table thead th{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);font-size:14px;font-weight:600;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center;line-height:2.5}.table thead th:first-child{border-top-left-radius:10px}.table thead th:last-child{border-top-right-radius:10px}.table.nested thead th{font-size:.7rem;padding:7px;line-height:.8}.table tbody td{font-family:var(--font-family);font-size:14px;color:#737b7b;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center}.table tbody td:first-child{text-align:left;padding-left:1.4rem}.table.nested tbody td:first-child{padding-left:1rem}.table tbody tr:hover{background-color:#f5f5f5!important;transition:background-color .3s ease}.table.nested tbody tr:hover{background-color:#f0f0f0!important}.pagination-controls{display:flex;justify-content:center;align-items:center;margin-top:1rem}.pagination-controls.nested{font-size:.7rem;transform:scale(.7);margin-top:.5rem}.data-table-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.left-section{display:flex;align-items:center}.items-per-page-label{font-family:var(--font-family);font-size:14px;color:#666;margin-right:.5rem}.custom-select{font-family:var(--font-family);font-size:14px;padding:.375rem 1.75rem .375rem .75rem;border:1px solid #ccc;border-radius:.25rem;appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 4 5\"><path fill=\"#666\" d=\"M2 0L0 2h4L2 0zM2 5l2-2H0l2 2z\"/></svg>') no-repeat right .75rem center/8px 10px}.custom-select:focus{border-color:#80bdff;outline:none;box-shadow:0 0 0 .2rem #007bff40}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: CustomPaginationComponent, selector: "custom-pagination", inputs: ["totalItems", "itemsPerPage", "currentPage", "showPageInfo"], outputs: ["pageChange"] }] }); }
|
3549
|
+
}
|
3550
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DynamicTableComponent, decorators: [{
|
3551
|
+
type: Component,
|
3552
|
+
args: [{ selector: "argenta-dynamic-table", template: "<table class=\"table\" [ngClass]=\"{ nested: config.isNested }\">\n <thead *ngIf=\"config.showHeader\">\n <tr>\n <th *ngFor=\"let column of config.columns\">{{ column.header }}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of paginatedData\">\n <td *ngFor=\"let column of config.columns\">\n <ng-container [ngSwitch]=\"column.type\">\n <span *ngSwitchCase=\"'text'\">{{ row[column.key] }}</span>\n <ng-container *ngSwitchCase=\"'template'\">\n <ng-container\n *ngTemplateOutlet=\"\n column.template || null;\n context: { $implicit: row }\n \"\n ></ng-container>\n </ng-container>\n </ng-container>\n </td>\n </tr>\n </tbody>\n</table>\n\n<div\n class=\"text-center pagination-controls\"\n [ngClass]=\"{ nested: config.isNested }\"\n *ngIf=\"config.pagination\"\n>\n <custom-pagination\n [totalItems]=\"safeTotalItems\"\n [itemsPerPage]=\"itemsPerPage\"\n [currentPage]=\"currentPage\"\n [showPageInfo]=\"showPageInfo\"\n (pageChange)=\"onPageChange($event)\"\n >\n </custom-pagination>\n</div>\n", styles: ["@charset \"UTF-8\";.table{width:100%;border-collapse:collapse;border-spacing:0}.table{width:100%;border-collapse:separate;border-spacing:0;overflow:hidden}.table thead th{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);font-size:14px;font-weight:600;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center;line-height:2.5}.table thead th:first-child{border-top-left-radius:10px}.table thead th:last-child{border-top-right-radius:10px}.table.nested thead th{font-size:.7rem;padding:7px;line-height:.8}.table tbody td{font-family:var(--font-family);font-size:14px;color:#737b7b;padding:10px;border-bottom:.1rem solid #dcdcdc;text-align:center}.table tbody td:first-child{text-align:left;padding-left:1.4rem}.table.nested tbody td:first-child{padding-left:1rem}.table tbody tr:hover{background-color:#f5f5f5!important;transition:background-color .3s ease}.table.nested tbody tr:hover{background-color:#f0f0f0!important}.pagination-controls{display:flex;justify-content:center;align-items:center;margin-top:1rem}.pagination-controls.nested{font-size:.7rem;transform:scale(.7);margin-top:.5rem}.data-table-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem}.left-section{display:flex;align-items:center}.items-per-page-label{font-family:var(--font-family);font-size:14px;color:#666;margin-right:.5rem}.custom-select{font-family:var(--font-family);font-size:14px;padding:.375rem 1.75rem .375rem .75rem;border:1px solid #ccc;border-radius:.25rem;appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 4 5\"><path fill=\"#666\" d=\"M2 0L0 2h4L2 0zM2 5l2-2H0l2 2z\"/></svg>') no-repeat right .75rem center/8px 10px}.custom-select:focus{border-color:#80bdff;outline:none;box-shadow:0 0 0 .2rem #007bff40}\n"] }]
|
3553
|
+
}], ctorParameters: function () { return []; }, propDecorators: { config: [{
|
3554
|
+
type: Input
|
3555
|
+
}], itemsPerPageOptions: [{
|
3556
|
+
type: Input
|
3557
|
+
}], showPageInfo: [{
|
3558
|
+
type: Input
|
3559
|
+
}] } });
|
3560
|
+
|
3561
|
+
function formatToBrazilianNumber(value) {
|
3562
|
+
return value.toLocaleString("pt-BR", {
|
3563
|
+
minimumFractionDigits: 2,
|
3564
|
+
maximumFractionDigits: 2,
|
3565
|
+
});
|
3566
|
+
}
|
3567
|
+
|
3568
|
+
class ArgentaPdfDataHandlerComponent {
|
3569
|
+
constructor() {
|
3570
|
+
this.data = [];
|
3571
|
+
}
|
3572
|
+
isNumericColumn(key) {
|
3573
|
+
// Se 'numericColumns' estiver definido no pdfConfig, use-o como referência
|
3574
|
+
return this.config?.numericColumns?.includes(key) ?? false;
|
3575
|
+
}
|
3576
|
+
processData(data) {
|
3577
|
+
if (!data || !this.config?.tableKeys?.length) {
|
3578
|
+
console.warn("Dados ou chaves de tabela ausentes!");
|
3579
|
+
return [];
|
3580
|
+
}
|
3581
|
+
// Identificar colunas numéricas
|
3582
|
+
const numericColumns = this.config.numericColumns || [];
|
3583
|
+
return data.map((item) => {
|
3584
|
+
const processedItem = {};
|
3585
|
+
this.config.tableKeys.forEach((key) => {
|
3586
|
+
if (numericColumns.includes(key)) {
|
3587
|
+
const value = item[key];
|
3588
|
+
if (typeof value === "string") {
|
3589
|
+
// Converte o valor no formato brasileiro para número
|
3590
|
+
processedItem[key] = parseFloat(value.replace(".", "").replace(",", "."));
|
3591
|
+
}
|
3592
|
+
else if (typeof value === "number") {
|
3593
|
+
processedItem[key] = value;
|
3594
|
+
}
|
3595
|
+
else {
|
3596
|
+
processedItem[key] = 0; // Valor padrão para entradas inválidas
|
3597
|
+
}
|
3598
|
+
}
|
3599
|
+
else {
|
3600
|
+
// Mantém o valor original para colunas não numéricas
|
3601
|
+
processedItem[key] = item[key];
|
3602
|
+
}
|
3603
|
+
});
|
3604
|
+
return processedItem;
|
3605
|
+
});
|
3606
|
+
}
|
3607
|
+
exportToPdf() {
|
3608
|
+
if (!this.config || !this.data.length) {
|
3609
|
+
console.warn("Configuração ou dados ausentes para exportação de PDF!");
|
3610
|
+
return;
|
3611
|
+
}
|
3612
|
+
const doc = new jsPDF();
|
3613
|
+
// Configuração do título
|
3614
|
+
const titleStyle = this.styles?.titleStyle || {};
|
3615
|
+
doc.setFont(titleStyle.fontFamily || "helvetica", "normal");
|
3616
|
+
doc.setFontSize(titleStyle.fontSize || 14);
|
3617
|
+
doc.setTextColor(titleStyle.fontColor || "#000");
|
3618
|
+
doc.text(this.config.pdfTitle || "Relatório", titleStyle.align === "center" ? 105 : 10, 10, { align: titleStyle.align || "left" });
|
3619
|
+
// Processar os dados
|
3620
|
+
const processedData = this.processData(this.data);
|
3621
|
+
// Calcular totais por linha
|
3622
|
+
const calculatedData = processedData.map((row) => {
|
3623
|
+
const newRow = { ...row };
|
3624
|
+
this.config.rowCalculations?.forEach((calc) => {
|
3625
|
+
const result = calc.formula(row);
|
3626
|
+
newRow[calc.label] = isNaN(result)
|
3627
|
+
? "-"
|
3628
|
+
: formatToBrazilianNumber(result); // Formata os totais por linha
|
3629
|
+
});
|
3630
|
+
return newRow;
|
3631
|
+
});
|
3632
|
+
// Calcular o total geral
|
3633
|
+
let totalRow = {};
|
3634
|
+
if (this.config.totalizer?.include) {
|
3635
|
+
this.config.totalizer.columns.forEach((column) => {
|
3636
|
+
const values = calculatedData
|
3637
|
+
.map((item) => {
|
3638
|
+
const value = item[column.field];
|
3639
|
+
if (typeof value === "string") {
|
3640
|
+
return parseFloat(value.replace(".", "").replace(",", "."));
|
3641
|
+
}
|
3642
|
+
return typeof value === "number" ? value : 0; // Valores inválidos tratados como 0
|
3643
|
+
})
|
3644
|
+
.filter((value) => !isNaN(value)); // Filtra valores válidos
|
3645
|
+
const total = column.formula(values);
|
3646
|
+
totalRow[column.field] = formatToBrazilianNumber(total); // Formata o total geral
|
3647
|
+
});
|
3648
|
+
}
|
3649
|
+
// Preparar os dados para a tabela
|
3650
|
+
const tableHeaders = [...this.config.tableHeaders];
|
3651
|
+
const tableKeys = [...this.config.tableKeys];
|
3652
|
+
const tableData = calculatedData.map((item) => tableKeys.map((key) => {
|
3653
|
+
const value = item[key];
|
3654
|
+
if (typeof value === "number") {
|
3655
|
+
return formatToBrazilianNumber(value); // Formata números
|
3656
|
+
}
|
3657
|
+
return value || "-"; // Retorna o valor original
|
3658
|
+
}));
|
3659
|
+
// Adicionar a linha totalizadora ao final da tabela
|
3660
|
+
if (this.config.totalizer?.include) {
|
3661
|
+
const totalizerRow = tableKeys.map((key, index) => {
|
3662
|
+
if (index === 0) {
|
3663
|
+
return this.config.totalizer?.columns[0].label || "-"; // Adiciona o label na primeira coluna
|
3664
|
+
}
|
3665
|
+
return totalRow[key] || "-";
|
3666
|
+
});
|
3667
|
+
tableData.push(totalizerRow);
|
3668
|
+
}
|
3669
|
+
// Configurar estilos e gerar a tabela
|
3670
|
+
const tableStyle = this.styles?.tableStyle || {};
|
3671
|
+
const headerStyle = this.styles?.headerStyle || {};
|
3672
|
+
const dataStyle = this.styles?.dataStyle || {};
|
3673
|
+
doc.autoTable({
|
3674
|
+
head: [tableHeaders],
|
3675
|
+
body: tableData,
|
3676
|
+
startY: 20,
|
3677
|
+
headStyles: {
|
3678
|
+
fontSize: headerStyle.fontSize || 12,
|
3679
|
+
textColor: headerStyle.fontColor || "#fff",
|
3680
|
+
fillColor: headerStyle.backgroundColor || "#007bff",
|
3681
|
+
},
|
3682
|
+
bodyStyles: {
|
3683
|
+
fontSize: dataStyle.fontSize || 10,
|
3684
|
+
textColor: dataStyle.fontColor || "#555",
|
3685
|
+
},
|
3686
|
+
styles: {
|
3687
|
+
fontSize: tableStyle.fontSize || 10,
|
3688
|
+
textColor: tableStyle.fontColor || "#000",
|
3689
|
+
fillColor: tableStyle.backgroundColor || "#fff",
|
3690
|
+
},
|
3691
|
+
theme: "grid",
|
3692
|
+
});
|
3693
|
+
// Salvar o PDF
|
3694
|
+
doc.save(this.config.fileName || "relatorio.pdf");
|
3695
|
+
}
|
3696
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ArgentaPdfDataHandlerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3697
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ArgentaPdfDataHandlerComponent, selector: "argenta-pdf-data-handler", inputs: { config: "config", data: "data", styles: "styles" }, ngImport: i0, template: "<div class=\"pdf-data-handler-container\">\n <button class=\"pdf-button\" (click)=\"exportToPdf()\">\n {{ config.buttonLabel || \"Export PDF\" }}\n </button>\n</div>\n", styles: [".pdf-data-handler-container{display:flex;justify-content:center;align-items:center;padding:1rem}.pdf-data-handler-container .pdf-button{font-family:var(--font-family, Arial, sans-serif);font-size:16px;font-weight:600;padding:.5rem 1rem;border-radius:.25rem;color:var(--text-color, #fff);background-color:var(--primary-color);border:none;cursor:pointer;transition:background-color .3s,box-shadow .3s}.pdf-data-handler-container .pdf-button:hover{background-color:var(--secondary-color)}.pdf-data-handler-container .pdf-button:active{transform:scale(.98)}\n"] }); }
|
3698
|
+
}
|
3699
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ArgentaPdfDataHandlerComponent, decorators: [{
|
3700
|
+
type: Component,
|
3701
|
+
args: [{ selector: "argenta-pdf-data-handler", template: "<div class=\"pdf-data-handler-container\">\n <button class=\"pdf-button\" (click)=\"exportToPdf()\">\n {{ config.buttonLabel || \"Export PDF\" }}\n </button>\n</div>\n", styles: [".pdf-data-handler-container{display:flex;justify-content:center;align-items:center;padding:1rem}.pdf-data-handler-container .pdf-button{font-family:var(--font-family, Arial, sans-serif);font-size:16px;font-weight:600;padding:.5rem 1rem;border-radius:.25rem;color:var(--text-color, #fff);background-color:var(--primary-color);border:none;cursor:pointer;transition:background-color .3s,box-shadow .3s}.pdf-data-handler-container .pdf-button:hover{background-color:var(--secondary-color)}.pdf-data-handler-container .pdf-button:active{transform:scale(.98)}\n"] }]
|
3702
|
+
}], propDecorators: { config: [{
|
3703
|
+
type: Input
|
3704
|
+
}], data: [{
|
3705
|
+
type: Input
|
3706
|
+
}], styles: [{
|
3707
|
+
type: Input
|
3708
|
+
}] } });
|
3709
|
+
|
3710
|
+
class ArgentaPdfDownloadComponent {
|
3711
|
+
constructor(http) {
|
3712
|
+
this.http = http;
|
3713
|
+
this.apiEndpoint = ""; // Endpoint do back-end ou URL pública
|
3714
|
+
this.buttonText = "Baixar PDF"; // Texto do botão
|
3715
|
+
this.loadingText = "Baixando..."; // Texto durante o carregamento
|
3716
|
+
this.isLoading = false;
|
3717
|
+
}
|
3718
|
+
downloadPdf() {
|
3719
|
+
if (!this.apiEndpoint) {
|
3720
|
+
console.error("O endpoint da API não foi fornecido.");
|
3721
|
+
return;
|
3722
|
+
}
|
3723
|
+
// Verifica se a URL é pública (HTTPS ou HTTP)
|
3724
|
+
if (this.apiEndpoint.startsWith("http://") ||
|
3725
|
+
this.apiEndpoint.startsWith("https://")) {
|
3726
|
+
window.open(this.apiEndpoint, "_blank"); // Abre a URL diretamente
|
3727
|
+
return;
|
3728
|
+
}
|
3729
|
+
this.isLoading = true;
|
3730
|
+
// Requisição para obter o arquivo como blob
|
3731
|
+
this.http.get(this.apiEndpoint, { responseType: "blob" }).subscribe({
|
3732
|
+
next: (blob) => {
|
3733
|
+
const fileURL = window.URL.createObjectURL(blob);
|
3734
|
+
window.open(fileURL, "_blank"); // Abre o arquivo como blob
|
3735
|
+
this.isLoading = false;
|
3736
|
+
},
|
3737
|
+
error: (err) => {
|
3738
|
+
console.error("Erro ao baixar o PDF:", err);
|
3739
|
+
this.isLoading = false;
|
3740
|
+
},
|
3741
|
+
});
|
3742
|
+
}
|
3743
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ArgentaPdfDownloadComponent, deps: [{ token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
|
3744
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ArgentaPdfDownloadComponent, selector: "argenta-pdf-download", inputs: { apiEndpoint: "apiEndpoint", buttonText: "buttonText", loadingText: "loadingText" }, ngImport: i0, template: "<button (click)=\"downloadPdf()\" [disabled]=\"isLoading\">\n <span *ngIf=\"!isLoading\">{{ buttonText }}</span>\n <span *ngIf=\"isLoading\">{{ loadingText }}</span>\n</button>\n", styles: ["button{font-family:var(--font-family);font-size:16px;font-weight:600;padding:.5rem 1rem;border-radius:.25rem;color:var(--text-color);background-color:var(--primary-color);border:none;cursor:pointer;transition:background-color .3s ease-in-out,box-shadow .3s ease-in-out,transform .2s ease;box-shadow:0 4px 6px #0000001a}button:hover{background-color:var(--secondary-color);box-shadow:0 6px 8px #00000026}button:active{transform:scale(.96);box-shadow:0 2px 4px #0000001a}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
|
3745
|
+
}
|
3746
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ArgentaPdfDownloadComponent, decorators: [{
|
3747
|
+
type: Component,
|
3748
|
+
args: [{ selector: "argenta-pdf-download", template: "<button (click)=\"downloadPdf()\" [disabled]=\"isLoading\">\n <span *ngIf=\"!isLoading\">{{ buttonText }}</span>\n <span *ngIf=\"isLoading\">{{ loadingText }}</span>\n</button>\n", styles: ["button{font-family:var(--font-family);font-size:16px;font-weight:600;padding:.5rem 1rem;border-radius:.25rem;color:var(--text-color);background-color:var(--primary-color);border:none;cursor:pointer;transition:background-color .3s ease-in-out,box-shadow .3s ease-in-out,transform .2s ease;box-shadow:0 4px 6px #0000001a}button:hover{background-color:var(--secondary-color);box-shadow:0 6px 8px #00000026}button:active{transform:scale(.96);box-shadow:0 2px 4px #0000001a}\n"] }]
|
3749
|
+
}], ctorParameters: function () { return [{ type: i1$2.HttpClient }]; }, propDecorators: { apiEndpoint: [{
|
3750
|
+
type: Input
|
3751
|
+
}], buttonText: [{
|
3752
|
+
type: Input
|
3753
|
+
}], loadingText: [{
|
3754
|
+
type: Input
|
3755
|
+
}] } });
|
3756
|
+
|
3757
|
+
class DragDropListComponent {
|
3758
|
+
constructor() {
|
3759
|
+
this.nonSelectedList = [];
|
3760
|
+
this.nonSelectedButtonClick = new EventEmitter();
|
3761
|
+
this.nonSelectedInputChanged = new EventEmitter();
|
3762
|
+
this.selectedList = [];
|
3763
|
+
this.selectedButtonClick = new EventEmitter();
|
3764
|
+
this.selectedInputChanged = new EventEmitter();
|
3765
|
+
this.nonSelectedListInputSubject = new Subject();
|
3766
|
+
this.selectedListInputSubject = new Subject();
|
3767
|
+
this.ButtonClasses = ButtonClasses; // Adicione a enumeração ao componente
|
3768
|
+
this.draggedItem = null;
|
3769
|
+
this.nonSelectedListInputSubject.pipe(debounceTime(2000)).subscribe((value) => {
|
3770
|
+
this.nonSelectedInputChanged.emit(value);
|
3771
|
+
});
|
3772
|
+
this.selectedListInputSubject.pipe(debounceTime(2000)).subscribe((value) => {
|
3773
|
+
this.selectedInputChanged.emit(value);
|
3774
|
+
});
|
3775
|
+
}
|
3776
|
+
onDragStart(item) {
|
3777
|
+
this.draggedItem = item;
|
3778
|
+
}
|
3779
|
+
onDragOver(event) {
|
3780
|
+
event.preventDefault();
|
3781
|
+
}
|
3782
|
+
onDrop(list, event) {
|
3783
|
+
event.preventDefault();
|
3784
|
+
if (this.draggedItem) {
|
3785
|
+
const index = list.indexOf(this.draggedItem);
|
3786
|
+
if (index === -1) {
|
3787
|
+
this.removeItem(this.draggedItem);
|
3788
|
+
list.push(this.draggedItem);
|
3789
|
+
}
|
3790
|
+
this.draggedItem = null;
|
3791
|
+
}
|
3792
|
+
}
|
3793
|
+
removeItem(item) {
|
3794
|
+
[this.nonSelectedList, this.selectedList].forEach((list) => {
|
3795
|
+
const index = list.indexOf(item);
|
3796
|
+
if (index !== -1) {
|
3797
|
+
list.splice(index, 1);
|
3798
|
+
}
|
3799
|
+
});
|
3800
|
+
}
|
3801
|
+
nonSelectedListInputChange(event) {
|
3802
|
+
this.nonSelectedListInputSubject.next(event.target.value);
|
3803
|
+
}
|
3804
|
+
selectedListInputChange(event) {
|
3805
|
+
this.selectedListInputSubject.next(event.target.value);
|
3806
|
+
}
|
3807
|
+
selButtonClick() {
|
3808
|
+
this.selectedButtonClick.emit();
|
3809
|
+
}
|
3810
|
+
nonSelButtonClick() {
|
3811
|
+
this.nonSelectedButtonClick.emit();
|
3812
|
+
}
|
3813
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragDropListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3814
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DragDropListComponent, selector: "argenta-drag-drop-list", inputs: { nonSelectedTitle: "nonSelectedTitle", nonSelectedList: "nonSelectedList", nonSelectedButtonLabel: "nonSelectedButtonLabel", selectedTitle: "selectedTitle", selectedList: "selectedList", selectedButtonLabel: "selectedButtonLabel" }, outputs: { nonSelectedButtonClick: "nonSelectedButtonClick", nonSelectedInputChanged: "nonSelectedInputChanged", selectedButtonClick: "selectedButtonClick", selectedInputChanged: "selectedInputChanged" }, ngImport: i0, template: "<!-- Cont\u00EAiner externo para dar a apar\u00EAncia de grupo -->\n<div class=\"group-container\">\n <div class=\"container\">\n <!-- Lista 1 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(nonSelectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ nonSelectedTitle }}</h6>\n <div *ngIf=\"nonSelectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ nonSelectedButtonLabel }}\"\n (onButtonClick)=\"nonSelButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"nonSelectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of nonSelectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n\n <!-- Lista 2 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(selectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ selectedTitle }}</h6>\n <div *ngIf=\"selectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ selectedButtonLabel }}\"\n (onButtonClick)=\"selButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"selectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of selectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.group-container{display:flex;justify-content:center;padding:20px;background-color:#fff;border-radius:12px;box-shadow:0 4px 8px #0000001a;width:80%;margin:auto}.container{display:flex;gap:20px;width:100%}.list{flex:1;padding:10px;background-color:#f0f0f0;border-radius:8px;display:flex;flex-direction:column;align-items:flex-start;gap:10px}.list-input{width:100%;height:40px;margin-bottom:15px;border-radius:4px;border:1px solid #ccc;outline:none;font-size:1rem;resize:none}.item-card{width:100%;padding:15px;background-color:#fff;border-radius:8px;box-shadow:0 2px 5px #0003;cursor:move;display:flex;align-items:center;justify-content:center;text-align:center;font-family:var(--font-family);font-weight:500;font-size:1.1rem;color:#333}.row{display:flex;justify-content:space-between;align-items:center;width:100%;max-height:50px;height:50px}.align-end{display:flex;justify-content:flex-end}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "argenta-custom-button", inputs: ["type", "label", "btnClass", "fontSize", "disabled", "autofocus", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget", "name", "value", "permissions"], outputs: ["onButtonClick"] }] }); }
|
3815
|
+
}
|
3816
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragDropListComponent, decorators: [{
|
3817
|
+
type: Component,
|
3818
|
+
args: [{ selector: "argenta-drag-drop-list", template: "<!-- Cont\u00EAiner externo para dar a apar\u00EAncia de grupo -->\n<div class=\"group-container\">\n <div class=\"container\">\n <!-- Lista 1 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(nonSelectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ nonSelectedTitle }}</h6>\n <div *ngIf=\"nonSelectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ nonSelectedButtonLabel }}\"\n (onButtonClick)=\"nonSelButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"nonSelectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of nonSelectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n\n <!-- Lista 2 com input -->\n <div\n class=\"list\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop(selectedList, $event)\"\n >\n <div class=\"row\">\n <h6 class=\"col-md-8\">{{ selectedTitle }}</h6>\n <div *ngIf=\"selectedButtonLabel\" class=\"col-md-4 align-end\">\n <argenta-custom-button\n label=\"{{ selectedButtonLabel }}\"\n (onButtonClick)=\"selButtonClick()\"\n class=\"align-end\"\n [btnClass]=\"ButtonClasses.Primary\"\n >\n </argenta-custom-button>\n </div>\n </div>\n <input\n type=\"text\"\n class=\"list-input\"\n (input)=\"selectedListInputChange($event)\"\n />\n <div\n *ngFor=\"let item of selectedList\"\n class=\"item-card\"\n draggable=\"true\"\n (dragstart)=\"onDragStart(item)\"\n >\n {{ item.descricao }}\n </div>\n </div>\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";.group-container{display:flex;justify-content:center;padding:20px;background-color:#fff;border-radius:12px;box-shadow:0 4px 8px #0000001a;width:80%;margin:auto}.container{display:flex;gap:20px;width:100%}.list{flex:1;padding:10px;background-color:#f0f0f0;border-radius:8px;display:flex;flex-direction:column;align-items:flex-start;gap:10px}.list-input{width:100%;height:40px;margin-bottom:15px;border-radius:4px;border:1px solid #ccc;outline:none;font-size:1rem;resize:none}.item-card{width:100%;padding:15px;background-color:#fff;border-radius:8px;box-shadow:0 2px 5px #0003;cursor:move;display:flex;align-items:center;justify-content:center;text-align:center;font-family:var(--font-family);font-weight:500;font-size:1.1rem;color:#333}.row{display:flex;justify-content:space-between;align-items:center;width:100%;max-height:50px;height:50px}.align-end{display:flex;justify-content:flex-end}\n"] }]
|
3819
|
+
}], ctorParameters: function () { return []; }, propDecorators: { nonSelectedTitle: [{
|
3820
|
+
type: Input
|
3821
|
+
}], nonSelectedList: [{
|
3822
|
+
type: Input
|
3823
|
+
}], nonSelectedButtonLabel: [{
|
3824
|
+
type: Input
|
3825
|
+
}], nonSelectedButtonClick: [{
|
3826
|
+
type: Output
|
3827
|
+
}], nonSelectedInputChanged: [{
|
3828
|
+
type: Output
|
3829
|
+
}], selectedTitle: [{
|
3830
|
+
type: Input
|
3831
|
+
}], selectedList: [{
|
3832
|
+
type: Input
|
3833
|
+
}], selectedButtonLabel: [{
|
3834
|
+
type: Input
|
3835
|
+
}], selectedButtonClick: [{
|
3836
|
+
type: Output
|
3837
|
+
}], selectedInputChanged: [{
|
3838
|
+
type: Output
|
3839
|
+
}] } });
|
3840
|
+
|
3841
|
+
class DataExcelExporterComponent {
|
3842
|
+
constructor() {
|
3843
|
+
this.data = [];
|
3844
|
+
}
|
3845
|
+
exportToExcel() {
|
3846
|
+
if (!this.config || (!this.data.length && !this.config.multipleSheets)) {
|
3847
|
+
console.warn("Nenhuma configuração ou dados fornecidos.");
|
3848
|
+
return;
|
3849
|
+
}
|
3850
|
+
const workbook = XLSX.utils.book_new();
|
3851
|
+
// Verifica se múltiplas planilhas estão configuradas
|
3852
|
+
if (this.config.multipleSheets) {
|
3853
|
+
this.config.multipleSheets.forEach((sheetConfig) => {
|
3854
|
+
const worksheet = XLSX.utils.aoa_to_sheet([]);
|
3855
|
+
// Adiciona o título, se houver
|
3856
|
+
let startRow = 0;
|
3857
|
+
if (sheetConfig.title) {
|
3858
|
+
XLSX.utils.sheet_add_aoa(worksheet, [[sheetConfig.title]], {
|
3859
|
+
origin: "A1",
|
3860
|
+
});
|
3861
|
+
// Define larguras personalizadas do título
|
3862
|
+
if (sheetConfig.titleWidths) {
|
3863
|
+
worksheet["!cols"] = sheetConfig.titleWidths.map((width) => ({
|
3864
|
+
wch: width,
|
3865
|
+
}));
|
3866
|
+
}
|
3867
|
+
// Mescla o título
|
3868
|
+
if (sheetConfig.tableHeaders) {
|
3869
|
+
worksheet["!merges"] = worksheet["!merges"] || [];
|
3870
|
+
worksheet["!merges"].push({
|
3871
|
+
s: { r: 0, c: 0 },
|
3872
|
+
e: { r: 0, c: sheetConfig.tableHeaders.length - 1 },
|
3873
|
+
});
|
3874
|
+
}
|
3875
|
+
startRow = 1;
|
3876
|
+
}
|
3877
|
+
// Adiciona cabeçalhos
|
3878
|
+
if (sheetConfig.tableHeaders) {
|
3879
|
+
XLSX.utils.sheet_add_aoa(worksheet, [sheetConfig.tableHeaders], {
|
3880
|
+
origin: `A${startRow + 1}`,
|
3881
|
+
});
|
3882
|
+
}
|
3883
|
+
// Adiciona dados
|
3884
|
+
if (sheetConfig.data) {
|
3885
|
+
XLSX.utils.sheet_add_json(worksheet, sheetConfig.data, {
|
3886
|
+
origin: `A${startRow + 2}`,
|
3887
|
+
skipHeader: true,
|
3888
|
+
});
|
3889
|
+
}
|
3890
|
+
// Define larguras das colunas
|
3891
|
+
if (sheetConfig.columnWidths) {
|
3892
|
+
worksheet["!cols"] = sheetConfig.columnWidths.map((width) => ({
|
3893
|
+
wch: width,
|
3894
|
+
}));
|
3895
|
+
}
|
3896
|
+
// Adiciona a planilha ao workbook
|
3897
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, sheetConfig.sheetName);
|
3898
|
+
});
|
3899
|
+
}
|
3900
|
+
else {
|
3901
|
+
// Caso não haja múltiplas planilhas, processa a planilha única
|
3902
|
+
const worksheet = XLSX.utils.aoa_to_sheet([]);
|
3903
|
+
// Adiciona título, se houver
|
3904
|
+
let startRow = 0;
|
3905
|
+
if (this.config.title) {
|
3906
|
+
XLSX.utils.sheet_add_aoa(worksheet, [[this.config.title]], {
|
3907
|
+
origin: "A1",
|
3908
|
+
});
|
3909
|
+
// Define larguras do título
|
3910
|
+
if (this.config.titleWidths) {
|
3911
|
+
worksheet["!cols"] = this.config.titleWidths.map((width) => ({
|
3912
|
+
wch: width,
|
3913
|
+
}));
|
3914
|
+
}
|
3915
|
+
// Mescla o título
|
3916
|
+
if (this.config.tableHeaders) {
|
3917
|
+
worksheet["!merges"] = worksheet["!merges"] || [];
|
3918
|
+
worksheet["!merges"].push({
|
3919
|
+
s: { r: 0, c: 0 },
|
3920
|
+
e: { r: 0, c: this.config.tableHeaders.length - 1 },
|
3921
|
+
});
|
3922
|
+
}
|
3923
|
+
startRow = 1;
|
3924
|
+
}
|
3925
|
+
// Adiciona cabeçalhos
|
3926
|
+
if (this.config.tableHeaders) {
|
3927
|
+
XLSX.utils.sheet_add_aoa(worksheet, [this.config.tableHeaders], {
|
3928
|
+
origin: `A${startRow + 1}`,
|
3929
|
+
});
|
3930
|
+
}
|
3931
|
+
// Adiciona dados
|
3932
|
+
XLSX.utils.sheet_add_json(worksheet, this.data, {
|
3933
|
+
origin: `A${startRow + 2}`,
|
3934
|
+
skipHeader: true,
|
3935
|
+
});
|
3936
|
+
// Define larguras das colunas
|
3937
|
+
if (this.config.columnWidths) {
|
3938
|
+
worksheet["!cols"] = this.config.columnWidths.map((width) => ({
|
3939
|
+
wch: width,
|
3940
|
+
}));
|
3941
|
+
}
|
3942
|
+
// Adiciona a planilha ao workbook
|
3943
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, this.config.sheetName);
|
3944
|
+
}
|
3945
|
+
// Salva o arquivo Excel
|
3946
|
+
XLSX.writeFile(workbook, this.config.fileName);
|
3947
|
+
}
|
3948
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataExcelExporterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3949
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataExcelExporterComponent, selector: "argenta-excel-exporter", inputs: { config: "config", data: "data" }, ngImport: i0, template: `
|
3950
|
+
<button (click)="exportToExcel()">{{ config?.buttonLabel }}</button>
|
3951
|
+
`, isInline: true, styles: ["button{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);padding:10px 20px;border:none;cursor:pointer}button:hover{background-color:var(--secondary-color)}\n"] }); }
|
3952
|
+
}
|
3953
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataExcelExporterComponent, decorators: [{
|
3954
|
+
type: Component,
|
3955
|
+
args: [{ selector: "argenta-excel-exporter", template: `
|
3956
|
+
<button (click)="exportToExcel()">{{ config?.buttonLabel }}</button>
|
3957
|
+
`, styles: ["button{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);padding:10px 20px;border:none;cursor:pointer}button:hover{background-color:var(--secondary-color)}\n"] }]
|
3958
|
+
}], propDecorators: { config: [{
|
3959
|
+
type: Input
|
3960
|
+
}], data: [{
|
3961
|
+
type: Input
|
3962
|
+
}] } });
|
3963
|
+
|
3964
|
+
class DataExcelImporterComponent {
|
3965
|
+
constructor() {
|
3966
|
+
this.excelData = new EventEmitter(); // Evento para enviar dados processados
|
3967
|
+
// Configurações padrão
|
3968
|
+
this.config = {
|
3969
|
+
acceptedFileTypes: [".xlsx", ".xls", ".csv"],
|
3970
|
+
onImport: (data) => this.defaultImportHandler(data),
|
3971
|
+
excludeRows: [],
|
3972
|
+
excludeColumns: [],
|
3973
|
+
hasHeader: true,
|
3974
|
+
headerRowIndex: 1,
|
3975
|
+
titleRowIndex: 1,
|
3976
|
+
};
|
3977
|
+
// Controle do modal e inputs de configuração
|
3978
|
+
this.userConfig = { ...this.config };
|
3979
|
+
this.excludeRowsInput = ""; // Para capturar linhas a excluir
|
3980
|
+
this.excludeColumnsInput = ""; // Para capturar colunas a excluir
|
3981
|
+
this.showConfigModal = false;
|
3982
|
+
this.buttonLabel = "Importar Dados";
|
3983
|
+
}
|
3984
|
+
// Abre o modal de configurações
|
3985
|
+
openModal() {
|
3986
|
+
this.showConfigModal = true;
|
3987
|
+
}
|
3988
|
+
// Fecha o modal de configurações
|
3989
|
+
closeModal() {
|
3990
|
+
this.showConfigModal = false;
|
3991
|
+
}
|
3992
|
+
// Salva as configurações ajustadas no modal
|
3993
|
+
saveConfig() {
|
3994
|
+
this.config = {
|
3995
|
+
...this.userConfig,
|
3996
|
+
titleRowIndex: (this.userConfig.titleRowIndex ?? 1) - 1,
|
3997
|
+
headerRowIndex: (this.userConfig.headerRowIndex ?? 2) - 1,
|
3998
|
+
excludeRows: this.excludeRowsInput
|
3999
|
+
.split(",")
|
4000
|
+
.map((row) => parseInt(row.trim(), 10) - 1),
|
4001
|
+
excludeColumns: this.excludeColumnsInput
|
4002
|
+
.split(",")
|
4003
|
+
.map((col) => this.columnLetterToIndex(col.trim())), // Converte letras para índices
|
4004
|
+
};
|
4005
|
+
this.closeModal();
|
4006
|
+
}
|
4007
|
+
// Valida que as linhas informadas sejam pelo menos 1
|
4008
|
+
validateRowInput(field) {
|
4009
|
+
if (field === "headerRow" && this.userConfig.headerRowIndex < 1) {
|
4010
|
+
this.userConfig.headerRowIndex = 1;
|
4011
|
+
}
|
4012
|
+
if (field === "titleRow" && this.userConfig.titleRowIndex < 1) {
|
4013
|
+
this.userConfig.titleRowIndex = 1;
|
4014
|
+
}
|
4015
|
+
}
|
4016
|
+
// Processa o arquivo selecionado
|
4017
|
+
handleFileInput(event) {
|
4018
|
+
const file = event.target.files[0];
|
4019
|
+
if (file) {
|
4020
|
+
const fileType = file.name.split(".").pop()?.toLowerCase();
|
4021
|
+
if (fileType === "csv") {
|
4022
|
+
this.processCSVFile(file); // Processa o CSV de forma isolada
|
4023
|
+
}
|
4024
|
+
else {
|
4025
|
+
this.processExcelFile(file); // Mantém o fluxo atual para Excel
|
4026
|
+
}
|
4027
|
+
event.target.value = ""; // Reseta o input para permitir reimportação
|
4028
|
+
}
|
4029
|
+
}
|
4030
|
+
processExcelFile(file) {
|
4031
|
+
const reader = new FileReader();
|
4032
|
+
reader.onload = (e) => {
|
4033
|
+
const data = new Uint8Array(e.target.result);
|
4034
|
+
const workbook = XLSX.read(data, { type: "array" });
|
4035
|
+
const sheetName = workbook.SheetNames[0];
|
4036
|
+
const worksheet = workbook.Sheets[sheetName];
|
4037
|
+
const titleRowIndex = this.config.titleRowIndex ?? 0;
|
4038
|
+
const headerRowIndex = this.config.headerRowIndex ?? titleRowIndex + 1;
|
4039
|
+
if (worksheet["!ref"]) {
|
4040
|
+
worksheet["!ref"] = this.adjustRange(worksheet["!ref"], headerRowIndex + 1);
|
4041
|
+
}
|
4042
|
+
else {
|
4043
|
+
console.error("Intervalo da planilha ('!ref') não encontrado.");
|
4044
|
+
return;
|
4045
|
+
}
|
4046
|
+
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
|
4047
|
+
header: 1,
|
4048
|
+
defval: "",
|
4049
|
+
blankrows: false,
|
4050
|
+
});
|
4051
|
+
this.processData(jsonData);
|
4052
|
+
};
|
4053
|
+
reader.readAsArrayBuffer(file); // Lê o Excel como array buffer
|
4054
|
+
}
|
4055
|
+
processCSVFile(file) {
|
4056
|
+
if (this.userConfig.hasHeader) {
|
4057
|
+
if (this.config?.headerRowIndex !== undefined) {
|
4058
|
+
this.config.headerRowIndex =
|
4059
|
+
this.config.headerRowIndex === 0 ? 1 : this.config.headerRowIndex + 1;
|
4060
|
+
}
|
4061
|
+
const sum = (this.config.excludeRows ?? []).reduce((acc, value) => acc + value, 0) +
|
4062
|
+
1;
|
4063
|
+
this.config.excludeRows = [sum];
|
4064
|
+
}
|
4065
|
+
const reader = new FileReader();
|
4066
|
+
reader.onload = (e) => {
|
4067
|
+
const csvData = e.target.result;
|
4068
|
+
// Converte CSV em JSON usando XLSX
|
4069
|
+
const workbook = XLSX.read(csvData, { type: "string" });
|
4070
|
+
const sheetName = workbook.SheetNames[0];
|
4071
|
+
const worksheet = workbook.Sheets[sheetName];
|
4072
|
+
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
|
4073
|
+
header: 1,
|
4074
|
+
defval: "",
|
4075
|
+
blankrows: false,
|
4076
|
+
});
|
4077
|
+
this.processData(jsonData);
|
4078
|
+
};
|
4079
|
+
reader.readAsText(file); // Lê o CSV como texto
|
4080
|
+
}
|
4081
|
+
processData(jsonData) {
|
4082
|
+
const titleRowIndex = this.config.titleRowIndex ?? 0;
|
4083
|
+
const headerRowIndex = this.config.headerRowIndex ?? titleRowIndex + 1;
|
4084
|
+
const headers = jsonData[0];
|
4085
|
+
if (!headers) {
|
4086
|
+
console.error("Cabeçalhos não encontrados. Verifique o headerRowIndex.");
|
4087
|
+
return;
|
4088
|
+
}
|
4089
|
+
const normalizedHeaders = headers.map((header, index) => this.normalizeHeader(header || `col_${index}`));
|
4090
|
+
const dataRows = jsonData.slice(1); // Remove a linha de cabeçalho
|
4091
|
+
// Filtra as linhas baseando-se no índice informado pelo usuário (1-based)
|
4092
|
+
const filteredRows = dataRows.filter((_, index) => !this.config.excludeRows?.includes(index + headerRowIndex + 1));
|
4093
|
+
const formattedData = filteredRows.map((row) => {
|
4094
|
+
const record = {};
|
4095
|
+
normalizedHeaders.forEach((header, index) => {
|
4096
|
+
record[header] = row[index] ?? "";
|
4097
|
+
});
|
4098
|
+
return record;
|
4099
|
+
});
|
4100
|
+
const finalData = this.filterColumns(formattedData);
|
4101
|
+
this.config.onImport(finalData); // Chama o callback com os dados processados
|
4102
|
+
this.excelData.emit(finalData); // Emite os dados processados para o cliente
|
4103
|
+
}
|
4104
|
+
// Ajusta o intervalo da planilha com base na linha do cabeçalho
|
4105
|
+
adjustRange(range, startRow) {
|
4106
|
+
const [start, end] = range.split(":");
|
4107
|
+
const startCol = start.replace(/[0-9]/g, "");
|
4108
|
+
const endCol = end.replace(/[0-9]/g, "");
|
4109
|
+
const endRow = end.replace(/[A-Za-z]/g, "");
|
4110
|
+
return `${startCol}${startRow}:${endCol}${endRow}`;
|
4111
|
+
}
|
4112
|
+
// Normaliza os cabeçalhos removendo acentos e espaços
|
4113
|
+
normalizeHeader(header) {
|
4114
|
+
return header
|
4115
|
+
.normalize("NFD")
|
4116
|
+
.replace(/[\u0300-\u036f]/g, "")
|
4117
|
+
.replace(/\s+/g, "_")
|
4118
|
+
.toLowerCase();
|
4119
|
+
}
|
4120
|
+
// Filtra as colunas configuradas para exclusão
|
4121
|
+
filterColumns(data) {
|
4122
|
+
const { excludeColumns } = this.config;
|
4123
|
+
return data.map((row) => {
|
4124
|
+
const filteredRow = {};
|
4125
|
+
Object.keys(row).forEach((key, index) => {
|
4126
|
+
if (!excludeColumns?.includes(index)) {
|
4127
|
+
filteredRow[key] = row[key];
|
4128
|
+
}
|
4129
|
+
});
|
4130
|
+
return filteredRow;
|
4131
|
+
});
|
4132
|
+
}
|
4133
|
+
// Converte letra da coluna para índice (A -> 0, B -> 1, etc.)
|
4134
|
+
columnLetterToIndex(letter) {
|
4135
|
+
let index = 0;
|
4136
|
+
for (let i = 0; i < letter.length; i++) {
|
4137
|
+
index = index * 26 + (letter.charCodeAt(i) - "A".charCodeAt(0) + 1);
|
4138
|
+
}
|
4139
|
+
return index - 1;
|
4140
|
+
}
|
4141
|
+
// Callback padrão para manipular dados importados
|
4142
|
+
defaultImportHandler(data) { }
|
4143
|
+
transformToUppercase() {
|
4144
|
+
this.excludeColumnsInput = this.excludeColumnsInput.toUpperCase();
|
4145
|
+
}
|
4146
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataExcelImporterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
4147
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DataExcelImporterComponent, selector: "argenta-excel-importer", outputs: { excelData: "excelData" }, ngImport: i0, template: "<div class=\"excel-importer\">\n <input\n type=\"file\"\n (change)=\"handleFileInput($event)\"\n [accept]=\"config.acceptedFileTypes?.join(',')\"\n style=\"display: none\"\n #fileInput\n />\n <button (click)=\"fileInput.click()\">{{ buttonLabel }}</button>\n <lucide-icon\n name=\"settings\"\n [size]=\"24\"\n [strokeWidth]=\"2.25\"\n class=\"settings-icon\"\n (click)=\"openModal()\"\n ></lucide-icon>\n</div>\n\n<div class=\"modal-container\" *ngIf=\"showConfigModal\">\n <div class=\"modal-content\">\n <h4 class=\"titulo\">Configura\u00E7\u00E3o de Importa\u00E7\u00E3o</h4>\n <form (ngSubmit)=\"saveConfig()\">\n <div class=\"form-group\">\n <label for=\"acceptedFileTypes\">Tipos de Arquivo Permitidos</label>\n <input\n id=\"acceptedFileTypes\"\n type=\"text\"\n [(ngModel)]=\"userConfig.acceptedFileTypes\"\n name=\"acceptedFileTypes\"\n placeholder=\".xlsx, .xls\"\n />\n </div>\n <div class=\"form-group\" style=\"display: none\">\n <label for=\"titleRow\">Linha do T\u00EDtulo (se aplic\u00E1vel)</label>\n <input\n id=\"titleRow\"\n type=\"number\"\n [(ngModel)]=\"userConfig.titleRowIndex\"\n name=\"titleRow\"\n placeholder=\"Ex: 1\"\n (change)=\"validateRowInput('titleRow')\"\n />\n </div>\n <div class=\"form-group checkbox-group\">\n <div class=\"row\">\n <div class=\"col-md-8\">\n <label for=\"hasHeader\">A planilha cont\u00E9m cabe\u00E7alho?</label>\n </div>\n <div class=\"col-md-4\">\n <input\n id=\"hasHeader\"\n class=\"input-checkbox\"\n type=\"checkbox\"\n [(ngModel)]=\"userConfig.hasHeader\"\n name=\"hasHeader\"\n />\n </div>\n </div>\n </div>\n\n <!-- Exibe a linha do cabe\u00E7alho apenas se o checkbox estiver marcado -->\n <div class=\"form-group\" *ngIf=\"userConfig.hasHeader\">\n <label for=\"headerRow\">Linha do Cabe\u00E7alho</label>\n <input\n id=\"headerRow\"\n type=\"number\"\n [(ngModel)]=\"userConfig.headerRowIndex\"\n name=\"headerRow\"\n placeholder=\"Ex: 2\"\n (change)=\"validateRowInput('headerRow')\"\n />\n </div>\n\n <div class=\"form-group\">\n <label for=\"excludeRows\">Linhas a Excluir</label>\n <input\n id=\"excludeRows\"\n type=\"text\"\n [(ngModel)]=\"excludeRowsInput\"\n name=\"excludeRows\"\n placeholder=\"Ex: 1, 3\"\n />\n </div>\n <div class=\"form-group\">\n <label for=\"excludeColumns\">Colunas a Excluir</label>\n <input\n id=\"excludeColumns\"\n type=\"text\"\n [(ngModel)]=\"excludeColumnsInput\"\n name=\"excludeColumns\"\n placeholder=\"Ex: A, C\"\n (input)=\"transformToUppercase()\"\n />\n </div>\n <button type=\"submit\">Salvar Configura\u00E7\u00F5es</button>\n <button type=\"button\" (click)=\"closeModal()\">Fechar</button>\n </form>\n </div>\n</div>\n", styles: [".excel-importer{display:flex;align-items:center;gap:10px}.excel-importer button{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);padding:10px 20px;border:none;cursor:pointer;display:flex;align-items:center}.excel-importer button:hover{background-color:var(--secondary-color)}.excel-importer .settings-icon{color:var(--text-color);background-color:var(--primary-color);border-radius:50%;padding:5px;cursor:pointer;transition:background-color .3s,color .3s}.excel-importer .settings-icon:hover{background-color:var(--secondary-color);color:#fff}.modal-container{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center}.modal-content{background:#fff;padding:20px;border-radius:5px;width:400px}.modal-content h2{margin-bottom:20px}.modal-content .form-group{margin-bottom:15px}.modal-content .form-group label{display:block;margin-bottom:5px}.modal-content .form-group input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px}.modal-content button{margin-right:10px;padding:8px 15px;border:none;cursor:pointer}.modal-content button:first-of-type{background-color:var(--primary-color);color:#fff}.modal-content button:last-of-type{background-color:#ccc}input#excludeColumns{text-transform:uppercase}.small-label{font-size:.7rem;color:#555}.input-checkbox{margin-left:-5rem}.titulo{margin-bottom:2rem}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i4.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }] }); }
|
4148
|
+
}
|
4149
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataExcelImporterComponent, decorators: [{
|
4150
|
+
type: Component,
|
4151
|
+
args: [{ selector: "argenta-excel-importer", template: "<div class=\"excel-importer\">\n <input\n type=\"file\"\n (change)=\"handleFileInput($event)\"\n [accept]=\"config.acceptedFileTypes?.join(',')\"\n style=\"display: none\"\n #fileInput\n />\n <button (click)=\"fileInput.click()\">{{ buttonLabel }}</button>\n <lucide-icon\n name=\"settings\"\n [size]=\"24\"\n [strokeWidth]=\"2.25\"\n class=\"settings-icon\"\n (click)=\"openModal()\"\n ></lucide-icon>\n</div>\n\n<div class=\"modal-container\" *ngIf=\"showConfigModal\">\n <div class=\"modal-content\">\n <h4 class=\"titulo\">Configura\u00E7\u00E3o de Importa\u00E7\u00E3o</h4>\n <form (ngSubmit)=\"saveConfig()\">\n <div class=\"form-group\">\n <label for=\"acceptedFileTypes\">Tipos de Arquivo Permitidos</label>\n <input\n id=\"acceptedFileTypes\"\n type=\"text\"\n [(ngModel)]=\"userConfig.acceptedFileTypes\"\n name=\"acceptedFileTypes\"\n placeholder=\".xlsx, .xls\"\n />\n </div>\n <div class=\"form-group\" style=\"display: none\">\n <label for=\"titleRow\">Linha do T\u00EDtulo (se aplic\u00E1vel)</label>\n <input\n id=\"titleRow\"\n type=\"number\"\n [(ngModel)]=\"userConfig.titleRowIndex\"\n name=\"titleRow\"\n placeholder=\"Ex: 1\"\n (change)=\"validateRowInput('titleRow')\"\n />\n </div>\n <div class=\"form-group checkbox-group\">\n <div class=\"row\">\n <div class=\"col-md-8\">\n <label for=\"hasHeader\">A planilha cont\u00E9m cabe\u00E7alho?</label>\n </div>\n <div class=\"col-md-4\">\n <input\n id=\"hasHeader\"\n class=\"input-checkbox\"\n type=\"checkbox\"\n [(ngModel)]=\"userConfig.hasHeader\"\n name=\"hasHeader\"\n />\n </div>\n </div>\n </div>\n\n <!-- Exibe a linha do cabe\u00E7alho apenas se o checkbox estiver marcado -->\n <div class=\"form-group\" *ngIf=\"userConfig.hasHeader\">\n <label for=\"headerRow\">Linha do Cabe\u00E7alho</label>\n <input\n id=\"headerRow\"\n type=\"number\"\n [(ngModel)]=\"userConfig.headerRowIndex\"\n name=\"headerRow\"\n placeholder=\"Ex: 2\"\n (change)=\"validateRowInput('headerRow')\"\n />\n </div>\n\n <div class=\"form-group\">\n <label for=\"excludeRows\">Linhas a Excluir</label>\n <input\n id=\"excludeRows\"\n type=\"text\"\n [(ngModel)]=\"excludeRowsInput\"\n name=\"excludeRows\"\n placeholder=\"Ex: 1, 3\"\n />\n </div>\n <div class=\"form-group\">\n <label for=\"excludeColumns\">Colunas a Excluir</label>\n <input\n id=\"excludeColumns\"\n type=\"text\"\n [(ngModel)]=\"excludeColumnsInput\"\n name=\"excludeColumns\"\n placeholder=\"Ex: A, C\"\n (input)=\"transformToUppercase()\"\n />\n </div>\n <button type=\"submit\">Salvar Configura\u00E7\u00F5es</button>\n <button type=\"button\" (click)=\"closeModal()\">Fechar</button>\n </form>\n </div>\n</div>\n", styles: [".excel-importer{display:flex;align-items:center;gap:10px}.excel-importer button{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);padding:10px 20px;border:none;cursor:pointer;display:flex;align-items:center}.excel-importer button:hover{background-color:var(--secondary-color)}.excel-importer .settings-icon{color:var(--text-color);background-color:var(--primary-color);border-radius:50%;padding:5px;cursor:pointer;transition:background-color .3s,color .3s}.excel-importer .settings-icon:hover{background-color:var(--secondary-color);color:#fff}.modal-container{position:fixed;top:0;left:0;width:100%;height:100%;background-color:#00000080;display:flex;justify-content:center;align-items:center}.modal-content{background:#fff;padding:20px;border-radius:5px;width:400px}.modal-content h2{margin-bottom:20px}.modal-content .form-group{margin-bottom:15px}.modal-content .form-group label{display:block;margin-bottom:5px}.modal-content .form-group input{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px}.modal-content button{margin-right:10px;padding:8px 15px;border:none;cursor:pointer}.modal-content button:first-of-type{background-color:var(--primary-color);color:#fff}.modal-content button:last-of-type{background-color:#ccc}input#excludeColumns{text-transform:uppercase}.small-label{font-size:.7rem;color:#555}.input-checkbox{margin-left:-5rem}.titulo{margin-bottom:2rem}\n"] }]
|
4152
|
+
}], propDecorators: { excelData: [{
|
4153
|
+
type: Output
|
4154
|
+
}] } });
|
4155
|
+
|
4156
|
+
class CsvImporterComponent {
|
4157
|
+
constructor() {
|
4158
|
+
this.config = {
|
4159
|
+
acceptedFileTypes: [".xlsx", ".xls", ".csv"],
|
4160
|
+
detectHeaders: true,
|
4161
|
+
delimiter: ";",
|
4162
|
+
onImport: () => { },
|
4163
|
+
};
|
4164
|
+
}
|
4165
|
+
handleFileInput(event) {
|
4166
|
+
const file = event.target.files[0];
|
4167
|
+
if (file) {
|
4168
|
+
const reader = new FileReader();
|
4169
|
+
// Detecta se o arquivo é CSV
|
4170
|
+
if (file.name.endsWith(".csv")) {
|
4171
|
+
reader.onload = (e) => {
|
4172
|
+
const csvData = e.target.result;
|
4173
|
+
const delimiter = this.config.delimiter ?? ";"; // Usa delimitador configurado ou padrão
|
4174
|
+
const jsonData = this.parseCSV(csvData, delimiter);
|
4175
|
+
this.processData(jsonData);
|
4176
|
+
};
|
4177
|
+
reader.readAsText(file);
|
4178
|
+
}
|
4179
|
+
else {
|
4180
|
+
// Processa arquivos Excel (XLSX/XLS)
|
4181
|
+
reader.onload = (e) => {
|
4182
|
+
const data = new Uint8Array(e.target.result);
|
4183
|
+
const workbook = XLSX.read(data, { type: "array" });
|
4184
|
+
const sheetName = workbook.SheetNames[0];
|
4185
|
+
const worksheet = workbook.Sheets[sheetName];
|
4186
|
+
const jsonData = XLSX.utils.sheet_to_json(worksheet, {
|
4187
|
+
header: 1,
|
4188
|
+
defval: "",
|
4189
|
+
});
|
4190
|
+
this.processData(jsonData);
|
4191
|
+
};
|
4192
|
+
reader.readAsArrayBuffer(file);
|
4193
|
+
}
|
4194
|
+
}
|
4195
|
+
}
|
4196
|
+
parseCSV(csvData, delimiter = ";") {
|
4197
|
+
return csvData
|
4198
|
+
.split("\n")
|
4199
|
+
.map((row) => row.split(delimiter).map((cell) => cell.trim()));
|
4200
|
+
}
|
4201
|
+
processData(jsonData) {
|
4202
|
+
const headers = this.getHeaders(jsonData);
|
4203
|
+
const dataRows = jsonData.slice(headers ? 1 : 0);
|
4204
|
+
const formattedData = this.formatData(dataRows, headers);
|
4205
|
+
this.config.onImport(formattedData);
|
4206
|
+
}
|
4207
|
+
getHeaders(data) {
|
4208
|
+
if (this.config.customHeaders) {
|
4209
|
+
return this.config.customHeaders;
|
4210
|
+
}
|
4211
|
+
if (this.config.detectHeaders && data.length > 0) {
|
4212
|
+
return data[0].map((header, index) => this.normalizeHeader(header || `col_${index}`));
|
4213
|
+
}
|
4214
|
+
return null; // Nenhum cabeçalho detectado
|
4215
|
+
}
|
4216
|
+
formatData(dataRows, headers) {
|
4217
|
+
if (!headers) {
|
4218
|
+
return dataRows; // Retorna dados brutos se não houver cabeçalhos
|
4219
|
+
}
|
4220
|
+
return dataRows.map((row) => {
|
4221
|
+
const record = {};
|
4222
|
+
headers.forEach((header, index) => {
|
4223
|
+
record[header] = row[index] ?? "";
|
4224
|
+
});
|
4225
|
+
return record;
|
4226
|
+
});
|
4227
|
+
}
|
4228
|
+
normalizeHeader(header) {
|
4229
|
+
return String(header)
|
4230
|
+
.normalize("NFD")
|
4231
|
+
.replace(/[\u0300-\u036f]/g, "")
|
4232
|
+
.replace(/\s+/g, "_")
|
4233
|
+
.toLowerCase();
|
4234
|
+
}
|
4235
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CsvImporterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
4236
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CsvImporterComponent, selector: "argenta-csv-importer", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"excel-importer\">\n <input\n type=\"file\"\n (change)=\"handleFileInput($event)\"\n [accept]=\"config.acceptedFileTypes?.join(',')\"\n style=\"display: none\"\n #fileInput\n />\n <button (click)=\"fileInput.click()\">Importar Arquivo</button>\n</div>\n", styles: [".excel-importer button{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);padding:10px 20px;border:none;cursor:pointer}.excel-importer button:hover{background-color:var(--secondary-color)}\n"] }); }
|
4237
|
+
}
|
4238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CsvImporterComponent, decorators: [{
|
4239
|
+
type: Component,
|
4240
|
+
args: [{ selector: "argenta-csv-importer", template: "<div class=\"excel-importer\">\n <input\n type=\"file\"\n (change)=\"handleFileInput($event)\"\n [accept]=\"config.acceptedFileTypes?.join(',')\"\n style=\"display: none\"\n #fileInput\n />\n <button (click)=\"fileInput.click()\">Importar Arquivo</button>\n</div>\n", styles: [".excel-importer button{background-color:var(--primary-color);color:var(--text-color);font-family:var(--font-family);padding:10px 20px;border:none;cursor:pointer}.excel-importer button:hover{background-color:var(--secondary-color)}\n"] }]
|
4241
|
+
}], propDecorators: { config: [{
|
4242
|
+
type: Input
|
4243
|
+
}] } });
|
4244
|
+
|
3594
4245
|
// Select some icons (use an object, not an array)
|
3595
4246
|
class LucideIconsModule {
|
3596
4247
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LucideIconsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
3597
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: LucideIconsModule, imports: [
|
4248
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: LucideIconsModule, imports: [i4.LucideAngularModule], exports: [LucideAngularModule] }); }
|
3598
4249
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LucideIconsModule, imports: [LucideAngularModule.pick(icons), LucideAngularModule] }); }
|
3599
4250
|
}
|
3600
4251
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LucideIconsModule, decorators: [{
|
@@ -3640,7 +4291,12 @@ class ComponentsModule {
|
|
3640
4291
|
ModalComponent,
|
3641
4292
|
DragDropListComponent,
|
3642
4293
|
DynamicModalComponent,
|
3643
|
-
DynamicTableComponent
|
4294
|
+
DynamicTableComponent,
|
4295
|
+
ArgentaPdfDataHandlerComponent,
|
4296
|
+
ArgentaPdfDownloadComponent,
|
4297
|
+
DataExcelExporterComponent,
|
4298
|
+
DataExcelImporterComponent,
|
4299
|
+
CsvImporterComponent], imports: [CommonModule,
|
3644
4300
|
FormsModule,
|
3645
4301
|
ReactiveFormsModule,
|
3646
4302
|
NgSelectModule,
|
@@ -3681,7 +4337,12 @@ class ComponentsModule {
|
|
3681
4337
|
ModalComponent,
|
3682
4338
|
DragDropListComponent,
|
3683
4339
|
DynamicModalComponent,
|
3684
|
-
DynamicTableComponent
|
4340
|
+
DynamicTableComponent,
|
4341
|
+
ArgentaPdfDataHandlerComponent,
|
4342
|
+
ArgentaPdfDownloadComponent,
|
4343
|
+
DataExcelExporterComponent,
|
4344
|
+
DataExcelImporterComponent,
|
4345
|
+
CsvImporterComponent] }); }
|
3685
4346
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ComponentsModule, imports: [CommonModule,
|
3686
4347
|
FormsModule,
|
3687
4348
|
ReactiveFormsModule,
|
@@ -3729,6 +4390,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
3729
4390
|
DragDropListComponent,
|
3730
4391
|
DynamicModalComponent,
|
3731
4392
|
DynamicTableComponent,
|
4393
|
+
ArgentaPdfDataHandlerComponent,
|
4394
|
+
ArgentaPdfDownloadComponent,
|
4395
|
+
DataExcelExporterComponent,
|
4396
|
+
DataExcelImporterComponent,
|
4397
|
+
CsvImporterComponent,
|
3732
4398
|
],
|
3733
4399
|
imports: [
|
3734
4400
|
CommonModule,
|
@@ -3776,6 +4442,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
3776
4442
|
DragDropListComponent,
|
3777
4443
|
DynamicModalComponent,
|
3778
4444
|
DynamicTableComponent,
|
4445
|
+
ArgentaPdfDataHandlerComponent,
|
4446
|
+
ArgentaPdfDownloadComponent,
|
4447
|
+
DataExcelExporterComponent,
|
4448
|
+
DataExcelImporterComponent,
|
4449
|
+
CsvImporterComponent,
|
3779
4450
|
],
|
3780
4451
|
}]
|
3781
4452
|
}] });
|
@@ -3869,7 +4540,7 @@ class DataPaginateService {
|
|
3869
4540
|
};
|
3870
4541
|
}));
|
3871
4542
|
}
|
3872
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataPaginateService, deps: [{ token:
|
4543
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataPaginateService, deps: [{ token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
3873
4544
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataPaginateService, providedIn: "root" }); }
|
3874
4545
|
}
|
3875
4546
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DataPaginateService, decorators: [{
|
@@ -3877,7 +4548,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
3877
4548
|
args: [{
|
3878
4549
|
providedIn: "root",
|
3879
4550
|
}]
|
3880
|
-
}], ctorParameters: function () { return [{ type:
|
4551
|
+
}], ctorParameters: function () { return [{ type: i1$2.HttpClient }]; } });
|
3881
4552
|
|
3882
4553
|
class RouterParameterService {
|
3883
4554
|
constructor() {
|
@@ -3976,7 +4647,7 @@ function setThemeColors(config) {
|
|
3976
4647
|
}
|
3977
4648
|
|
3978
4649
|
/*
|
3979
|
-
* Public API Surface of
|
4650
|
+
* Public API Surface of lib-atriun-angular
|
3980
4651
|
*
|
3981
4652
|
* Este arquivo exporta todos os componentes, enums e módulos necessários
|
3982
4653
|
* para que os consumidores da biblioteca possam utilizá-los em suas aplicações.
|
@@ -3987,5 +4658,5 @@ function setThemeColors(config) {
|
|
3987
4658
|
* Generated bundle index. Do not edit.
|
3988
4659
|
*/
|
3989
4660
|
|
3990
|
-
export { AccordionArgentaComponent, AlertComponent, AppBackgroundComponent, AutofocusDirective, BadgeComponent, BasicRegistrationComponent, ButtonClasses, ButtonComponent, CalendarArgentaComponent, CardComponent, CepMaskDirective, CheckboxComponent, CnpjMaskDirective, CodeHighlightComponent, ComponentsModule, ConfirmationComponent, ConfirmationService, CpfMaskDirective, CustomPaginationComponent, CustomSwitchComponent, DataPaginateService, DataTableComponent, DragDropListComponent, DynamicModalComponent, DynamicTableComponent, FileUploadComponent, InputComponent, JsonViewerComponent, LibPortalAngularModule, LucideIconsModule, ModalComponent, MultiSelectCategoryComponent, MultiSelectComponent, NotificationService, RadioComponent, RefreshService, RouterParameterService, SearchCustomerComponent, SearchInputComponent, SelectComponent, TabComponent, TextareaComponent, TreeNodeComponent, convertToSnakeCase, setThemeColors };
|
4661
|
+
export { AccordionArgentaComponent, AlertComponent, AppBackgroundComponent, ArgentaPdfDataHandlerComponent, ArgentaPdfDownloadComponent, AutofocusDirective, BadgeComponent, BasicRegistrationComponent, ButtonClasses, ButtonComponent, CalendarArgentaComponent, CardComponent, CepMaskDirective, CheckboxComponent, CnpjMaskDirective, CodeHighlightComponent, ComponentsModule, ConfirmationComponent, ConfirmationService, CpfMaskDirective, CsvImporterComponent, CustomPaginationComponent, CustomSwitchComponent, DataExcelExporterComponent, DataExcelImporterComponent, DataPaginateService, DataTableComponent, DragDropListComponent, DynamicModalComponent, DynamicTableComponent, FileUploadComponent, InputComponent, JsonViewerComponent, LibPortalAngularModule, LucideIconsModule, ModalComponent, MultiSelectCategoryComponent, MultiSelectComponent, NotificationService, RadioComponent, RefreshService, RouterParameterService, SearchCustomerComponent, SearchInputComponent, SelectComponent, TabComponent, TextareaComponent, TreeNodeComponent, convertToSnakeCase, setThemeColors };
|
3991
4662
|
//# sourceMappingURL=lib-portal-angular.mjs.map
|