@senior-gestao-relacionamento/angular-components 2.5.0 → 2.6.0-master-682f107e

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();
@@ -2131,38 +2174,19 @@ class ExportDataComponent {
2131
2174
  { value: ExportFileFormat.A3, label: 'A3', description: 'Grande (297×420mm)' }
2132
2175
  ];
2133
2176
  ngOnChanges() {
2134
- const cfg = this.config();
2177
+ let cfg;
2178
+ try {
2179
+ cfg = this.config();
2180
+ }
2181
+ catch {
2182
+ return; // config ainda não foi setado (required input)
2183
+ }
2135
2184
  if (cfg?.columns) {
2136
2185
  this.columnSelections.set(cfg.columns.map(col => ({ column: this.normalizeColumn(col), selected: true })));
2137
2186
  }
2138
2187
  // Sincroniza escopo com presença de IDs
2139
- this.exportScope.set(this.selectedIds().length > 0 ? 'selected' : 'all');
2140
- // Subscribe ao WebSocket quando o dialog fica visível
2141
- if (this.visible() && !this.wsSubscription) {
2142
- this.subscribeToWebSocket();
2143
- }
2144
- }
2145
- ngOnDestroy() {
2146
- this.wsSubscription?.unsubscribe();
2147
- this.webSocketService.unsubscribe(this.wsConfig);
2148
- this.webSocketService.disconnect();
2149
- }
2150
- subscribeToWebSocket() {
2151
- this.wsSubscription = this.webSocketService
2152
- .subscribe(this.wsConfig)
2153
- .subscribe(msg => {
2154
- this.ngZone.run(() => {
2155
- const data = msg.body.data;
2156
- if (data?.success) {
2157
- this.exported.emit();
2158
- this.visibleChange.emit(false);
2159
- }
2160
- else {
2161
- this.exportError.emit(data?.entityName ?? '');
2162
- }
2163
- this.exporting.set(false);
2164
- });
2165
- });
2188
+ const scope = this.selectedIds().length > 0 ? 'selected' : 'all';
2189
+ this.exportScope.set(scope);
2166
2190
  }
2167
2191
  isExportColumn(col) {
2168
2192
  return 'columnName' in col && 'translateKey' in col && 'columnType' in col;
@@ -2202,252 +2226,47 @@ class ExportDataComponent {
2202
2226
  this.visibleChange.emit(false);
2203
2227
  }
2204
2228
  async doExport() {
2205
- this.exporting.set(true);
2206
- const cfg = this.config();
2207
- 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
+ };
2208
2243
  try {
2209
- await this.exportViaBackend(cfg, selectedCols);
2210
- // O dialog permanece aberto com loading até o WebSocket notificar o resultado
2211
- }
2212
- catch (e) {
2213
- this.exporting.set(false);
2214
- 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);
2215
2259
  }
