@senior-gestao-relacionamento/angular-components 2.5.0-master-5861fa25 → 2.6.0

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.
@@ -363,7 +363,22 @@ var ptBR = {
363
363
  "crmx.components.chatbot_typing_2": "Analisando sua pergunta...",
364
364
  "crmx.components.chatbot_typing_3": "Reunindo informações...",
365
365
  "crmx.components.chatbot_typing_4": "Quase pronto!",
366
- "crmx.components.chatbot_typing_5": "Finalizando a resposta..."
366
+ "crmx.components.chatbot_typing_5": "Finalizando a resposta...",
367
+ "crmx.components.export_title": "Exportar Dados",
368
+ "crmx.components.export_file_format": "Formato do arquivo",
369
+ "crmx.components.export_orientation": "Orientação da página",
370
+ "crmx.components.export_sheet_format": "Formato da folha",
371
+ "crmx.components.export_scope": "Escopo da exportação",
372
+ "crmx.components.export_scope_all": "Todos os registros",
373
+ "crmx.components.export_scope_all_desc": "Exporta todos com o filtro ativo",
374
+ "crmx.components.export_scope_selected": "Registros selecionados",
375
+ "crmx.components.export_scope_selected_desc": "Exporta apenas os itens marcados",
376
+ "crmx.components.export_records_selected": "{{count}} registro(s) selecionado(s)",
377
+ "crmx.components.export_columns": "Colunas",
378
+ "crmx.components.export_columns_all": "Todas",
379
+ "crmx.components.export_columns_none": "Nenhuma",
380
+ "crmx.components.export_columns_summary": "{{selected}} de {{total}} colunas selecionadas",
381
+ "crmx.components.export_button": "Exportar"
367
382
  };
368
383
 
369
384
  var enUS = {
@@ -474,7 +489,22 @@ var enUS = {
474
489
  "crmx.components.chatbot_typing_2": "Analyzing your question...",
475
490
  "crmx.components.chatbot_typing_3": "Gathering information...",
476
491
  "crmx.components.chatbot_typing_4": "Almost there!",
477
- "crmx.components.chatbot_typing_5": "Wrapping up the answer..."
492
+ "crmx.components.chatbot_typing_5": "Wrapping up the answer...",
493
+ "crmx.components.export_title": "Export Data",
494
+ "crmx.components.export_file_format": "File format",
495
+ "crmx.components.export_orientation": "Page orientation",
496
+ "crmx.components.export_sheet_format": "Sheet format",
497
+ "crmx.components.export_scope": "Export scope",
498
+ "crmx.components.export_scope_all": "All records",
499
+ "crmx.components.export_scope_all_desc": "Exports all records with the active filter",
500
+ "crmx.components.export_scope_selected": "Selected records",
501
+ "crmx.components.export_scope_selected_desc": "Exports only the checked items",
502
+ "crmx.components.export_records_selected": "{{count}} record(s) selected",
503
+ "crmx.components.export_columns": "Columns",
504
+ "crmx.components.export_columns_all": "All",
505
+ "crmx.components.export_columns_none": "None",
506
+ "crmx.components.export_columns_summary": "{{selected}} of {{total}} columns selected",
507
+ "crmx.components.export_button": "Export"
478
508
  };
479
509
 
480
510
  var esES = {
@@ -585,7 +615,22 @@ var esES = {
585
615
  "crmx.components.chatbot_typing_2": "Analizando tu pregunta...",
586
616
  "crmx.components.chatbot_typing_3": "Reuniendo información...",
587
617
  "crmx.components.chatbot_typing_4": "¡Casi listo!",
588
- "crmx.components.chatbot_typing_5": "Finalizando la respuesta..."
618
+ "crmx.components.chatbot_typing_5": "Finalizando la respuesta...",
619
+ "crmx.components.export_title": "Exportar Datos",
620
+ "crmx.components.export_file_format": "Formato de archivo",
621
+ "crmx.components.export_orientation": "Orientación de página",
622
+ "crmx.components.export_sheet_format": "Formato de hoja",
623
+ "crmx.components.export_scope": "Alcance de exportación",
624
+ "crmx.components.export_scope_all": "Todos los registros",
625
+ "crmx.components.export_scope_all_desc": "Exporta todos con el filtro activo",
626
+ "crmx.components.export_scope_selected": "Registros seleccionados",
627
+ "crmx.components.export_scope_selected_desc": "Exporta solo los elementos marcados",
628
+ "crmx.components.export_records_selected": "{{count}} registro(s) seleccionado(s)",
629
+ "crmx.components.export_columns": "Columnas",
630
+ "crmx.components.export_columns_all": "Todas",
631
+ "crmx.components.export_columns_none": "Ninguna",
632
+ "crmx.components.export_columns_summary": "{{selected}} de {{total}} columnas seleccionadas",
633
+ "crmx.components.export_button": "Exportar"
589
634
  };
590
635
 
591
636
  const LIB_TRANSLATIONS = {
@@ -2027,11 +2072,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2027
2072
  type: Output
2028
2073
  }] } });
2029
2074
 
2075
+ var ExportFileType;
2076
+ (function (ExportFileType) {
2077
+ ExportFileType["Excel"] = "EXCEL";
2078
+ ExportFileType["Pdf"] = "PDF";
2079
+ })(ExportFileType || (ExportFileType = {}));
2080
+ var ExportOrientation;
2081
+ (function (ExportOrientation) {
2082
+ ExportOrientation["Portrait"] = "PORTRAIT";
2083
+ ExportOrientation["Landscape"] = "LANDSCAPE";
2084
+ })(ExportOrientation || (ExportOrientation = {}));
2085
+ var ExportFileFormat;
2086
+ (function (ExportFileFormat) {
2087
+ ExportFileFormat["A3"] = "A3";
2088
+ ExportFileFormat["A4"] = "A4";
2089
+ })(ExportFileFormat || (ExportFileFormat = {}));
2090
+ var ExportColumnType;
2091
+ (function (ExportColumnType) {
2092
+ ExportColumnType["Text"] = "TEXT";
2093
+ ExportColumnType["Enum"] = "ENUM";
2094
+ ExportColumnType["Date"] = "DATE";
2095
+ ExportColumnType["Datetime"] = "DATETIME";
2096
+ ExportColumnType["Currency"] = "CURRENCY";
2097
+ ExportColumnType["Number"] = "NUMBER";
2098
+ })(ExportColumnType || (ExportColumnType = {}));
2099
+
2030
2100
  /**
2031
2101
  * Serviço que dispara os signals de exportação no `crmx-data-export-backend`.
2032
2102
  *
2033
- * Os signals são fire-and-forget: o backend gera o arquivo, faz upload
2034
- * e notifica o usuário via WebSocket/notificação.
2103
+ * Os signals são fire-and-forget: o backend processa e gera o arquivo de forma assíncrona.
2035
2104
  */
2036
2105
  class ExportDataService {
2037
2106
  http;
@@ -2059,42 +2128,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2059
2128
  args: [{ providedIn: 'root' }]
2060
2129
  }], ctorParameters: () => [{ type: i1.HttpClient }] });
2061
2130
 
