@cdmx/wappler_ag_grid 2.0.13 → 2.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app_connect/components.hjson +8 -0
- package/dmx-ag-grid.js +160 -98
- package/package.json +1 -1
|
@@ -253,6 +253,14 @@
|
|
|
253
253
|
"type": "text",
|
|
254
254
|
"help": "Specifies fields to be excluded in CSV export (comma-seperated)."
|
|
255
255
|
},
|
|
256
|
+
{
|
|
257
|
+
"name": "exportRemoveHtml",
|
|
258
|
+
"attribute": "dmx-bind:export_remove_html",
|
|
259
|
+
"title": "Remove HTML from Export",
|
|
260
|
+
"type": "boolean",
|
|
261
|
+
"defaultValue": false,
|
|
262
|
+
"help": "Removes HTML tags from exported data (CSV/PDF). Converts <br> tags to newlines."
|
|
263
|
+
},
|
|
256
264
|
{
|
|
257
265
|
"name": "paginationPageSizeSelector",
|
|
258
266
|
"attribute": "dmx-bind:pagination_page_size_selector",
|
package/dmx-ag-grid.js
CHANGED
|
@@ -87,6 +87,7 @@ dmx.Component('ag-grid', {
|
|
|
87
87
|
export_trim_data: { type: Boolean, default: false },
|
|
88
88
|
export_exclude_hidden_fields: { type: Boolean, default: false },
|
|
89
89
|
export_exclude_fields: { type: String, default: null },
|
|
90
|
+
export_remove_html: { type: Boolean, default: false },
|
|
90
91
|
export_to_csv: { type: Boolean, default: true },
|
|
91
92
|
export_csv_filename: { type: String, default: 'export.csv' },
|
|
92
93
|
export_to_pdf: { type: Boolean, default: false },
|
|
@@ -356,9 +357,11 @@ dmx.Component('ag-grid', {
|
|
|
356
357
|
Csv = true;
|
|
357
358
|
}
|
|
358
359
|
dmx.nextTick(() => {
|
|
359
|
-
const
|
|
360
|
-
if (
|
|
361
|
-
|
|
360
|
+
const gridInst = this.get('gridInstance');
|
|
361
|
+
if (Csv) {
|
|
362
|
+
exportGridData(gridInst, this.gridConfig);
|
|
363
|
+
} else if (Pdf) {
|
|
364
|
+
exportGridDataToPDF(gridInst, this.gridConfig);
|
|
362
365
|
} else {
|
|
363
366
|
console.error('Grid not loaded to perform the requested export');
|
|
364
367
|
}
|
|
@@ -1979,6 +1982,8 @@ dmx.Component('ag-grid', {
|
|
|
1979
1982
|
columnDefs: columnDefs,
|
|
1980
1983
|
...gridOptions
|
|
1981
1984
|
};
|
|
1985
|
+
// Store gridConfig on component instance for export functions
|
|
1986
|
+
this.gridConfig = gridConfig;
|
|
1982
1987
|
// Conditionally add event listeners based on whether columnsToSum or columnsToCount are defined
|
|
1983
1988
|
if ((options.columns_to_sum && options.columns_to_sum.split(',').length > 0) || (options.columns_to_count.length > 0)) {
|
|
1984
1989
|
let columnsToSum = options.columns_to_sum ? options.columns_to_sum.split(',') : [];
|
|
@@ -2150,7 +2155,22 @@ dmx.Component('ag-grid', {
|
|
|
2150
2155
|
updateHoveringBarStyles();
|
|
2151
2156
|
|
|
2152
2157
|
//CSV Export Function
|
|
2153
|
-
|
|
2158
|
+
// Helper function to remove HTML tags from string
|
|
2159
|
+
const removeHtmlTags = (htmlString) => {
|
|
2160
|
+
if (typeof htmlString !== 'string') return htmlString;
|
|
2161
|
+
// Remove all HTML tags and decode common HTML entities
|
|
2162
|
+
return htmlString
|
|
2163
|
+
.replace(/<br\s*\/?>/gi, '\n') // Replace <br> tags with newlines
|
|
2164
|
+
.replace(/<[^>]*>/g, '') // Remove all other HTML tags
|
|
2165
|
+
.replace(/ /g, ' ') // Replace non-breaking space
|
|
2166
|
+
.replace(/</g, '<')
|
|
2167
|
+
.replace(/>/g, '>')
|
|
2168
|
+
.replace(/&/g, '&')
|
|
2169
|
+
.replace(/"/g, '"')
|
|
2170
|
+
.replace(/'/g, "'");
|
|
2171
|
+
};
|
|
2172
|
+
|
|
2173
|
+
exportGridData = (currentGridInstance, currentGridConfig) => {
|
|
2154
2174
|
const excludedColumnIds = ['checkboxColumn', 'actionsColumn'];
|
|
2155
2175
|
const exportExcludeFieldsArray = options.export_exclude_fields ? options.export_exclude_fields.split(',') : [];
|
|
2156
2176
|
|
|
@@ -2204,9 +2224,9 @@ dmx.Component('ag-grid', {
|
|
|
2204
2224
|
}
|
|
2205
2225
|
return null;
|
|
2206
2226
|
};
|
|
2207
|
-
return traverseColumns(
|
|
2227
|
+
return traverseColumns(currentGridConfig.columnDefs);
|
|
2208
2228
|
} else {
|
|
2209
|
-
return
|
|
2229
|
+
return currentGridConfig.columnDefs.find((column) => column.colId === colId);
|
|
2210
2230
|
}
|
|
2211
2231
|
}
|
|
2212
2232
|
|
|
@@ -2236,9 +2256,9 @@ dmx.Component('ag-grid', {
|
|
|
2236
2256
|
return fieldsAndColIds;
|
|
2237
2257
|
};
|
|
2238
2258
|
// Traverse columnDefs to gather fields and colIds
|
|
2239
|
-
fieldsAndColIds = traverseColumns(
|
|
2259
|
+
fieldsAndColIds = traverseColumns(currentGridConfig.columnDefs);
|
|
2240
2260
|
} else {
|
|
2241
|
-
fieldsAndColIds =
|
|
2261
|
+
fieldsAndColIds = currentGridConfig.columnDefs.map((column) => ({
|
|
2242
2262
|
field: column.field,
|
|
2243
2263
|
colId: column.colId,
|
|
2244
2264
|
hide: column.hide,
|
|
@@ -2283,6 +2303,11 @@ dmx.Component('ag-grid', {
|
|
|
2283
2303
|
}
|
|
2284
2304
|
}
|
|
2285
2305
|
|
|
2306
|
+
// Remove HTML tags if export_remove_html is true
|
|
2307
|
+
if (options.export_remove_html && typeof value === 'string') {
|
|
2308
|
+
value = removeHtmlTags(value);
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2286
2311
|
// Trim value if export_trim is true
|
|
2287
2312
|
if (options.export_trim_data && typeof value === 'string') {
|
|
2288
2313
|
return value.trim();
|
|
@@ -2291,46 +2316,57 @@ dmx.Component('ag-grid', {
|
|
|
2291
2316
|
return value;
|
|
2292
2317
|
},
|
|
2293
2318
|
};
|
|
2294
|
-
|
|
2319
|
+
currentGridInstance.exportDataAsCsv(params);
|
|
2295
2320
|
};
|
|
2296
2321
|
// Create the export button
|
|
2297
2322
|
if (exportToCSV) {
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2323
|
+
let exportButton = document.getElementById(`exportButton-${options.id}`);
|
|
2324
|
+
let isNewButton = false;
|
|
2325
|
+
if (!exportButton) {
|
|
2326
|
+
isNewButton = true;
|
|
2327
|
+
exportButton = document.createElement('button');
|
|
2328
|
+
exportButton.id = `exportButton-${options.id}`;
|
|
2329
|
+
const icon = document.createElement('i');
|
|
2330
|
+
icon.classList.add('fas', 'fa-file-csv');
|
|
2331
|
+
exportButton.appendChild(icon);
|
|
2307
2332
|
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2333
|
+
// Add the button text
|
|
2334
|
+
const buttonText = document.createElement('span');
|
|
2335
|
+
buttonText.innerText = ' Export to CSV';
|
|
2336
|
+
exportButton.appendChild(buttonText);
|
|
2337
|
+
exportButton.style.backgroundColor = '#4CAF50';
|
|
2338
|
+
exportButton.style.border = 'none';
|
|
2339
|
+
exportButton.style.color = 'white';
|
|
2340
|
+
exportButton.style.padding = '5px 10px';
|
|
2341
|
+
exportButton.style.textAlign = 'center';
|
|
2342
|
+
exportButton.style.textDecoration = 'none';
|
|
2343
|
+
exportButton.style.display = 'inline-block';
|
|
2344
|
+
exportButton.style.fontSize = '14px';
|
|
2345
|
+
exportButton.style.borderRadius = '5px';
|
|
2346
|
+
exportButton.style.cursor = 'pointer';
|
|
2347
|
+
exportButton.style.marginBottom = '10px';
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
// Always update the click handler to ensure it has the latest gridInstance and gridConfig
|
|
2351
|
+
exportButton.onclick = () => {
|
|
2352
|
+
const currentGridInstance = this.get('gridInstance');
|
|
2353
|
+
const currentGridConfig = this.gridConfig;
|
|
2354
|
+
if (currentGridInstance && currentGridConfig) {
|
|
2355
|
+
exportGridData(currentGridInstance, currentGridConfig);
|
|
2356
|
+
} else {
|
|
2357
|
+
console.error('Grid instance or configuration not available for export');
|
|
2358
|
+
}
|
|
2359
|
+
};
|
|
2360
|
+
|
|
2361
|
+
if (isNewButton) {
|
|
2362
|
+
// Append the export button to the grid container
|
|
2363
|
+
gridContainer.parentNode.insertBefore(exportButton, gridContainer);
|
|
2364
|
+
exportButton.style.marginBottom = '10px';
|
|
2365
|
+
}
|
|
2330
2366
|
}
|
|
2331
2367
|
// Export AG Grid data to PDF
|
|
2332
|
-
exportGridDataToPDF = async () => {
|
|
2333
|
-
if (!
|
|
2368
|
+
exportGridDataToPDF = async (currentGridInstance, currentGridConfig) => {
|
|
2369
|
+
if (!currentGridInstance || currentGridInstance.isDestroyed()) {
|
|
2334
2370
|
console.error('Grid API is destroyed or not initialized.');
|
|
2335
2371
|
return;
|
|
2336
2372
|
}
|
|
@@ -2355,9 +2391,9 @@ dmx.Component('ag-grid', {
|
|
|
2355
2391
|
return fieldsAndColIds;
|
|
2356
2392
|
};
|
|
2357
2393
|
// Traverse columnDefs to gather fields and colIds
|
|
2358
|
-
fieldsAndColIds = traverseColumns(
|
|
2394
|
+
fieldsAndColIds = traverseColumns(currentGridConfig.columnDefs);
|
|
2359
2395
|
} else {
|
|
2360
|
-
fieldsAndColIds =
|
|
2396
|
+
fieldsAndColIds = currentGridConfig.columnDefs.map((column) => ({
|
|
2361
2397
|
field: column.field,
|
|
2362
2398
|
colId: column.colId,
|
|
2363
2399
|
hide: column.hide,
|
|
@@ -2409,19 +2445,19 @@ dmx.Component('ag-grid', {
|
|
|
2409
2445
|
return options.wrap_text ? { whiteSpace: 'normal' } : null;
|
|
2410
2446
|
};
|
|
2411
2447
|
|
|
2412
|
-
const getColumnData = (
|
|
2413
|
-
|
|
2448
|
+
const getColumnData = (gInstance, isHeader) =>
|
|
2449
|
+
gInstance.getAllDisplayedColumns()
|
|
2414
2450
|
.filter(column => fieldsToExport.includes(column.getColDef().field))
|
|
2415
2451
|
.map(column => {
|
|
2416
2452
|
const colDef = column.getColDef();
|
|
2417
2453
|
const field = colDef.field;
|
|
2418
2454
|
const params = {
|
|
2419
|
-
value: isHeader ? null :
|
|
2420
|
-
data: isHeader ? null :
|
|
2421
|
-
node: isHeader ? null :
|
|
2455
|
+
value: isHeader ? null : gInstance.getValue(column, gInstance.getDisplayedRowAtIndex(0)),
|
|
2456
|
+
data: isHeader ? null : gInstance.getDisplayedRowAtIndex(0).data,
|
|
2457
|
+
node: isHeader ? null : gInstance.getDisplayedRowAtIndex(0),
|
|
2422
2458
|
colDef,
|
|
2423
2459
|
column,
|
|
2424
|
-
api:
|
|
2460
|
+
api: gInstance,
|
|
2425
2461
|
context: params.context,
|
|
2426
2462
|
};
|
|
2427
2463
|
const cellStyle = applyCellStyle(params);
|
|
@@ -2431,39 +2467,55 @@ dmx.Component('ag-grid', {
|
|
|
2431
2467
|
cnames[field].custom_name :
|
|
2432
2468
|
humanize(field)
|
|
2433
2469
|
) : '';
|
|
2470
|
+
let cellValue = !isHeader ? (
|
|
2471
|
+
(colDef.cellRenderer && typeof colDef.cellRenderer === 'function') ? colDef.cellRenderer(params) :
|
|
2472
|
+
(colDef.valueFormatter && typeof colDef.valueFormatter === 'function') ? colDef.valueFormatter(params) :
|
|
2473
|
+
gInstance.getValue(column, gInstance.getDisplayedRowAtIndex(0)) ?? ''
|
|
2474
|
+
) : headerName;
|
|
2475
|
+
|
|
2476
|
+
// Remove HTML tags if export_remove_html is true
|
|
2477
|
+
if (options.export_remove_html && typeof cellValue === 'string') {
|
|
2478
|
+
cellValue = removeHtmlTags(cellValue);
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2434
2481
|
return {
|
|
2435
|
-
text:
|
|
2436
|
-
(colDef.cellRenderer && typeof colDef.cellRenderer === 'function') ? colDef.cellRenderer(params) :
|
|
2437
|
-
(colDef.valueFormatter && typeof colDef.valueFormatter === 'function') ? colDef.valueFormatter(params) :
|
|
2438
|
-
gridInstance.getValue(column, gridInstance.getDisplayedRowAtIndex(0)) ?? ''
|
|
2439
|
-
) : headerName,
|
|
2482
|
+
text: cellValue,
|
|
2440
2483
|
color: cellStyle?.color ?? 'black',
|
|
2441
2484
|
fillColor: cellStyle?.backgroundColor ? cellStyle.backgroundColor.replace('#', '') : undefined,
|
|
2442
2485
|
};
|
|
2443
|
-
})
|
|
2486
|
+
});;
|
|
2444
2487
|
|
|
2445
|
-
const columns =
|
|
2488
|
+
const columns = currentGridInstance.getColumnState();
|
|
2446
2489
|
const columnMap = new Map(columns.map(col => [col.colId, col]));
|
|
2447
2490
|
|
|
2448
2491
|
const rows = [];
|
|
2449
|
-
|
|
2492
|
+
currentGridInstance.forEachNode(node => {
|
|
2450
2493
|
const row = fieldsToExport.map(field => {
|
|
2451
2494
|
const col = columnMap.get(field);
|
|
2452
|
-
const colDef = col ?
|
|
2495
|
+
const colDef = col ? currentGridInstance.getColumnDefs().find(def => def.colId === col.colId) : {};
|
|
2453
2496
|
const params = {
|
|
2454
|
-
value:
|
|
2497
|
+
value: currentGridInstance.getCellValue({ rowNode: node, colKey: col.colId }) ?? '-',
|
|
2455
2498
|
data: node.data,
|
|
2456
2499
|
node,
|
|
2457
2500
|
colDef,
|
|
2458
|
-
column:
|
|
2459
|
-
api:
|
|
2501
|
+
column: currentGridInstance.getColumnState().find(col => col.colId === col.colId),
|
|
2502
|
+
api: currentGridInstance,
|
|
2460
2503
|
};
|
|
2461
2504
|
const cellStyle = applyCellStyle(params);
|
|
2462
|
-
|
|
2505
|
+
let value = currentGridInstance.getCellValue({ rowNode: node, colKey: col.colId }) ?? '-';
|
|
2506
|
+
|
|
2507
|
+
// Get the rendered value
|
|
2508
|
+
let displayValue = (colDef.cellRenderer && typeof colDef.cellRenderer === 'function') ? colDef.cellRenderer(params) :
|
|
2509
|
+
(colDef.valueFormatter && typeof colDef.valueFormatter === 'function') ? colDef.valueFormatter(params) :
|
|
2510
|
+
value;
|
|
2511
|
+
|
|
2512
|
+
// Remove HTML tags if export_remove_html is true
|
|
2513
|
+
if (options.export_remove_html && typeof displayValue === 'string') {
|
|
2514
|
+
displayValue = removeHtmlTags(displayValue);
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2463
2517
|
return {
|
|
2464
|
-
text:
|
|
2465
|
-
(colDef.valueFormatter && typeof colDef.valueFormatter === 'function') ? colDef.valueFormatter(params) :
|
|
2466
|
-
value,
|
|
2518
|
+
text: displayValue,
|
|
2467
2519
|
color: cellStyle?.color ?? 'black',
|
|
2468
2520
|
fillColor: cellStyle?.backgroundColor ? cellStyle.backgroundColor.replace('#', '') : undefined,
|
|
2469
2521
|
};
|
|
@@ -2476,7 +2528,7 @@ dmx.Component('ag-grid', {
|
|
|
2476
2528
|
table: {
|
|
2477
2529
|
headerRows: 1,
|
|
2478
2530
|
widths: fieldsToExport.map(() => `${100 / fieldsToExport.length}%`),
|
|
2479
|
-
body: [getColumnData(
|
|
2531
|
+
body: [getColumnData(currentGridInstance, true), ...rows],
|
|
2480
2532
|
heights: (rowIndex) => (rowIndex === 0 ? 40 : 15),
|
|
2481
2533
|
fillColor: (rowIndex, colIndex) => rows[rowIndex][colIndex].fillColor,
|
|
2482
2534
|
color: (rowIndex, colIndex) => rows[rowIndex][colIndex].color,
|
|
@@ -2486,39 +2538,49 @@ dmx.Component('ag-grid', {
|
|
|
2486
2538
|
pdfMake.createPdf(documentDefinition).download(options.export_pdf_filename);
|
|
2487
2539
|
};
|
|
2488
2540
|
if (exportToPDF) {
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2541
|
+
let exportPdfButton = document.getElementById(`exportPdfButton-${options.id}`);
|
|
2542
|
+
let isNewPdfButton = false;
|
|
2543
|
+
if (!exportPdfButton) {
|
|
2544
|
+
isNewPdfButton = true;
|
|
2545
|
+
exportPdfButton = document.createElement('button');
|
|
2546
|
+
exportPdfButton.id = `exportPdfButton-${options.id}`;
|
|
2547
|
+
const icon = document.createElement('i');
|
|
2548
|
+
icon.classList.add('fas', 'fa-file-pdf');
|
|
2549
|
+
exportPdfButton.appendChild(icon);
|
|
2498
2550
|
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2551
|
+
// Add the button text
|
|
2552
|
+
const buttonText = document.createElement('span');
|
|
2553
|
+
buttonText.innerText = ' Export to PDF';
|
|
2554
|
+
exportPdfButton.appendChild(buttonText);
|
|
2555
|
+
exportPdfButton.style.backgroundColor = '#4CAF50';
|
|
2556
|
+
exportPdfButton.style.border = 'none';
|
|
2557
|
+
exportPdfButton.style.color = 'white';
|
|
2558
|
+
exportPdfButton.style.padding = '5px 10px';
|
|
2559
|
+
exportPdfButton.style.textAlign = 'center';
|
|
2560
|
+
exportPdfButton.style.textDecoration = 'none';
|
|
2561
|
+
exportPdfButton.style.display = 'inline-block';
|
|
2562
|
+
exportPdfButton.style.fontSize = '14px';
|
|
2563
|
+
exportPdfButton.style.borderRadius = '5px';
|
|
2564
|
+
exportPdfButton.style.cursor = 'pointer';
|
|
2565
|
+
exportPdfButton.style.marginBottom = '10px';
|
|
2566
|
+
}
|
|
2567
|
+
|
|
2568
|
+
// Always update the click handler to ensure it has the latest gridInstance and gridConfig
|
|
2569
|
+
exportPdfButton.onclick = () => {
|
|
2570
|
+
const currentGridInstance = this.get('gridInstance');
|
|
2571
|
+
const currentGridConfig = this.gridConfig;
|
|
2572
|
+
if (currentGridInstance && currentGridConfig) {
|
|
2573
|
+
exportGridDataToPDF(currentGridInstance, currentGridConfig);
|
|
2574
|
+
} else {
|
|
2575
|
+
console.error('Grid instance or configuration not available for export');
|
|
2576
|
+
}
|
|
2577
|
+
};
|
|
2518
2578
|
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2579
|
+
if (isNewPdfButton) {
|
|
2580
|
+
// Append the export button to the grid container
|
|
2581
|
+
gridContainer.parentNode.insertBefore(exportPdfButton, gridContainer);
|
|
2582
|
+
exportPdfButton.style.marginBottom = '10px';
|
|
2583
|
+
}
|
|
2522
2584
|
}
|
|
2523
2585
|
const paginationPanelCss = `
|
|
2524
2586
|
/* Flexbox layout for pagination panel */
|
package/package.json
CHANGED