2216
- }
2217
- async exportViaBackend(cfg, columns) {
2218
- const fileType = this.selectedFileType();
2219
- const orientation = this.selectedOrientation();
2220
- const fileFormat = this.selectedFileFormat();
2221
- if (this.hasSelectedIds() && this.exportScope() === 'selected') {
2222
- await this.exportService.exportSelectedRecords({
2223
- datasource: cfg.datasource, fields: columns,
2224
- selectedIds: this.selectedIds(), entityName: cfg.entityName, fileType, orientation, fileFormat
2225
- });
2260
+ catch (err) {
2261
+ const errorMessage = err instanceof Error ? err.message : 'Erro ao iniciar exportação.';
2262
+ this.exportError.emit(errorMessage);
2226
2263
  }
2227
- else {
2228
- await this.exportService.exportAllRecords({
2229
- datasource: cfg.datasource, fields: columns,
2230
- filter: cfg.activeFilter ?? '', entityName: cfg.entityName, fileType, orientation, fileFormat
2231
- });
2264
+ finally {
2265
+ this.exporting.set(false);
2232
2266
  }
2233
2267
  }
2234
2268
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExportDataComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2235
- 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: `
2236
- <p-dialog
2237
- [visible]="visible()"
2238
- (visibleChange)="visibleChange.emit($event)"
2239
- (onHide)="onDialogHide()"
2240
- [modal]="true"
2241
- [draggable]="false"
2242
- [resizable]="false"
2243
- [style]="{ width: '700px' }"
2244
- styleClass="s-export-dialog"
2245
- >
2246
- <ng-template pTemplate="header">
2247
- <div class="custom-header">
2248
- <i class="pi pi-download header-icon"></i>
2249
- <span>Exportar Dados</span>
2250
- </div>
2251
- </ng-template>
2252
-
2253
- <div class="export-content">
2254
-
2255
- <!-- Formato de Exportação -->
2256
- <div class="export-section">
2257
- <div class="section-header">
2258
- <div class="section-icon"><i class="pi pi-file"></i></div>
2259
- <h3>Formato do arquivo</h3>
2260
- </div>
2261
- <div class="format-options">
2262
- <div
2263
- *ngFor="let fmt of fileTypes"
2264
- class="format-card"
2265
- [class.selected]="selectedFileType() === fmt.value"
2266
- (click)="selectedFileType.set(fmt.value)"
2267
- >
2268
- <div class="card-radio">
2269
- <p-radioButton
2270
- [value]="fmt.value"
2271
- [(ngModel)]="selectedFileTypeModel"
2272
- [inputId]="'fmt_' + fmt.value"
2273
- ></p-radioButton>
2274
- </div>
2275
- <div class="card-icon" [class.excel]="fmt.value === 'EXCEL'" [class.pdf]="fmt.value === 'PDF'">
2276
- <i class="pi" [ngClass]="fmt.icon"></i>
2277
- </div>
2278
- <div class="card-info">
2279
- <label [for]="'fmt_' + fmt.value" class="card-label">{{ fmt.label }}</label>
2280
- <span class="card-description">{{ fmt.description }}</span>
2281
- </div>
2282
- </div>
2283
- </div>
2284
- </div>
2285
-
2286
- <!-- Orientação + Formato da folha (apenas PDF) -->
2287
- @if (selectedFileType() === 'PDF') {
2288
- <div class="export-section">
2289
- <div class="section-header">
2290
- <div class="section-icon"><i class="pi pi-arrows-alt"></i></div>
2291
- <h3>Orientação da página</h3>
2292
- </div>
2293
- <div class="format-options">
2294
- <div
2295
- *ngFor="let o of orientations"
2296
- class="format-card"
2297
- [class.selected]="selectedOrientation() === o.value"
2298
- (click)="selectedOrientation.set(o.value)"
2299
- >
2300
- <div class="card-radio">
2301
- <p-radioButton
2302
- [value]="o.value"
2303
- [(ngModel)]="selectedOrientationModel"
2304
- [inputId]="'orient_' + o.value"
2305
- ></p-radioButton>
2306
- </div>
2307
- <div class="card-icon">
2308
- <i class="pi" [ngClass]="o.icon"></i>
2309
- </div>
2310
- <div class="card-info">
2311
- <label [for]="'orient_' + o.value" class="card-label">{{ o.label }}</label>
2312
- </div>
2313
- </div>
2314
- </div>
2315
- </div>
2316
-
2317
- <div class="export-section">
2318
- <div class="section-header">
2319
- <div class="section-icon"><i class="pi pi-stop"></i></div>
2320
- <h3>Formato da folha</h3>
2321
- </div>
2322
- <div class="format-options">
2323
- <div
2324
- *ngFor="let f of fileFormats"
2325
- class="format-card"
2326
- [class.selected]="selectedFileFormat() === f.value"
2327
- (click)="selectedFileFormat.set(f.value)"
2328
- >
2329
- <div class="card-radio">
2330
- <p-radioButton
2331
- [value]="f.value"
2332
- [(ngModel)]="selectedFileFormatModel"
2333
- [inputId]="'format_' + f.value"
2334
- ></p-radioButton>
2335
- </div>
2336
- <div class="card-icon">
2337
- <i class="pi pi-file"></i>
2338
- </div>
2339
- <div class="card-info">
2340
- <label [for]="'format_' + f.value" class="card-label">{{ f.label }}</label>
2341
- <span class="card-description">{{ f.description }}</span>
2342
- </div>
2343
- </div>
2344
- </div>
2345
- </div>
2346
- }
2347
-
2348
- <!-- Escopo -->
2349
- <div class="export-section">
2350
- <div class="section-header">
2351
- <div class="section-icon"><i class="pi pi-filter"></i></div>
2352
- <h3>Escopo da exportação</h3>
2353
- </div>
2354
- <div class="scope-options">
2355
- <div
2356
- class="scope-card"
2357
- [class.selected]="!hasSelectedIds()"
2358
- (click)="exportScope.set('all')"
2359
- >
2360
- <div class="card-radio">
2361
- <p-radioButton value="all" [(ngModel)]="exportScopeModel" inputId="scope_all"></p-radioButton>
2362
- </div>
2363
- <div class="card-icon"><i class="pi pi-list"></i></div>
2364
- <div class="card-info">
2365
- <label for="scope_all" class="card-label">Todos os registros</label>
2366
- <span class="card-description">Exporta todos com o filtro ativo</span>
2367
- </div>
2368
- </div>
2369
- <div
2370
- class="scope-card"
2371
- [class.selected]="hasSelectedIds()"
2372
- [class.disabled]="!hasSelectedIds()"
2373
- (click)="hasSelectedIds() ? exportScope.set('selected') : null"
2374
- >
2375
- <div class="card-radio">
2376
- <p-radioButton
2377
- value="selected"
2378
- [(ngModel)]="exportScopeModel"
2379
- inputId="scope_selected"
2380
- [disabled]="!hasSelectedIds()"
2381
- ></p-radioButton>
2382
- </div>
2383
- <div class="card-icon"><i class="pi pi-check-square"></i></div>
2384
- <div class="card-info">
2385
- <label for="scope_selected" class="card-label">Registros selecionados</label>
2386
- <span class="card-description">Exporta apenas os itens marcados</span>
2387
- <span class="card-count">
2388
- <i class="pi pi-circle-fill"></i>
2389
- {{ selectedIds().length }} registro(s) selecionado(s)
2390
- </span>
2391
- </div>
2392
- </div>
2393
- </div>
2394
- </div>
2395
-
2396
- <!-- Seleção de Colunas -->
2397
- <div class="export-section">
2398
- <div class="section-header">
2399
- <div class="section-icon"><i class="pi pi-table"></i></div>
2400
- <h3>Colunas</h3>
2401
- <div class="column-actions">
2402
- <button type="button" class="action-link" (click)="selectAllColumns()">Todas</button>
2403
- <span class="separator">|</span>
2404
- <button type="button" class="action-link" (click)="deselectAllColumns()">Nenhuma</button>
2405
- </div>
2406
- </div>
2407
- <div class="columns-grid">
2408
- <div
2409
- *ngFor="let col of columnSelections()"
2410
- class="column-item"
2411
- [class.selected]="col.selected"
2412
- (click)="toggleColumn(col)"
2413
- >
2414
- <p-checkbox
2415
- [(ngModel)]="col.selected"
2416
- [binary]="true"
2417
- [inputId]="'col_' + col.column.columnName"
2418
- (onChange)="refreshColumns()"
2419
- ></p-checkbox>
2420
- <label [for]="'col_' + col.column.columnName" class="column-label">
2421
- {{ col.column.translateKey }}
2422
- </label>
2423
- </div>
2424
- </div>
2425
- <div class="columns-summary">
2426
- <i class="pi pi-info-circle"></i>
2427
- <span>{{ selectedColumnsCount() }} de {{ columnSelections().length }} colunas selecionadas</span>
2428
- </div>
2429
- </div>
2430
-
2431
- </div>
2432
-
2433
- <ng-template pTemplate="footer">
2434
- <p-button
2435
- label="Cancelar"
2436
- icon="pi pi-times"
2437
- severity="secondary"
2438
- [text]="true"
2439
- (onClick)="onDialogHide()"
2440
- />
2441
- <p-button
2442
- label="Exportar"
2443
- icon="pi pi-download"
2444
- [disabled]="!canExport()"
2445
- [loading]="exporting()"
2446
- (onClick)="doExport()"
2447
- />
2448
- </ng-template>
2449
- </p-dialog>
2450
- `, 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-file\"></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]=\"exportScope() === 'all'\"\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]=\"exportScope() === 'selected'\"\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" }] });
2451
2270
  }