2062
- var ExportFileType;
2063
- (function (ExportFileType) {
2064
- ExportFileType["Excel"] = "EXCEL";
2065
- ExportFileType["Pdf"] = "PDF";
2066
- })(ExportFileType || (ExportFileType = {}));
2067
- var ExportOrientation;
2068
- (function (ExportOrientation) {
2069
- ExportOrientation["Portrait"] = "PORTRAIT";
2070
- ExportOrientation["Landscape"] = "LANDSCAPE";
2071
- })(ExportOrientation || (ExportOrientation = {}));
2072
- var ExportFileFormat;
2073
- (function (ExportFileFormat) {
2074
- ExportFileFormat["A3"] = "A3";
2075
- ExportFileFormat["A4"] = "A4";
2076
- })(ExportFileFormat || (ExportFileFormat = {}));
2077
- var ExportColumnType;
2078
- (function (ExportColumnType) {
2079
- ExportColumnType["Text"] = "TEXT";
2080
- ExportColumnType["Enum"] = "ENUM";
2081
- ExportColumnType["Date"] = "DATE";
2082
- ExportColumnType["Datetime"] = "DATETIME";
2083
- ExportColumnType["Currency"] = "CURRENCY";
2084
- ExportColumnType["Number"] = "NUMBER";
2085
- })(ExportColumnType || (ExportColumnType = {}));
2086
-
2131
+ /**
2132
+ * Componente de exportação de dados (s-export-data).
2133
+ * Permite ao usuário escolher o formato do arquivo (Excel ou PDF), a orientação da página,
2134
+ * o formato da folha, o escopo (todos os registros ou apenas os selecionados) e
2135
+ * as colunas a serem exportadas.
2136
+ *
2137
+ * Comunica-se com o `crmx-data-export-backend` via HTTP (fire-and-forget).
2138
+ */
2087
2139
  class ExportDataComponent {
2088
- exportService = inject(ExportDataService);
2089
- webSocketService = inject(WebSocketService);
2090
- ngZone = inject(NgZone);
2091
- wsSubscription = null;
2092
- wsConfig = {
2093
- domain: 'crmx',
2094
- service: 'dataexport',
2095
- primitive: 'wsExportCompleted',
2096
- userScoped: true
2097
- };
2140
+ exportDataService = inject(ExportDataService);
2098
2141
  visible = input(false);
2099
2142
  visibleChange = output();
2100
2143
  config = input.required();
@@ -2142,33 +2185,8 @@ class ExportDataComponent {
2142
2185
  this.columnSelections.set(cfg.columns.map(col => ({ column: this.normalizeColumn(col), selected: true })));
2143
2186
  }
2144
2187
  // Sincroniza escopo com presença de IDs
2145
- this.exportScope.set(this.selectedIds().length > 0 ? 'selected' : 'all');
2146
- // Subscribe ao WebSocket quando o dialog fica visível
2147
- if (this.visible() && !this.wsSubscription) {
2148
- this.subscribeToWebSocket();
2149
- }
2150
- }
2151
- ngOnDestroy() {
2152
- this.wsSubscription?.unsubscribe();
2153
- this.webSocketService.unsubscribe(this.wsConfig);
2154
- this.webSocketService.disconnect();
2155
- }
2156
- subscribeToWebSocket() {
2157
- this.wsSubscription = this.webSocketService
2158
- .subscribe(this.wsConfig)
2159
- .subscribe(msg => {
2160
- this.ngZone.run(() => {
2161
- const data = msg.body.data;
2162
- if (data?.success) {
2163
- this.exported.emit();
2164
- this.visibleChange.emit(false);
2165
- }
2166
- else {
2167
- this.exportError.emit(data?.entityName ?? '');
2168
- }
2169
- this.exporting.set(false);
2170
- });
2171
- });
2188
+ const scope = this.selectedIds().length > 0 ? 'selected' : 'all';
2189
+ this.exportScope.set(scope);
2172
2190
  }