2452
2271
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ExportDataComponent, decorators: [{
2453
2272
  type: Component,
@@ -2457,223 +2276,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2457
2276
  DialogModule,
2458
2277
  ButtonModule,
2459
2278
  RadioButtonModule,
2460
- CheckboxModule
2461
- ], template: `
2462
- <p-dialog
2463
- [visible]="visible()"
2464
- (visibleChange)="visibleChange.emit($event)"
2465
- (onHide)="onDialogHide()"
2466
- [modal]="true"
2467
- [draggable]="false"
2468
- [resizable]="false"
2469
- [style]="{ width: '700px' }"
2470
- styleClass="s-export-dialog"
2471
- >
2472
- <ng-template pTemplate="header">
2473
- <div class="custom-header">
2474
- <i class="pi pi-download header-icon"></i>
2475
- <span>Exportar Dados</span>
2476
- </div>
2477
- </ng-template>
2478
-
2479
- <div class="export-content">
2480
-
2481
- <!-- Formato de Exportação -->
2482
- <div class="export-section">
2483
- <div class="section-header">
2484
- <div class="section-icon"><i class="pi pi-file"></i></div>
2485
- <h3>Formato do arquivo</h3>
2486
- </div>
2487
- <div class="format-options">
2488
- <div
2489
- *ngFor="let fmt of fileTypes"
2490
- class="format-card"
2491
- [class.selected]="selectedFileType() === fmt.value"
2492
- (click)="selectedFileType.set(fmt.value)"
2493
- >
2494
- <div class="card-radio">
2495
- <p-radioButton
2496
- [value]="fmt.value"
2497
- [(ngModel)]="selectedFileTypeModel"
2498
- [inputId]="'fmt_' + fmt.value"
2499
- ></p-radioButton>
2500
- </div>
2501
- <div class="card-icon" [class.excel]="fmt.value === 'EXCEL'" [class.pdf]="fmt.value === 'PDF'">
2502
- <i class="pi" [ngClass]="fmt.icon"></i>
2503
- </div>
2504
- <div class="card-info">
2505
- <label [for]="'fmt_' + fmt.value" class="card-label">{{ fmt.label }}</label>
2506
- <span class="card-description">{{ fmt.description }}</span>
2507
- </div>
2508
- </div>
2509
- </div>
2510
- </div>
2511
-
2512
- <!-- Orientação + Formato da folha (apenas PDF) -->
2513
- @if (selectedFileType() === 'PDF') {
2514
- <div class="export-section">
2515
- <div class="section-header">
2516
- <div class="section-icon"><i class="pi pi-arrows-alt"></i></div>
2517
- <h3>Orientação da página</h3>
2518
- </div>
2519
- <div class="format-options">
2520
- <div
2521
- *ngFor="let o of orientations"
2522
- class="format-card"
2523
- [class.selected]="selectedOrientation() === o.value"
2524
- (click)="selectedOrientation.set(o.value)"
2525
- >
2526
- <div class="card-radio">
2527
- <p-radioButton
2528
- [value]="o.value"
2529
- [(ngModel)]="selectedOrientationModel"
2530
- [inputId]="'orient_' + o.value"
2531
- ></p-radioButton>
2532
- </div>
2533
- <div class="card-icon">
2534
- <i class="pi" [ngClass]="o.icon"></i>
2535
- </div>
2536
- <div class="card-info">
2537
- <label [for]="'orient_' + o.value" class="card-label">{{ o.label }}</label>
2538
- </div>
2539
- </div>
2540
- </div>
2541
- </div>
2542
-
2543
- <div class="export-section">
2544
- <div class="section-header">
2545
- <div class="section-icon"><i class="pi pi-stop"></i></div>
2546
- <h3>Formato da folha</h3>
2547
- </div>
2548
- <div class="format-options">
2549
- <div
2550
- *ngFor="let f of fileFormats"
2551
- class="format-card"
2552
- [class.selected]="selectedFileFormat() === f.value"
2553
- (click)="selectedFileFormat.set(f.value)"
2554
- >
2555
- <div class="card-radio">
2556
- <p-radioButton
2557
- [value]="f.value"
2558
- [(ngModel)]="selectedFileFormatModel"
2559
- [inputId]="'format_' + f.value"
2560
- ></p-radioButton>
2561
- </div>
2562
- <div class="card-icon">
2563
- <i class="pi pi-file"></i>
2564
- </div>
2565
- <div class="card-info">
2566
- <label [for]="'format_' + f.value" class="card-label">{{ f.label }}</label>
2567
- <span class="card-description">{{ f.description }}</span>
2568
- </div>
2569
- </div>
2570
- </div>
2571
- </div>
2572
- }
2573
-
2574
- <!-- Escopo -->
2575
- <div class="export-section">
2576
- <div class="section-header">
2577
- <div class="section-icon"><i class="pi pi-filter"></i></div>
2578
- <h3>Escopo da exportação</h3>
2579
- </div>
2580
- <div class="scope-options">
2581
- <div
2582
- class="scope-card"
2583
- [class.selected]="!hasSelectedIds()"
2584
- (click)="exportScope.set('all')"
2585
- >
2586
- <div class="card-radio">
2587
- <p-radioButton value="all" [(ngModel)]="exportScopeModel" inputId="scope_all"></p-radioButton>
2588
- </div>
2589
- <div class="card-icon"><i class="pi pi-list"></i></div>
2590
- <div class="card-info">
2591
- <label for="scope_all" class="card-label">Todos os registros</label>
2592
- <span class="card-description">Exporta todos com o filtro ativo</span>
2593
- </div>
2594
- </div>
2595
- <div
2596
- class="scope-card"
2597
- [class.selected]="hasSelectedIds()"
2598
- [class.disabled]="!hasSelectedIds()"
2599
- (click)="hasSelectedIds() ? exportScope.set('selected') : null"
2600
- >
2601
- <div class="card-radio">
2602
- <p-radioButton
2603
- value="selected"
2604
- [(ngModel)]="exportScopeModel"
2605
- inputId="scope_selected"
2606
- [disabled]="!hasSelectedIds()"
2607
- ></p-radioButton>
2608
- </div>
2609
- <div class="card-icon"><i class="pi pi-check-square"></i></div>
2610
- <div class="card-info">
2611
- <label for="scope_selected" class="card-label">Registros selecionados</label>
2612
- <span class="card-description">Exporta apenas os itens marcados</span>
2613
- <span class="card-count">
2614
- <i class="pi pi-circle-fill"></i>
2615
- {{ selectedIds().length }} registro(s) selecionado(s)
2616
- </span>
2617
- </div>
2618
- </div>
2619
- </div>
2620
- </div>
2621
-
2622
- <!-- Seleção de Colunas -->
2623
- <div class="export-section">
2624
- <div class="section-header">
2625
- <div class="section-icon"><i class="pi pi-table"></i></div>
2626
- <h3>Colunas</h3>
2627
- <div class="column-actions">
2628
- <button type="button" class="action-link" (click)="selectAllColumns()">Todas</button>
2629
- <span class="separator">|</span>
2630
- <button type="button" class="action-link" (click)="deselectAllColumns()">Nenhuma</button>
2631
- </div>
2632
- </div>
2633
- <div class="columns-grid">
2634
- <div
2635
- *ngFor="let col of columnSelections()"
2636
- class="column-item"
2637
- [class.selected]="col.selected"
2638
- (click)="toggleColumn(col)"
2639
- >
2640
- <p-checkbox
2641
- [(ngModel)]="col.selected"
2642
- [binary]="true"
2643
- [inputId]="'col_' + col.column.columnName"
2644
- (onChange)="refreshColumns()"
2645
- ></p-checkbox>
2646
- <label [for]="'col_' + col.column.columnName" class="column-label">
2647
- {{ col.column.translateKey }}
2648
- </label>
2649
- </div>
2650
- </div>
2651
- <div class="columns-summary">
2652
- <i class="pi pi-info-circle"></i>
2653
- <span>{{ selectedColumnsCount() }} de {{ columnSelections().length }} colunas selecionadas</span>
2654
- </div>
2655
- </div>
2656
-
2657
- </div>
2658
-
2659
- <ng-template pTemplate="footer">
2660
- <p-button
2661
- label="Cancelar"
2662
- icon="pi pi-times"
2663
- severity="secondary"
2664
- [text]="true"
2665
- (onClick)="onDialogHide()"
2666
- />
2667
- <p-button
2668
- label="Exportar"
2669
- icon="pi pi-download"
2670
- [disabled]="!canExport()"
2671
- [loading]="exporting()"
2672
- (onClick)="doExport()"
2673
- />
2674
- </ng-template>
2675
- </p-dialog>
2676
- `, 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-file\"></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]=\"exportScope() === 'all'\"\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]=\"exportScope() === 'selected'\"\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"] }]
2677
2282
  }] });
2678
2283
 
2679
2284
  /*