2173
2191
  isExportColumn(col) {
2174
2192
  return 'columnName' in col && 'translateKey' in col && 'columnType' in col;
@@ -2208,252 +2226,47 @@ class ExportDataComponent {
2208
2226
  this.visibleChange.emit(false);
2209
2227
  }
2210
2228
  async doExport() {
2211
- this.exporting.set(true);
2212
- const cfg = this.config();
2213
- const selectedCols = this.columnSelections().filter(c => c.selected).map(c => c.column);
2229
+ const config = this.config();
2230
+ const columnsToExport = this.columnSelections()
2231
+ .filter(c => c.selected)
2232
+ .map(c => c.column);
2233
+ const basePayload = {
2234
+ fileType: this.selectedFileType(),
2235
+ datasource: config.datasource,
2236
+ fields: columnsToExport,
2237
+ entityName: config.entityName,
2238
+ ...(this.selectedFileType() === ExportFileType.Pdf && {
2239
+ orientation: this.selectedOrientation(),
2240
+ fileFormat: this.selectedFileFormat()
2241
+ })
2242
+ };
2214
2243
  try {
2215
- await this.exportViaBackend(cfg, selectedCols);
2216
- // O dialog permanece aberto com loading até o WebSocket notificar o resultado
2217
- }
2218
- catch (e) {
2219
- this.exporting.set(false);
2220
- this.exportError.emit(cfg.entityName);
2244
+ this.exporting.set(true);
2245
+ if (this.exportScope() === 'selected' && this.selectedIds().length > 0) {
2246
+ await this.exportDataService.exportSelectedRecords({
2247
+ ...basePayload,
2248
+ selectedIds: this.selectedIds()
2249
+ });
2250
+ }
2251
+ else {
2252
+ await this.exportDataService.exportAllRecords({
2253
+ ...basePayload,
2254
+ filter: config.activeFilter || ''
2255
+ });
2256
+ }
2257
+ this.exported.emit();
2258
+ this.visibleChange.emit(false);
2221
2259
  }
2222
- }
2223
- async exportViaBackend(cfg, columns) {
2224
- const fileType = this.selectedFileType();
2225
- const orientation = this.selectedOrientation();
2226
- const fileFormat = this.selectedFileFormat();
2227
- if (this.hasSelectedIds() && this.exportScope() === 'selected') {
2228
- await this.exportService.exportSelectedRecords({
2229
- datasource: cfg.datasource, fields: columns,
2230
- selectedIds: this.selectedIds(), entityName: cfg.entityName, fileType, orientation, fileFormat
2231
- });
2260
+ catch (err) {
2261
+ const errorMessage = err instanceof Error ? err.message : 'Erro ao iniciar exportação.';
2262
+ this.exportError.emit(errorMessage);
2232
2263
  }
2233
- else {
2234
- await this.exportService.exportAllRecords({
2235
- datasource: cfg.datasource, fields: columns,
2236
- filter: cfg.activeFilter ?? '', entityName: cfg.entityName, fileType, orientation, fileFormat
2237
- });
2264
+ finally {
2265
+ this.exporting.set(false);
2238
2266
  }
2239
2267
  }
2240
2268
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExportDataComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2241
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ExportDataComponent, isStandalone: true, selector: "s-export-data", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange", exported: "exported", exportError: "exportError" }, usesOnChanges: true, ngImport: i0, template: `
2242
- <p-dialog
2243
- [visible]="visible()"
2244
- (visibleChange)="visibleChange.emit($event)"
2245
- (onHide)="onDialogHide()"
2246
- [modal]="true"
2247
- [draggable]="false"
2248
- [resizable]="false"
2249
- [style]="{ width: '700px' }"
2250
- styleClass="s-export-dialog"
2251
- >
2252
- <ng-template pTemplate="header">
2253
- <div class="custom-header">
2254
- <i class="pi pi-download header-icon"></i>
2255
- <span>Exportar Dados</span>
2256
- </div>
2257
- </ng-template>
2258
-
2259
- <div class="export-content">
2260
-
2261
- <!-- Formato de Exportação -->
2262
- <div class="export-section">
2263
- <div class="section-header">
2264
- <div class="section-icon"><i class="pi pi-file"></i></div>
2265
- <h3>Formato do arquivo</h3>
2266
- </div>
2267
- <div class="format-options">
2268
- <div
2269
- *ngFor="let fmt of fileTypes"
2270
- class="format-card"
2271
- [class.selected]="selectedFileType() === fmt.value"
2272
- (click)="selectedFileType.set(fmt.value)"
2273
- >
2274
- <div class="card-radio">
2275
- <p-radioButton
2276
- [value]="fmt.value"
2277
- [(ngModel)]="selectedFileTypeModel"
2278
- [inputId]="'fmt_' + fmt.value"
2279
- ></p-radioButton>
2280
- </div>
2281
- <div class="card-icon" [class.excel]="fmt.value === 'EXCEL'" [class.pdf]="fmt.value === 'PDF'">
2282
- <i class="pi" [ngClass]="fmt.icon"></i>
2283
- </div>
2284
- <div class="card-info">
2285
- <label [for]="'fmt_' + fmt.value" class="card-label">{{ fmt.label }}</label>
2286
- <span class="card-description">{{ fmt.description }}</span>
2287
- </div>
2288
- </div>
2289
- </div>
2290
- </div>
2291
-
2292
- <!-- Orientação + Formato da folha (apenas PDF) -->
2293
- @if (selectedFileType() === 'PDF') {
2294
- <div class="export-section">
2295
- <div class="section-header">
2296
- <div class="section-icon"><i class="pi pi-arrows-alt"></i></div>
2297
- <h3>Orientação da página</h3>
2298
- </div>
2299
- <div class="format-options">
2300
- <div
2301
- *ngFor="let o of orientations"
2302
- class="format-card"
2303
- [class.selected]="selectedOrientation() === o.value"
2304
- (click)="selectedOrientation.set(o.value)"
2305
- >
2306
- <div class="card-radio">
2307
- <p-radioButton
2308
- [value]="o.value"
2309
- [(ngModel)]="selectedOrientationModel"
2310
- [inputId]="'orient_' + o.value"
2311
- ></p-radioButton>
2312
- </div>
2313
- <div class="card-icon">
2314
- <i class="pi" [ngClass]="o.icon"></i>
2315
- </div>
2316
- <div class="card-info">
2317
- <label [for]="'orient_' + o.value" class="card-label">{{ o.label }}</label>
2318
- </div>
2319
- </div>
2320
- </div>
2321
- </div>
2322
-
2323
- <div class="export-section">
2324
- <div class="section-header">
2325
- <div class="section-icon"><i class="pi pi-stop"></i></div>
2326
- <h3>Formato da folha</h3>
2327
- </div>
2328
- <div class="format-options">
2329
- <div
2330
- *ngFor="let f of fileFormats"
2331
- class="format-card"
2332
- [class.selected]="selectedFileFormat() === f.value"
2333
- (click)="selectedFileFormat.set(f.value)"
2334
- >
2335
- <div class="card-radio">
2336
- <p-radioButton
2337
- [value]="f.value"
2338
- [(ngModel)]="selectedFileFormatModel"
2339
- [inputId]="'format_' + f.value"
2340
- ></p-radioButton>
2341
- </div>
2342
- <div class="card-icon">
2343
- <i class="pi pi-file"></i>
2344
- </div>
2345
- <div class="card-info">
2346
- <label [for]="'format_' + f.value" class="card-label">{{ f.label }}</label>
2347
- <span class="card-description">{{ f.description }}</span>
2348
- </div>
2349
- </div>
2350
- </div>
2351
- </div>
2352
- }
2353
-
2354
- <!-- Escopo -->
2355
- <div class="export-section">
2356
- <div class="section-header">
2357
- <div class="section-icon"><i class="pi pi-filter"></i></div>
2358
- <h3>Escopo da exportação</h3>
2359
- </div>
2360
- <div class="scope-options">
2361
- <div
2362
- class="scope-card"
2363
- [class.selected]="!hasSelectedIds()"
2364
- (click)="exportScope.set('all')"
2365
- >
2366
- <div class="card-radio">
2367
- <p-radioButton value="all" [(ngModel)]="exportScopeModel" inputId="scope_all"></p-radioButton>
2368
- </div>
2369
- <div class="card-icon"><i class="pi pi-list"></i></div>
2370
- <div class="card-info">
2371
- <label for="scope_all" class="card-label">Todos os registros</label>
2372
- <span class="card-description">Exporta todos com o filtro ativo</span>
2373
- </div>
2374
- </div>
2375
- <div
2376
- class="scope-card"
2377
- [class.selected]="hasSelectedIds()"
2378
- [class.disabled]="!hasSelectedIds()"
2379
- (click)="hasSelectedIds() ? exportScope.set('selected') : null"
2380
- >
2381
- <div class="card-radio">
2382
- <p-radioButton
2383
- value="selected"
2384
- [(ngModel)]="exportScopeModel"
2385
- inputId="scope_selected"
2386
- [disabled]="!hasSelectedIds()"
2387
- ></p-radioButton>
2388
- </div>
2389
- <div class="card-icon"><i class="pi pi-check-square"></i></div>
2390
- <div class="card-info">
2391
- <label for="scope_selected" class="card-label">Registros selecionados</label>
2392
- <span class="card-description">Exporta apenas os itens marcados</span>
2393
- <span class="card-count">
2394
- <i class="pi pi-circle-fill"></i>
2395
- {{ selectedIds().length }} registro(s) selecionado(s)
2396
- </span>
2397
- </div>
2398
- </div>
2399
- </div>
2400
- </div>
2401
-
2402
- <!-- Seleção de Colunas -->
2403
- <div class="export-section">
2404
- <div class="section-header">
2405
- <div class="section-icon"><i class="pi pi-table"></i></div>
2406
- <h3>Colunas</h3>
2407
- <div class="column-actions">
2408
- <button type="button" class="action-link" (click)="selectAllColumns()">Todas</button>
2409
- <span class="separator">|</span>
2410
- <button type="button" class="action-link" (click)="deselectAllColumns()">Nenhuma</button>
2411
- </div>
2412
- </div>
2413
- <div class="columns-grid">
2414
- <div
2415
- *ngFor="let col of columnSelections()"
2416
- class="column-item"
2417
- [class.selected]="col.selected"
2418
- (click)="toggleColumn(col)"
2419
- >
2420
- <p-checkbox
2421
- [(ngModel)]="col.selected"
2422
- [binary]="true"
2423
- [inputId]="'col_' + col.column.columnName"
2424
- (onChange)="refreshColumns()"
2425
- ></p-checkbox>
2426
- <label [for]="'col_' + col.column.columnName" class="column-label">
2427
- {{ col.column.translateKey }}
2428
- </label>
2429
- </div>
2430
- </div>
2431
- <div class="columns-summary">
2432
- <i class="pi pi-info-circle"></i>
2433
- <span>{{ selectedColumnsCount() }} de {{ columnSelections().length }} colunas selecionadas</span>
2434
- </div>
2435
- </div>
2436
-
2437
- </div>
2438
-
2439
- <ng-template pTemplate="footer">
2440
- <p-button
2441
- label="Cancelar"
2442
- icon="pi pi-times"
2443
- severity="secondary"
2444
- [text]="true"
2445
- (onClick)="onDialogHide()"
2446
- />
2447
- <p-button
2448
- label="Exportar"
2449
- icon="pi pi-download"
2450
- [disabled]="!canExport()"
2451
- [loading]="exporting()"
2452
- (onClick)="doExport()"
2453
- />
2454
- </ng-template>
2455
- </p-dialog>
2456
- `, isInline: true, styles: ["::ng-deep .s-export-dialog .p-dialog{border-radius:16px;overflow:hidden;box-shadow:0 20px 60px #0000004d}::ng-deep .s-export-dialog .p-dialog-content{padding:0;background:#fff;max-height:70vh;overflow-y:auto}::ng-deep .s-export-dialog .p-dialog-footer{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:16px 32px}.custom-header{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:600}.custom-header .header-icon{font-size:22px;color:var(--p-primary-500)}.export-content{padding:28px 32px}.export-section{margin-bottom:32px}.export-section:last-child{margin-bottom:0}.section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}.section-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.1),rgba(var(--p-primary-rgb),.15));border-radius:10px}.section-icon i{font-size:18px;color:var(--p-primary-500)}.section-header h3{margin:0;font-size:17px;font-weight:700;color:var(--neutral-color-800, #1f2937);flex:1}.column-actions{display:flex;align-items:center;gap:10px;font-size:13px}.action-link{background:none;border:none;color:var(--p-primary-500);cursor:pointer;font-weight:600;padding:0;transition:all .2s;font-size:13px}.separator{color:var(--neutral-color-300, #d1d5db)}.format-options{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}.format-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.format-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.format-card:hover{border-color:var(--p-primary-500);transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--p-primary-rgb),.15)}.format-card:hover:before{opacity:1}.format-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.format-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.format-card.selected .card-icon i{color:#fff}.card-icon{width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:12px;transition:all .3s;position:relative;z-index:1;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon.excel{background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon.excel i{color:#107c41;font-size:26px}.card-icon.pdf{background:linear-gradient(135deg,#fee8e8,#fdd4d4)}.card-icon.pdf i{color:#dc2626;font-size:26px}.card-icon i{font-size:22px;color:var(--p-primary-500)}.card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0}.card-description{font-size:13px;color:var(--neutral-color-600, #4b5563);line-height:1.4}.scope-options{display:flex;flex-direction:column;gap:14px}.scope-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.scope-card:hover:not(.disabled){border-color:var(--p-primary-500);box-shadow:0 4px 16px rgba(var(--p-primary-rgb),.12)}.scope-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.scope-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.scope-card.selected .card-icon i{color:#fff}.scope-card.disabled{opacity:.5;cursor:not-allowed;background:#f9fafb}.card-count{font-size:13px;font-weight:600;color:var(--p-primary-500);margin-top:6px;display:inline-flex;align-items:center;gap:6px}.card-count i{font-size:6px}.columns-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}.column-item{display:flex;align-items:center;gap:12px;padding:16px;border:2px solid #e5e7eb;border-radius:10px;transition:all .2s;background:#fff;cursor:pointer}.column-item:hover{border-color:var(--p-primary-500);background:rgba(var(--p-primary-rgb),.03)}.column-item.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08))}.column-label{font-size:14px;font-weight:600;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0;-webkit-user-select:none;user-select:none}.columns-summary{display:flex;align-items:center;gap:10px;padding:14px 18px;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%);border-radius:10px;font-size:14px;color:var(--neutral-color-700, #374151);font-weight:600}.columns-summary i{color:var(--p-primary-500);font-size:18px}@media (max-width: 768px){::ng-deep .s-export-dialog .p-dialog{width:95vw!important;margin:0}.export-content{padding:24px}.format-options,.columns-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i6.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i7$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }] });
2269
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ExportDataComponent, isStandalone: true, selector: "s-export-data", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visibleChange: "visibleChange", exported: "exported", exportError: "exportError" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visibleChange.emit($event)\"\n (onHide)=\"onDialogHide()\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n styleClass=\"s-export-dialog s-export-dialog-width\"\n>\n <ng-template pTemplate=\"header\">\n <div class=\"custom-header\">\n <i class=\"pi pi-download header-icon\"></i>\n <span>{{ 'crmx.components.export_title' | translate }}</span>\n </div>\n </ng-template>\n\n <div class=\"export-content\">\n\n <!-- Formato de Exporta\u00E7\u00E3o -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-file\"></i></div>\n <h3>{{ 'crmx.components.export_file_format' | translate }}</h3>\n </div>\n <div class=\"format-options\" role=\"radiogroup\">\n <label\n *ngFor=\"let fmt of fileTypes\"\n class=\"format-card\"\n [class.selected]=\"selectedFileType() === fmt.value\"\n [for]=\"'fmt_' + fmt.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"fmt.value\"\n [(ngModel)]=\"selectedFileTypeModel\"\n [inputId]=\"'fmt_' + fmt.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\" [class.excel]=\"fmt.value === 'EXCEL'\" [class.pdf]=\"fmt.value === 'PDF'\">\n <i class=\"pi\" [ngClass]=\"fmt.icon\"></i>\n </div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ fmt.label }}</span>\n <span class=\"card-description\">{{ fmt.description }}</span>\n </div>\n </label>\n </div>\n </div>\n\n <!-- Orienta\u00E7\u00E3o + Formato da folha (apenas PDF) -->\n @if (selectedFileType() === 'PDF') {\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-arrows-alt\"></i></div>\n <h3>{{ 'crmx.components.export_orientation' | translate }}</h3>\n </div>\n <div class=\"format-options\" role=\"radiogroup\">\n <label\n *ngFor=\"let o of orientations\"\n class=\"format-card\"\n [class.selected]=\"selectedOrientation() === o.value\"\n [for]=\"'orient_' + o.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"o.value\"\n [(ngModel)]=\"selectedOrientationModel\"\n [inputId]=\"'orient_' + o.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\">\n <i class=\"pi\" [ngClass]=\"o.icon\"></i>\n </div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ o.label }}</span>\n </div>\n </label>\n </div>\n </div>\n\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-stop\"></i></div>\n <h3>{{ 'crmx.components.export_sheet_format' | translate }}</h3>\n </div>\n <div class=\"format-options\" role=\"radiogroup\">\n <label\n *ngFor=\"let f of fileFormats\"\n class=\"format-card\"\n [class.selected]=\"selectedFileFormat() === f.value\"\n [for]=\"'format_' + f.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"f.value\"\n [(ngModel)]=\"selectedFileFormatModel\"\n [inputId]=\"'format_' + f.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\">\n <i class=\"pi pi-file\"></i>\n </div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ f.label }}</span>\n <span class=\"card-description\">{{ f.description }}</span>\n </div>\n </label>\n </div>\n </div>\n }\n\n <!-- Escopo -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-filter\"></i></div>\n <h3>{{ 'crmx.components.export_scope' | translate }}</h3>\n </div>\n <div class=\"scope-options\" role=\"radiogroup\">\n <label\n class=\"scope-card\"\n [class.selected]=\"!hasSelectedIds()\"\n for=\"scope_all\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n value=\"all\"\n [(ngModel)]=\"exportScopeModel\"\n inputId=\"scope_all\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\"><i class=\"pi pi-list\"></i></div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ 'crmx.components.export_scope_all' | translate }}</span>\n <span class=\"card-description\">{{ 'crmx.components.export_scope_all_desc' | translate }}</span>\n </div>\n </label>\n <label\n class=\"scope-card\"\n [class.selected]=\"hasSelectedIds()\"\n [class.disabled]=\"!hasSelectedIds()\"\n for=\"scope_selected\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n value=\"selected\"\n [(ngModel)]=\"exportScopeModel\"\n inputId=\"scope_selected\"\n [disabled]=\"!hasSelectedIds()\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\"><i class=\"pi pi-check-square\"></i></div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ 'crmx.components.export_scope_selected' | translate }}</span>\n <span class=\"card-description\">{{ 'crmx.components.export_scope_selected_desc' | translate }}</span>\n <span class=\"card-count\">\n <i class=\"pi pi-circle-fill\"></i>\n {{ 'crmx.components.export_records_selected' | translate:{ count: selectedIds().length } }}\n </span>\n </div>\n </label>\n </div>\n </div>\n\n <!-- Sele\u00E7\u00E3o de Colunas -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-table\"></i></div>\n <h3>{{ 'crmx.components.export_columns' | translate }}</h3>\n <div class=\"column-actions\">\n <button type=\"button\" class=\"action-link\" (click)=\"selectAllColumns()\">\n {{ 'crmx.components.export_columns_all' | translate }}\n </button>\n <span class=\"separator\">|</span>\n <button type=\"button\" class=\"action-link\" (click)=\"deselectAllColumns()\">\n {{ 'crmx.components.export_columns_none' | translate }}\n </button>\n </div>\n </div>\n <div class=\"columns-grid\">\n <label\n *ngFor=\"let col of columnSelections()\"\n class=\"column-item\"\n [class.selected]=\"col.selected\"\n [for]=\"'col_' + col.column.columnName\"\n >\n <p-checkbox\n [(ngModel)]=\"col.selected\"\n [binary]=\"true\"\n [inputId]=\"'col_' + col.column.columnName\"\n (onChange)=\"refreshColumns()\"\n ></p-checkbox>\n <span class=\"column-label\">{{ col.column.translateKey | translate }}</span>\n </label>\n </div>\n <div class=\"columns-summary\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n {{\n 'crmx.components.export_columns_summary'\n | translate:{ selected: selectedColumnsCount(), total: columnSelections().length }\n }}\n </span>\n </div>\n </div>\n\n </div>\n\n <ng-template pTemplate=\"footer\">\n <p-button\n [label]=\"'crmx.components.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onDialogHide()\"\n />\n <p-button\n [label]=\"'crmx.components.export_button' | translate\"\n icon=\"pi pi-download\"\n [disabled]=\"!canExport()\"\n [loading]=\"exporting()\"\n (onClick)=\"doExport()\"\n />\n </ng-template>\n</p-dialog>\n", styles: ["::ng-deep .s-export-dialog .p-dialog{border-radius:16px;overflow:hidden;box-shadow:0 20px 60px #0000004d}::ng-deep .s-export-dialog-width .p-dialog{width:700px}::ng-deep .s-export-dialog .p-dialog-content{padding:0;background:#fff;max-height:70vh;overflow-y:auto}::ng-deep .s-export-dialog .p-dialog-footer{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:16px 32px}.custom-header{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:600}.custom-header .header-icon{font-size:22px;color:var(--p-primary-500)}.export-content{padding:28px 32px}.export-section{margin-bottom:32px}.export-section:last-child{margin-bottom:0}.section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}.section-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.1),rgba(var(--p-primary-rgb),.15));border-radius:10px}.section-icon i{font-size:18px;color:var(--p-primary-500)}.section-header h3{margin:0;font-size:17px;font-weight:700;color:var(--neutral-color-800, #1f2937);flex:1}.column-actions{display:flex;align-items:center;gap:10px;font-size:13px}.action-link{background:none;border:none;color:var(--p-primary-500);cursor:pointer;font-weight:600;padding:0;transition:all .2s;font-size:13px}.separator{color:var(--neutral-color-300, #d1d5db)}.format-options{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}.format-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.format-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.format-card:hover{border-color:var(--p-primary-500);transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--p-primary-rgb),.15)}.format-card:hover:before{opacity:1}.format-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.card-icon{width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:12px;transition:all .3s;position:relative;z-index:1;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon i{font-size:22px;color:var(--p-primary-500)}.card-count i{font-size:6px}.columns-summary i{color:var(--p-primary-500);font-size:18px}.card-icon.excel{background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon.excel i{color:#107c41;font-size:26px}.card-icon.pdf{background:linear-gradient(135deg,#fee8e8,#fdd4d4)}.card-icon.pdf i{color:#dc2626;font-size:26px}.format-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.format-card.selected .card-icon i{color:#fff}.card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0}.card-description{font-size:13px;color:var(--neutral-color-600, #4b5563);line-height:1.4}.scope-options{display:flex;flex-direction:column;gap:14px}.scope-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.scope-card:hover:not(.disabled){border-color:var(--p-primary-500);box-shadow:0 4px 16px rgba(var(--p-primary-rgb),.12)}.scope-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.card-count{font-size:13px;font-weight:600;color:var(--p-primary-500);margin-top:6px;display:inline-flex;align-items:center;gap:6px}.scope-card.disabled{opacity:.5;cursor:not-allowed;background:#f9fafb}.scope-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.scope-card.selected .card-icon i{color:#fff}.columns-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}.column-item{display:flex;align-items:center;gap:12px;padding:16px;border:2px solid #e5e7eb;border-radius:10px;transition:all .2s;background:#fff;cursor:pointer}.column-item:hover{border-color:var(--p-primary-500);background:rgba(var(--p-primary-rgb),.03)}.column-item.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08))}.column-label{font-size:14px;font-weight:600;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0;-webkit-user-select:none;user-select:none}.columns-summary{display:flex;align-items:center;gap:10px;padding:14px 18px;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%);border-radius:10px;font-size:14px;color:var(--neutral-color-700, #374151);font-weight:600}@media (max-width: 768px){::ng-deep .s-export-dialog .p-dialog{width:95vw!important;margin:0}.export-content{padding:24px}.format-options,.columns-grid{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i4.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "directive", type: i8.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i6.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i7$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
2457
2270
  }
2458
2271
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExportDataComponent, decorators: [{
2459
2272
  type: Component,
@@ -2463,223 +2276,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2463
2276
  DialogModule,
2464
2277
  ButtonModule,
2465
2278
  RadioButtonModule,
2466
- CheckboxModule
2467
- ], template: `
2468
- <p-dialog
2469
- [visible]="visible()"
2470
- (visibleChange)="visibleChange.emit($event)"
2471
- (onHide)="onDialogHide()"
2472
- [modal]="true"
2473
- [draggable]="false"
2474
- [resizable]="false"
2475
- [style]="{ width: '700px' }"
2476
- styleClass="s-export-dialog"
2477
- >
2478
- <ng-template pTemplate="header">
2479
- <div class="custom-header">
2480
- <i class="pi pi-download header-icon"></i>
2481
- <span>Exportar Dados</span>
2482
- </div>
2483
- </ng-template>
2484
-
2485
- <div class="export-content">
2486
-
2487
- <!-- Formato de Exportação -->
2488
- <div class="export-section">
2489
- <div class="section-header">
2490
- <div class="section-icon"><i class="pi pi-file"></i></div>
2491
- <h3>Formato do arquivo</h3>
2492
- </div>
2493
- <div class="format-options">
2494
- <div
2495
- *ngFor="let fmt of fileTypes"
2496
- class="format-card"
2497
- [class.selected]="selectedFileType() === fmt.value"
2498
- (click)="selectedFileType.set(fmt.value)"
2499
- >
2500
- <div class="card-radio">
2501
- <p-radioButton
2502
- [value]="fmt.value"
2503
- [(ngModel)]="selectedFileTypeModel"
2504
- [inputId]="'fmt_' + fmt.value"
2505
- ></p-radioButton>
2506
- </div>
2507
- <div class="card-icon" [class.excel]="fmt.value === 'EXCEL'" [class.pdf]="fmt.value === 'PDF'">
2508
- <i class="pi" [ngClass]="fmt.icon"></i>
2509
- </div>
2510
- <div class="card-info">
2511
- <label [for]="'fmt_' + fmt.value" class="card-label">{{ fmt.label }}</label>
2512
- <span class="card-description">{{ fmt.description }}</span>
2513
- </div>
2514
- </div>
2515
- </div>
2516
- </div>
2517
-
2518
- <!-- Orientação + Formato da folha (apenas PDF) -->
2519
- @if (selectedFileType() === 'PDF') {
2520
- <div class="export-section">
2521
- <div class="section-header">
2522
- <div class="section-icon"><i class="pi pi-arrows-alt"></i></div>
2523
- <h3>Orientação da página</h3>
2524
- </div>
2525
- <div class="format-options">
2526
- <div
2527
- *ngFor="let o of orientations"
2528
- class="format-card"
2529
- [class.selected]="selectedOrientation() === o.value"
2530
- (click)="selectedOrientation.set(o.value)"
2531
- >
2532
- <div class="card-radio">
2533
- <p-radioButton
2534
- [value]="o.value"
2535
- [(ngModel)]="selectedOrientationModel"
2536
- [inputId]="'orient_' + o.value"
2537
- ></p-radioButton>
2538
- </div>
2539
- <div class="card-icon">
2540
- <i class="pi" [ngClass]="o.icon"></i>
2541
- </div>
2542
- <div class="card-info">
2543
- <label [for]="'orient_' + o.value" class="card-label">{{ o.label }}</label>
2544
- </div>
2545
- </div>
2546
- </div>
2547
- </div>
2548
-
2549
- <div class="export-section">
2550
- <div class="section-header">
2551
- <div class="section-icon"><i class="pi pi-stop"></i></div>
2552
- <h3>Formato da folha</h3>
2553
- </div>
2554
- <div class="format-options">
2555
- <div
2556
- *ngFor="let f of fileFormats"
2557
- class="format-card"
2558
- [class.selected]="selectedFileFormat() === f.value"
2559
- (click)="selectedFileFormat.set(f.value)"
2560
- >
2561
- <div class="card-radio">
2562
- <p-radioButton
2563
- [value]="f.value"
2564
- [(ngModel)]="selectedFileFormatModel"
2565
- [inputId]="'format_' + f.value"
2566
- ></p-radioButton>
2567
- </div>
2568
- <div class="card-icon">
2569
- <i class="pi pi-file"></i>
2570
- </div>
2571
- <div class="card-info">
2572
- <label [for]="'format_' + f.value" class="card-label">{{ f.label }}</label>
2573
- <span class="card-description">{{ f.description }}</span>
2574
- </div>
2575
- </div>
2576
- </div>
2577
- </div>
2578
- }
2579
-
2580
- <!-- Escopo -->
2581
- <div class="export-section">
2582
- <div class="section-header">
2583
- <div class="section-icon"><i class="pi pi-filter"></i></div>
2584
- <h3>Escopo da exportação</h3>
2585
- </div>
2586
- <div class="scope-options">
2587
- <div
2588
- class="scope-card"
2589
- [class.selected]="!hasSelectedIds()"
2590
- (click)="exportScope.set('all')"
2591
- >
2592
- <div class="card-radio">
2593
- <p-radioButton value="all" [(ngModel)]="exportScopeModel" inputId="scope_all"></p-radioButton>
2594
- </div>
2595
- <div class="card-icon"><i class="pi pi-list"></i></div>
2596
- <div class="card-info">
2597
- <label for="scope_all" class="card-label">Todos os registros</label>
2598
- <span class="card-description">Exporta todos com o filtro ativo</span>
2599
- </div>
2600
- </div>
2601
- <div
2602
- class="scope-card"
2603
- [class.selected]="hasSelectedIds()"
2604
- [class.disabled]="!hasSelectedIds()"
2605
- (click)="hasSelectedIds() ? exportScope.set('selected') : null"
2606
- >
2607
- <div class="card-radio">
2608
- <p-radioButton
2609
- value="selected"
2610
- [(ngModel)]="exportScopeModel"
2611
- inputId="scope_selected"
2612
- [disabled]="!hasSelectedIds()"
2613
- ></p-radioButton>
2614
- </div>
2615
- <div class="card-icon"><i class="pi pi-check-square"></i></div>
2616
- <div class="card-info">
2617
- <label for="scope_selected" class="card-label">Registros selecionados</label>
2618
- <span class="card-description">Exporta apenas os itens marcados</span>
2619
- <span class="card-count">
2620
- <i class="pi pi-circle-fill"></i>
2621
- {{ selectedIds().length }} registro(s) selecionado(s)
2622
- </span>
2623
- </div>
2624
- </div>
2625
- </div>
2626
- </div>
2627
-
2628
- <!-- Seleção de Colunas -->
2629
- <div class="export-section">
2630
- <div class="section-header">
2631
- <div class="section-icon"><i class="pi pi-table"></i></div>
2632
- <h3>Colunas</h3>
2633
- <div class="column-actions">
2634
- <button type="button" class="action-link" (click)="selectAllColumns()">Todas</button>
2635
- <span class="separator">|</span>
2636
- <button type="button" class="action-link" (click)="deselectAllColumns()">Nenhuma</button>
2637
- </div>
2638
- </div>
2639
- <div class="columns-grid">
2640
- <div
2641
- *ngFor="let col of columnSelections()"
2642
- class="column-item"
2643
- [class.selected]="col.selected"
2644
- (click)="toggleColumn(col)"
2645
- >
2646
- <p-checkbox
2647
- [(ngModel)]="col.selected"
2648
- [binary]="true"
2649
- [inputId]="'col_' + col.column.columnName"
2650
- (onChange)="refreshColumns()"
2651
- ></p-checkbox>
2652
- <label [for]="'col_' + col.column.columnName" class="column-label">
2653
- {{ col.column.translateKey }}
2654
- </label>
2655
- </div>
2656
- </div>
2657
- <div class="columns-summary">
2658
- <i class="pi pi-info-circle"></i>
2659
- <span>{{ selectedColumnsCount() }} de {{ columnSelections().length }} colunas selecionadas</span>
2660
- </div>
2661
- </div>
2662
-
2663
- </div>
2664
-
2665
- <ng-template pTemplate="footer">
2666
- <p-button
2667
- label="Cancelar"
2668
- icon="pi pi-times"
2669
- severity="secondary"
2670
- [text]="true"
2671
- (onClick)="onDialogHide()"
2672
- />
2673
- <p-button
2674
- label="Exportar"
2675
- icon="pi pi-download"
2676
- [disabled]="!canExport()"
2677
- [loading]="exporting()"
2678
- (onClick)="doExport()"
2679
- />
2680
- </ng-template>
2681
- </p-dialog>
2682
- `, styles: ["::ng-deep .s-export-dialog .p-dialog{border-radius:16px;overflow:hidden;box-shadow:0 20px 60px #0000004d}::ng-deep .s-export-dialog .p-dialog-content{padding:0;background:#fff;max-height:70vh;overflow-y:auto}::ng-deep .s-export-dialog .p-dialog-footer{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:16px 32px}.custom-header{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:600}.custom-header .header-icon{font-size:22px;color:var(--p-primary-500)}.export-content{padding:28px 32px}.export-section{margin-bottom:32px}.export-section:last-child{margin-bottom:0}.section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}.section-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.1),rgba(var(--p-primary-rgb),.15));border-radius:10px}.section-icon i{font-size:18px;color:var(--p-primary-500)}.section-header h3{margin:0;font-size:17px;font-weight:700;color:var(--neutral-color-800, #1f2937);flex:1}.column-actions{display:flex;align-items:center;gap:10px;font-size:13px}.action-link{background:none;border:none;color:var(--p-primary-500);cursor:pointer;font-weight:600;padding:0;transition:all .2s;font-size:13px}.separator{color:var(--neutral-color-300, #d1d5db)}.format-options{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}.format-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.format-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.format-card:hover{border-color:var(--p-primary-500);transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--p-primary-rgb),.15)}.format-card:hover:before{opacity:1}.format-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.format-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.format-card.selected .card-icon i{color:#fff}.card-icon{width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:12px;transition:all .3s;position:relative;z-index:1;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon.excel{background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon.excel i{color:#107c41;font-size:26px}.card-icon.pdf{background:linear-gradient(135deg,#fee8e8,#fdd4d4)}.card-icon.pdf i{color:#dc2626;font-size:26px}.card-icon i{font-size:22px;color:var(--p-primary-500)}.card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0}.card-description{font-size:13px;color:var(--neutral-color-600, #4b5563);line-height:1.4}.scope-options{display:flex;flex-direction:column;gap:14px}.scope-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.scope-card:hover:not(.disabled){border-color:var(--p-primary-500);box-shadow:0 4px 16px rgba(var(--p-primary-rgb),.12)}.scope-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.scope-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.scope-card.selected .card-icon i{color:#fff}.scope-card.disabled{opacity:.5;cursor:not-allowed;background:#f9fafb}.card-count{font-size:13px;font-weight:600;color:var(--p-primary-500);margin-top:6px;display:inline-flex;align-items:center;gap:6px}.card-count i{font-size:6px}.columns-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}.column-item{display:flex;align-items:center;gap:12px;padding:16px;border:2px solid #e5e7eb;border-radius:10px;transition:all .2s;background:#fff;cursor:pointer}.column-item:hover{border-color:var(--p-primary-500);background:rgba(var(--p-primary-rgb),.03)}.column-item.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08))}.column-label{font-size:14px;font-weight:600;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0;-webkit-user-select:none;user-select:none}.columns-summary{display:flex;align-items:center;gap:10px;padding:14px 18px;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%);border-radius:10px;font-size:14px;color:var(--neutral-color-700, #374151);font-weight:600}.columns-summary i{color:var(--p-primary-500);font-size:18px}@media (max-width: 768px){::ng-deep .s-export-dialog .p-dialog{width:95vw!important;margin:0}.export-content{padding:24px}.format-options,.columns-grid{grid-template-columns:1fr}}\n"] }]
2279
+ CheckboxModule,
2280
+ TranslatePipe
2281
+ ], template: "<p-dialog\n [visible]=\"visible()\"\n (visibleChange)=\"visibleChange.emit($event)\"\n (onHide)=\"onDialogHide()\"\n [modal]=\"true\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n styleClass=\"s-export-dialog s-export-dialog-width\"\n>\n <ng-template pTemplate=\"header\">\n <div class=\"custom-header\">\n <i class=\"pi pi-download header-icon\"></i>\n <span>{{ 'crmx.components.export_title' | translate }}</span>\n </div>\n </ng-template>\n\n <div class=\"export-content\">\n\n <!-- Formato de Exporta\u00E7\u00E3o -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-file\"></i></div>\n <h3>{{ 'crmx.components.export_file_format' | translate }}</h3>\n </div>\n <div class=\"format-options\" role=\"radiogroup\">\n <label\n *ngFor=\"let fmt of fileTypes\"\n class=\"format-card\"\n [class.selected]=\"selectedFileType() === fmt.value\"\n [for]=\"'fmt_' + fmt.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"fmt.value\"\n [(ngModel)]=\"selectedFileTypeModel\"\n [inputId]=\"'fmt_' + fmt.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\" [class.excel]=\"fmt.value === 'EXCEL'\" [class.pdf]=\"fmt.value === 'PDF'\">\n <i class=\"pi\" [ngClass]=\"fmt.icon\"></i>\n </div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ fmt.label }}</span>\n <span class=\"card-description\">{{ fmt.description }}</span>\n </div>\n </label>\n </div>\n </div>\n\n <!-- Orienta\u00E7\u00E3o + Formato da folha (apenas PDF) -->\n @if (selectedFileType() === 'PDF') {\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-arrows-alt\"></i></div>\n <h3>{{ 'crmx.components.export_orientation' | translate }}</h3>\n </div>\n <div class=\"format-options\" role=\"radiogroup\">\n <label\n *ngFor=\"let o of orientations\"\n class=\"format-card\"\n [class.selected]=\"selectedOrientation() === o.value\"\n [for]=\"'orient_' + o.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"o.value\"\n [(ngModel)]=\"selectedOrientationModel\"\n [inputId]=\"'orient_' + o.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\">\n <i class=\"pi\" [ngClass]=\"o.icon\"></i>\n </div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ o.label }}</span>\n </div>\n </label>\n </div>\n </div>\n\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-stop\"></i></div>\n <h3>{{ 'crmx.components.export_sheet_format' | translate }}</h3>\n </div>\n <div class=\"format-options\" role=\"radiogroup\">\n <label\n *ngFor=\"let f of fileFormats\"\n class=\"format-card\"\n [class.selected]=\"selectedFileFormat() === f.value\"\n [for]=\"'format_' + f.value\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n [value]=\"f.value\"\n [(ngModel)]=\"selectedFileFormatModel\"\n [inputId]=\"'format_' + f.value\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\">\n <i class=\"pi pi-file\"></i>\n </div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ f.label }}</span>\n <span class=\"card-description\">{{ f.description }}</span>\n </div>\n </label>\n </div>\n </div>\n }\n\n <!-- Escopo -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-filter\"></i></div>\n <h3>{{ 'crmx.components.export_scope' | translate }}</h3>\n </div>\n <div class=\"scope-options\" role=\"radiogroup\">\n <label\n class=\"scope-card\"\n [class.selected]=\"!hasSelectedIds()\"\n for=\"scope_all\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n value=\"all\"\n [(ngModel)]=\"exportScopeModel\"\n inputId=\"scope_all\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\"><i class=\"pi pi-list\"></i></div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ 'crmx.components.export_scope_all' | translate }}</span>\n <span class=\"card-description\">{{ 'crmx.components.export_scope_all_desc' | translate }}</span>\n </div>\n </label>\n <label\n class=\"scope-card\"\n [class.selected]=\"hasSelectedIds()\"\n [class.disabled]=\"!hasSelectedIds()\"\n for=\"scope_selected\"\n >\n <div class=\"card-radio\">\n <p-radioButton\n value=\"selected\"\n [(ngModel)]=\"exportScopeModel\"\n inputId=\"scope_selected\"\n [disabled]=\"!hasSelectedIds()\"\n ></p-radioButton>\n </div>\n <div class=\"card-icon\"><i class=\"pi pi-check-square\"></i></div>\n <div class=\"card-info\">\n <span class=\"card-label\">{{ 'crmx.components.export_scope_selected' | translate }}</span>\n <span class=\"card-description\">{{ 'crmx.components.export_scope_selected_desc' | translate }}</span>\n <span class=\"card-count\">\n <i class=\"pi pi-circle-fill\"></i>\n {{ 'crmx.components.export_records_selected' | translate:{ count: selectedIds().length } }}\n </span>\n </div>\n </label>\n </div>\n </div>\n\n <!-- Sele\u00E7\u00E3o de Colunas -->\n <div class=\"export-section\">\n <div class=\"section-header\">\n <div class=\"section-icon\"><i class=\"pi pi-table\"></i></div>\n <h3>{{ 'crmx.components.export_columns' | translate }}</h3>\n <div class=\"column-actions\">\n <button type=\"button\" class=\"action-link\" (click)=\"selectAllColumns()\">\n {{ 'crmx.components.export_columns_all' | translate }}\n </button>\n <span class=\"separator\">|</span>\n <button type=\"button\" class=\"action-link\" (click)=\"deselectAllColumns()\">\n {{ 'crmx.components.export_columns_none' | translate }}\n </button>\n </div>\n </div>\n <div class=\"columns-grid\">\n <label\n *ngFor=\"let col of columnSelections()\"\n class=\"column-item\"\n [class.selected]=\"col.selected\"\n [for]=\"'col_' + col.column.columnName\"\n >\n <p-checkbox\n [(ngModel)]=\"col.selected\"\n [binary]=\"true\"\n [inputId]=\"'col_' + col.column.columnName\"\n (onChange)=\"refreshColumns()\"\n ></p-checkbox>\n <span class=\"column-label\">{{ col.column.translateKey | translate }}</span>\n </label>\n </div>\n <div class=\"columns-summary\">\n <i class=\"pi pi-info-circle\"></i>\n <span>\n {{\n 'crmx.components.export_columns_summary'\n | translate:{ selected: selectedColumnsCount(), total: columnSelections().length }\n }}\n </span>\n </div>\n </div>\n\n </div>\n\n <ng-template pTemplate=\"footer\">\n <p-button\n [label]=\"'crmx.components.cancel' | translate\"\n icon=\"pi pi-times\"\n severity=\"secondary\"\n [text]=\"true\"\n (onClick)=\"onDialogHide()\"\n />\n <p-button\n [label]=\"'crmx.components.export_button' | translate\"\n icon=\"pi pi-download\"\n [disabled]=\"!canExport()\"\n [loading]=\"exporting()\"\n (onClick)=\"doExport()\"\n />\n </ng-template>\n</p-dialog>\n", styles: ["::ng-deep .s-export-dialog .p-dialog{border-radius:16px;overflow:hidden;box-shadow:0 20px 60px #0000004d}::ng-deep .s-export-dialog-width .p-dialog{width:700px}::ng-deep .s-export-dialog .p-dialog-content{padding:0;background:#fff;max-height:70vh;overflow-y:auto}::ng-deep .s-export-dialog .p-dialog-footer{display:flex;justify-content:flex-end;align-items:center;gap:12px;padding:16px 32px}.custom-header{display:flex;align-items:center;gap:12px;font-size:18px;font-weight:600}.custom-header .header-icon{font-size:22px;color:var(--p-primary-500)}.export-content{padding:28px 32px}.export-section{margin-bottom:32px}.export-section:last-child{margin-bottom:0}.section-header{display:flex;align-items:center;gap:12px;margin-bottom:20px}.section-icon{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.1),rgba(var(--p-primary-rgb),.15));border-radius:10px}.section-icon i{font-size:18px;color:var(--p-primary-500)}.section-header h3{margin:0;font-size:17px;font-weight:700;color:var(--neutral-color-800, #1f2937);flex:1}.column-actions{display:flex;align-items:center;gap:10px;font-size:13px}.action-link{background:none;border:none;color:var(--p-primary-500);cursor:pointer;font-weight:600;padding:0;transition:all .2s;font-size:13px}.separator{color:var(--neutral-color-300, #d1d5db)}.format-options{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}.format-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.format-card:before{content:\"\";position:absolute;inset:0;background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.03),rgba(var(--p-primary-rgb),.06));opacity:0;transition:opacity .3s}.format-card:hover{border-color:var(--p-primary-500);transform:translateY(-2px);box-shadow:0 8px 24px rgba(var(--p-primary-rgb),.15)}.format-card:hover:before{opacity:1}.format-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.card-icon{width:52px;height:52px;display:flex;align-items:center;justify-content:center;border-radius:12px;transition:all .3s;position:relative;z-index:1;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon i{font-size:22px;color:var(--p-primary-500)}.card-count i{font-size:6px}.columns-summary i{color:var(--p-primary-500);font-size:18px}.card-icon.excel{background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%)}.card-icon.excel i{color:#107c41;font-size:26px}.card-icon.pdf{background:linear-gradient(135deg,#fee8e8,#fdd4d4)}.card-icon.pdf i{color:#dc2626;font-size:26px}.format-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.format-card.selected .card-icon i{color:#fff}.card-info{flex:1;display:flex;flex-direction:column;gap:4px;position:relative;z-index:1}.card-label{font-size:16px;font-weight:700;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0}.card-description{font-size:13px;color:var(--neutral-color-600, #4b5563);line-height:1.4}.scope-options{display:flex;flex-direction:column;gap:14px}.scope-card{display:flex;align-items:center;gap:16px;padding:20px;border:2px solid #e5e7eb;border-radius:12px;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);background:#fff;position:relative;overflow:hidden}.scope-card:hover:not(.disabled){border-color:var(--p-primary-500);box-shadow:0 4px 16px rgba(var(--p-primary-rgb),.12)}.scope-card.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08));box-shadow:0 0 0 4px rgba(var(--p-primary-rgb),.1)}.card-count{font-size:13px;font-weight:600;color:var(--p-primary-500);margin-top:6px;display:inline-flex;align-items:center;gap:6px}.scope-card.disabled{opacity:.5;cursor:not-allowed;background:#f9fafb}.scope-card.selected .card-icon{background:linear-gradient(135deg,var(--p-primary-500) 0%,var(--p-primary-500) 100%);transform:scale(1.05)}.scope-card.selected .card-icon i{color:#fff}.columns-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:16px}.column-item{display:flex;align-items:center;gap:12px;padding:16px;border:2px solid #e5e7eb;border-radius:10px;transition:all .2s;background:#fff;cursor:pointer}.column-item:hover{border-color:var(--p-primary-500);background:rgba(var(--p-primary-rgb),.03)}.column-item.selected{border-color:var(--p-primary-500);background:linear-gradient(135deg,rgba(var(--p-primary-rgb),.05),rgba(var(--p-primary-rgb),.08))}.column-label{font-size:14px;font-weight:600;color:var(--neutral-color-800, #1f2937);cursor:pointer;margin:0;-webkit-user-select:none;user-select:none}.columns-summary{display:flex;align-items:center;gap:10px;padding:14px 18px;background:linear-gradient(135deg,var(--p-primary-50, #f0fdf4) 0%,var(--p-primary-100, #dcfce7) 100%);border-radius:10px;font-size:14px;color:var(--neutral-color-700, #374151);font-weight:600}@media (max-width: 768px){::ng-deep .s-export-dialog .p-dialog{width:95vw!important;margin:0}.export-content{padding:24px}.format-options,.columns-grid{grid-template-columns:1fr}}\n"] }]
2683
2282
  }] });
2684
2283
 
2685
2284
  /*