@cdmx/wappler_ag_grid
Version:
App Connect module for AG Grid v35 - Advanced data grid with enhanced editing, filtering, and tree data capabilities.
1,096 lines (1,061 loc) • 125 kB
JavaScript
dmx.Component('ag-grid', {
initialData: {
id: null,
data: {},
count: Number,
fields: {},
fileData: [],
selectedRows: [],
columnState: [],
filterState: [],
state: {
gridReady: !1,
firstDataRendered: !1,
rowDataUpdated: !1
}
},
attributes: {
id: { default: null },
noload: { type: Boolean, default: false },
grid_theme: { type: String, default: 'ag-theme-alpine' },
dark_mode: { type: Boolean, default: false},
column_defs: { type: Array, default: [] },
tooltip_config: { type: Array, default: [] },
custom_tooltip: { type: String, default: null },
cstyles: { type: Array, default: [] },
rstyles: { type: Array, default: {} },
cnames: { type: Object, default: {} },
cwidths: { type: Object, default: {} },
ctypes: { type: Array, default: [] },
cfilters: { type: Array, default: [] },
csort: { type: Array, default: [] },
cstatic_select_editors: { type: Object, default: {} },
cdynamic_select_editors: { type: Object, default: {} },
cselect_placeholder: { type: String, default: "-" },
wrap_header_text: { type: Boolean, default: true },
auto_header_height: { type: Boolean, default: true },
wrap_text: { type: Boolean, default: false },
auto_height: { type: Boolean, default: false },
vert_center_cell_data: { type: Boolean, default: false },
horz_center_cell_data: { type: Boolean, default: false },
data_changes: { type: Array, default: [] },
display_data_changes: { type: Array, default: [] },
js_data_changes: { type: Array, default: [] },
js_tooltip_changes: { type: Array, default: [] },
tooltip_show_delay: { type: Number, default: 2000 },
data: { type: Array, default: [] },
dom_layout: { type: String, default: 'autoHeight' },
enable_cell_text_selection: { type: Boolean, default: true },
row_selection: { type: String, default: 'multiRow' },
suppress_row_deselection: { type: Boolean, default: false },
suppress_model_update: { type: Boolean, default: false },
pagination: { type: Boolean, default: true },
pagination_auto_page_size: { type: Boolean, default: false },
pagination_page_size_selector: { type: Array, default: [20,50,100] },
pagination_page_size: { type: Number, default: 20 },
row_height: { type: Number, default: null },
header_height: { type: Number, default: null },
suppress_row_click_selection: { type: Boolean, default: false },
suppress_menu_hide: { type: Boolean, default: false },
suppress_movable_columns: { type: Boolean, default: false },
enable_cell_expressions: { type: Boolean, default: false },
animate_rows: { type: Boolean, default: false },
always_show_horizontal_scroll: { type: Boolean, default: true },
always_show_vertical_scroll: { type: Boolean, default: false },
suppress_agg_func_in_header: { type: Boolean, default: false },
suppress_agg_at_root_level: { type: Boolean, default: false },
suppress_clipboard_paste: { type: Boolean, default: false },
suppress_scroll_on_new_data: { type: Boolean, default: false },
hide_id_field: { type: Boolean, default: false },
numeric_column_align: { type: Boolean, default: false },
enable_rtl: { type: Boolean, default: false },
locale_text: { type: String, default: null },
date_locale: { type: String, default: 'en-US' },
date_format: { type: String, default: 'dd/MM/yyyy hh:mm A' },
amount_fields: { type: String, default: null },
amount_field_precision: { type: Number, default: 2 },
min_width: { type: Number, default: 150 },
sortable: { type: Boolean, default: true },
cell_editable: { type: Boolean, default: false },
editable_fields: { type: String, default: null },
row_editable: { type: Boolean, default: false },
ci_sort: { type: Boolean, default: false },
resizable: { type: Boolean, default: true },
filter: { type: Boolean, default: true },
floating_filter: { type: Boolean, default: true },
column_hover_highlight: { type: Boolean, default: true },
quick_filter_field: { type: String, default: 'search_field' },
export_trim_data: { type: Boolean, default: false },
export_exclude_hidden_fields: { type: Boolean, default: false },
export_exclude_fields: { type: String, default: null },
export_remove_html: { type: Boolean, default: false },
export_to_csv: { type: Boolean, default: true },
export_csv_filename: { type: String, default: 'export.csv' },
export_to_pdf: { type: Boolean, default: false },
export_pdf_filename: { type: String, default: 'export.pdf' },
export_to_xls: { type: Boolean, default: false },
export_xls_filename: { type: String, default: 'export.xlsx' },
fixed_header: { type: Boolean, default: false },
topbar_class: { type: String, default: 'topbar' },
fixed_header_offset: { type: Number, default: 100 },
fixed_top_offset: { type: Number, default: 80 },
fixed_horizontal_scroll: { type: Boolean, default: false },
fixed_footer: { type: Boolean, default: false },
fixed_footer_bottom_padding: { type: Number, default: 10 },
timezone: {type: String, default: '' },
cell_click_event: {type: Boolean, default: false },
row_click_event: {type: Boolean, default: false },
row_double_click_event: {type: Boolean, default: false },
row_checkbox_event: {type: Boolean, default: false },
row_status_event: {type: Boolean, default: false },
loading_overlay: { type: Boolean, default: false },
loading_overlay_duration: { type: Number, default: 500 },
enable_actions: {type: Boolean, default: false },
actions_column_position: {type: String, default: 'right' },
actions_column_min_width: {type: Number, default: null },
actions_column_max_width: {type: Number, default: null },
pin_actions: { type: Boolean, default: true },
edit_action_btn: { type: Boolean, default: false },
edit_action_title: {type: String, default: '' },
edit_action_tooltip: {type: String, default: 'Edit' },
edit_action_icon_class: {type: String, default: 'fas fa-pencil-alt' },
edit_action_btn_class: {type: String, default: 'btn-primary btn-xs m-1' },
edit_action_btn_condition: {type: String, default: null },
view_action_btn: { type: Boolean, default: false },
view_action_title: {type: String, default: '' },
view_action_tooltip: {type: String, default: 'View' },
view_action_icon_class: {type: String, default: 'fas fa-eye' },
view_action_btn_class: {type: String, default: 'btn-info btn-xs m-1' },
view_action_btn_condition: {type: String, default: null },
delete_action_btn: { type: Boolean, default: false },
delete_action_title: {type: String, default: '' },
delete_action_tooltip: {type: String, default: 'Delete' },
delete_action_icon_class: {type: String, default: 'fas fa-trash' },
delete_action_btn_class: {type: String, default: 'btn-danger btn-xs m-1' },
delete_action_btn_condition: {type: String, default: null },
enable_custom_action_btns: { type: Boolean, default: false },
action_button_class_toggles: { type: Array, default: [] },
action_button_icon_class_toggles: { type: Array, default: [] },
button1_action_btn: { type: "Boolean", default: false },
button1_action_title: { type: "String", default: "" },
button1_action_tooltip: { type: "String", default: "" },
button1_action_icon_class: { type: "String", default: "fas fa-wrench" },
button1_action_btn_class: { type: "String", default: "btn-primary btn-xs m-1" },
button1_action_btn_condition: {type: String, default: null },
button2_action_btn: { type: "Boolean", default: false },
button2_action_title: { type: "String", default: "" },
button2_action_tooltip: { type: "String", default: "" },
button2_action_icon_class: { type: "String", default: "fas fa-search-plus" },
button2_action_btn_class: { type: "String", default: "btn-info btn-xs m-1" },
button2_action_btn_condition: {type: String, default: null },
button3_action_btn: { type: "Boolean", default: false },
button3_action_title: { type: "String", default: "" },
button3_action_tooltip: { type: "String", default: "" },
button3_action_icon_class: { type: "String", default: "fas fa-check-circle" },
button3_action_btn_class: { type: "String", default: "btn-success btn-xs m-1" },
button3_action_btn_condition: {type: String, default: null },
button4_action_btn: { type: "Boolean", default: false },
button4_action_title: { type: "String", default: "" },
button4_action_tooltip: { type: "String", default: "" },
button4_action_icon_class: { type: "String", default: "fas fa-exclamation-triangle" },
button4_action_btn_class: { type: "String", default: "btn-warning btn-xs m-1" },
button4_action_btn_condition: {type: String, default: null },
button5_action_btn: { type: "Boolean", default: false },
button5_action_title: { type: "String", default: "" },
button5_action_tooltip: { type: "String", default: "Edit" },
button5_action_icon_class: { type: "String", default: "fas fa-times-circle" },
button5_action_btn_class: { type: "String", default: "btn-danger btn-xs m-1" },
button5_action_btn_condition: {type: String, default: null },
button6_action_btn: { type: "Boolean", default: false },
button6_action_title: { type: "String", default: "" },
button6_action_tooltip: { type: "String", default: "" },
button6_action_icon_class: { type: "String", default: "fas fa-link" },
button6_action_btn_class: { type: "String", default: "btn-secondary btn-xs m-1" },
button6_action_btn_condition: {type: String, default: null },
button7_action_btn: { type: "Boolean", default: false },
button7_action_title: { type: "String", default: "" },
button7_action_tooltip: { type: "String", default: "" },
button7_action_icon_class: { type: "String", default: "fas fa-download" },
button7_action_btn_class: { type: "String", default: "btn-primary btn-xm" },
button7_action_btn_condition: {type: String, default: null },
button8_action_btn: { type: "Boolean", default: false },
button8_action_title: { type: "String", default: "" },
button8_action_tooltip: { type: "String", default: "" },
button8_action_icon_class: { type: "String", default: "fas fa-file-pdf" },
button8_action_btn_class: { type: "String", default: "btn-info btn-xs m-1" },
button8_action_btn_condition: {type: String, default: null },
button9_action_btn: { type: "Boolean", default: false },
button9_action_title: { type: "String", default: "" },
button9_action_tooltip: { type: "String", default: "" },
button9_action_icon_class: { type: "String", default: "fas fa-star" },
button9_action_btn_class: { type: "String", default: "btn-success btn-xs m-1" },
button9_action_btn_condition: {type: String, default: null },
button10_action_btn: { type: "Boolean", default: false },
button10_action_title: { type: "String", default: "" },
button10_action_tooltip: { type: "String", default: "" },
button10_action_icon_class: { type: "String", default: "fas fa-trash-alt" },
button10_action_btn_class: { type: "String", default: "btn-danger btn-xs m-1" },
button10_action_btn_condition: {type: String, default: null },
button11_action_btn: { type: "Boolean", default: false },
button11_action_title: { type: "String", default: "" },
button11_action_tooltip: { type: "String", default: "" },
button11_action_icon_class: { type: "String", default: "fas fa-cog" },
button11_action_btn_class: { type: "String", default: "btn-primary btn-xs m-1" },
button11_action_btn_condition: { type: String, default: null },
button12_action_btn: { type: "Boolean", default: false },
button12_action_title: { type: "String", default: "" },
button12_action_tooltip: { type: "String", default: "" },
button12_action_icon_class: { type: "String", default: "fas fa-search" },
button12_action_btn_class: { type: "String", default: "btn-info btn-xs m-1" },
button12_action_btn_condition: { type: String, default: null },
button13_action_btn: { type: "Boolean", default: false },
button13_action_title: { type: "String", default: "" },
button13_action_tooltip: { type: "String", default: "" },
button13_action_icon_class: { type: "String", default: "fas fa-thumbs-up" },
button13_action_btn_class: { type: "String", default: "btn-success btn-xs m-1" },
button13_action_btn_condition: { type: String, default: null },
button14_action_btn: { type: "Boolean", default: false },
button14_action_title: { type: "String", default: "" },
button14_action_tooltip: { type: "String", default: "" },
button14_action_icon_class: { type: "String", default: "fas fa-bell" },
button14_action_btn_class: { type: "String", default: "btn-warning btn-xs m-1" },
button14_action_btn_condition: { type: String, default: null },
button15_action_btn: { type: "Boolean", default: false },
button15_action_title: { type: "String", default: "" },
button15_action_tooltip: { type: "String", default: "" },
button15_action_icon_class: { type: "String", default: "fas fa-ban" },
button15_action_btn_class: { type: "String", default: "btn-danger btn-xs m-1" },
button15_action_btn_condition: { type: String, default: null },
button16_action_btn: { type: "Boolean", default: false },
button16_action_title: { type: "String", default: "" },
button16_action_tooltip: { type: "String", default: "" },
button16_action_icon_class: { type: "String", default: "fas fa-link" },
button16_action_btn_class: { type: "String", default: "btn-secondary btn-xs m-1" },
button16_action_btn_condition: { type: String, default: null },
button17_action_btn: { type: "Boolean", default: false },
button17_action_title: { type: "String", default: "" },
button17_action_tooltip: { type: "String", default: "" },
button17_action_icon_class: { type: "String", default: "fas fa-file" },
button17_action_btn_class: { type: "String", default: "btn-primary btn-sm m-1" },
button17_action_btn_condition: { type: String, default: null },
button18_action_btn: { type: "Boolean", default: false },
button18_action_title: { type: "String", default: "" },
button18_action_tooltip: { type: "String", default: "" },
button18_action_icon_class: { type: "String", default: "fas fa-print" },
button18_action_btn_class: { type: "String", default: "btn-info btn-sm m-1" },
button18_action_btn_condition: { type: String, default: null },
button19_action_btn: { type: "Boolean", default: false },
button19_action_title: { type: "String", default: "" },
button19_action_tooltip: { type: "String", default: "" },
button19_action_icon_class: { type: "String", default: "fas fa-heart" },
button19_action_btn_class: { type: "String", default: "btn-success btn-sm m-1" },
button19_action_btn_condition: { type: String, default: null },
button20_action_btn: { type: "Boolean", default: false },
button20_action_title: { type: "String", default: "" },
button20_action_tooltip: { type: "String", default: "" },
button20_action_icon_class: { type: "String", default: "fas fa-times" },
button20_action_btn_class: { type: "String", default: "btn-danger btn-sm m-1" },
button20_action_btn_condition: { type: String, default: null },
button21_action_btn: { type: "Boolean", default: false },
button21_action_title: { type: "String", default: "" },
button21_action_tooltip: { type: "String", default: "" },
button21_action_icon_class: { type: "String", default: "fas fa-arrow-right" },
button21_action_btn_class: { type: "String", default: "btn-primary btn-sm m-1" },
button21_action_btn_condition: { type: String, default: null },
button22_action_btn: { type: "Boolean", default: false },
button22_action_title: { type: "String", default: "" },
button22_action_tooltip: { type: "String", default: "" },
button22_action_icon_class: { type: "String", default: "fas fa-arrow-left" },
button22_action_btn_class: { type: "String", default: "btn-info btn-sm m-1" },
button22_action_btn_condition: { type: String, default: null },
button23_action_btn: { type: "Boolean", default: false },
button23_action_title: { type: "String", default: "" },
button23_action_tooltip: { type: "String", default: "" },
button23_action_icon_class: { type: "String", default: "fas fa-check" },
button23_action_btn_class: { type: "String", default: "btn-success btn-sm m-1" },
button23_action_btn_condition: { type: String, default: null },
button24_action_btn: { type: "Boolean", default: false },
button24_action_title: { type: "String", default: "" },
button24_action_tooltip: { type: "String", default: "" },
button24_action_icon_class: { type: "String", default: "fas fa-exclamation" },
button24_action_btn_class: { type: "String", default: "btn-warning btn-sm m-1" },
button24_action_btn_condition: { type: String, default: null },
button25_action_btn: { type: "Boolean", default: false },
button25_action_title: { type: "String", default: "" },
button25_action_tooltip: { type: "String", default: "" },
button25_action_icon_class: { type: "String", default: "fas fa-times" },
button25_action_btn_class: { type: "String", default: "btn-danger btn-sm m-1" },
button25_action_btn_condition: { type: String, default: null },
button26_action_btn: { type: "Boolean", default: false },
button26_action_title: { type: "String", default: "" },
button26_action_tooltip: { type: "String", default: "" },
button26_action_icon_class: { type: "String", default: "fas fa-refresh" },
button26_action_btn_class: { type: "String", default: "btn-secondary btn-sm m-1" },
button26_action_btn_condition: { type: String, default: null },
button27_action_btn: { type: "Boolean", default: false },
button27_action_title: { type: "String", default: "" },
button27_action_tooltip: { type: "String", default: "" },
button27_action_icon_class: { type: "String", default: "fas fa-plus" },
button27_action_btn_class: { type: "String", default: "btn-primary btn-sm m-1" },
button27_action_btn_condition: { type: String, default: null },
button28_action_btn: { type: "Boolean", default: false },
button28_action_title: { type: "String", default: "" },
button28_action_tooltip: { type: "String", default: "" },
button28_action_icon_class: { type: "String", default: "fas fa-minus" },
button28_action_btn_class: { type: "String", default: "btn-info btn-sm m-1" },
button28_action_btn_condition: { type: String, default: null },
button29_action_btn: { type: "Boolean", default: false },
button29_action_title: { type: "String", default: "" },
button29_action_tooltip: { type: "String", default: "" },
button29_action_icon_class: { type: "String", default: "fas fa-copy" },
button29_action_btn_class: { type: "String", default: "btn-success btn-sm m-1" },
button29_action_btn_condition: { type: String, default: null },
button30_action_btn: { type: "Boolean", default: false },
button30_action_title: { type: "String", default: "" },
button30_action_tooltip: { type: "String", default: "" },
button30_action_icon_class: { type: "String", default: "fas fa-share" },
button30_action_btn_class: { type: "String", default: "btn-danger btn-sm m-1" },
button30_action_btn_condition: { type: String, default: null },
data_binded_changes: {type: Array, default: [] },
hide_fields: {type: String, default: null },
hide_filters: {type: String, default: null },
hide_sort: {type: String, default: null },
compact_view: { type: Boolean, default: false },
compact_view_grid_size: { type: Number, default: 3 },
compact_view_item_height: { type: Number, default: 20 },
group_config: { type: Array, default: [] },
columns_to_count: { type: Array, default: [] },
columns_to_sum: { type: String, default: null },
footer_sum_precision: { type: Number, default: null },
columns_to_count_nonunique: { type: Boolean, default: false },
column_state_storage_key: { type: String, default: null }
},
methods: {
setValue: function (rowData, columnDefs) {
this.set('rowData', rowData);
this.set('columnDefs', columnDefs);
this.refreshGrid();
},
reloadGrid: function (loadGridInstance) {
dmx.nextTick(function() {
this.transactionUpdate(loadGridInstance);
}, this);
},
loadGrid: function () {
dmx.nextTick(function() {
let gridInstance = this.refreshGrid();
this.set('gridInstance', gridInstance);
}, this);
},
destroyGrid: function () {
dmx.nextTick(function() {
var gridInstance = this.get('gridInstance');
if (gridInstance) gridInstance.destroy();
}, this);
},
exportGrid: function (format) {
// Default to csv if no format specified
format = (format || 'csv')
dmx.nextTick(() => {
const gridInst = this.get('gridInstance');
const gridCfg = this.get('gridConfig');
if (!gridInst || !gridCfg) {
console.error('Grid not loaded to perform the requested export');
return;
}
switch (format) {
case 'pdf':
exportGridDataToPDF(gridInst, gridCfg);
break;
case 'xls':
exportGridDataToXLS(gridInst, gridCfg);
break;
case 'csv':
default:
exportGridData(gridInst, gridCfg);
break;
}
}, this);
},
saveColumnState: function () {
dmx.nextTick(function() {
if (typeof saveColumnStateToStorage === 'function') {
saveColumnStateToStorage();
} else {
console.error('Grid not loaded to perform save column state');
}
}, this);
},
resetColumnState: function () {
dmx.nextTick(function() {
const idValue = this.$node.querySelector('dmx-ag-grid > div')?.getAttribute('id') ?? 'Grid not found';
const currentPageUrl = window.location.pathname;
const uniqueId = `${currentPageUrl}_${idValue}`;
const storageKey = options.column_state_storage_key || uniqueId;
localStorage.removeItem(`dmxState-${storageKey}`);
let gridInstance = this.refreshGrid();
this.set('gridInstance', gridInstance);
}, this);
},
pinColumns: function (fieldId) {
pinColumnToLeft(fieldId);
},
hideColumns: function (fieldId) {
hideColumn(fieldId);
},
importFileData: async function (fieldId) {
await this.parseFileData(fieldId);
},
getSelectedRows: function () {
exportSelectedRows();
},
quickFilter: function () {
onFilterTextBoxChanged();
},
getAppliedFilters: function () {
dmx.nextTick(function() {
const gridInstance = this.get('gridInstance');
if (gridInstance) {
const filterModel = gridInstance.getFilterModel();
this.set('filterState', filterModel || {});
return filterModel;
} else {
console.error('Grid not loaded to get filters');
return null;
}
}, this);
},
getFilteredData: function () {
dmx.nextTick(function() {
const gridInstance = this.get('gridInstance');
if (gridInstance) {
const filteredData = [];
gridInstance.forEachNodeAfterFilter(node => {
if (node.data) {
filteredData.push(node.data);
}
});
return filteredData;
} else {
console.error('Grid not loaded to get filtered data');
return null;
}
}, this);
},
applyFilters: function (filterModel) {
dmx.nextTick(function() {
const gridInstance = this.get('gridInstance');
if (gridInstance && filterModel) {
gridInstance.setFilterModel(filterModel);
gridInstance.onFilterChanged();
this.set('filterState', filterModel);
} else {
console.error('Grid not loaded or filter model is invalid');
}
}, this);
},
clearFilters: function () {
dmx.nextTick(function() {
const gridInstance = this.get('gridInstance');
if (gridInstance) {
gridInstance.setFilterModel(null);
gridInstance.onFilterChanged();
this.set('filterState', {});
} else {
console.error('Grid not loaded to clear filters');
}
}, this);
}
},
transactionUpdate: async function (loadGridInstance) {
// const oldRowData = this.get('oldData');
var gridInstance = this.get('gridInstance');
if (!gridInstance) {
if (loadGridInstance) {
gridInstance = await this.refreshGrid();
await this.set('gridInstance', gridInstance);
}
else {
console.error('AG Grid instance not loaded.');
return;
}
}
if (!gridInstance) {
return;
}
const oldRowData = [];
gridInstance.forEachNode(node => {
if (node.data) {
oldRowData.push(node.data);
}
});
const newRowData = this.props.data;
let transaction;
if (oldRowData && oldRowData.length > 0) {
const addedRows = newRowData.filter(newRow => !oldRowData.some(oldRow => newRow.id === oldRow.id));
const removedRows = oldRowData.filter(oldRow => !newRowData.some(newRow => oldRow.id === newRow.id));
const updatedRows = newRowData.filter(newRow => {
const oldRow = oldRowData.find(old => old.id === newRow.id);
return oldRow && JSON.stringify(oldRow) !== JSON.stringify(newRow);
});
// Apply transactional updates to AG Grid
transaction = {
add: addedRows,
remove: removedRows,
update: updatedRows,
};
}
if (gridInstance && transaction) {
gridInstance.applyTransaction(transaction);
// gridInstance.refreshCells();
}
},
parseFileData: async function (fieldId) {
const parseCSV = (csvData) => {
return new Promise((resolve, reject) => {
Papa.parse(csvData, {
header: true,
dynamicTyping: true,
complete: function (results) {
resolve(results.data);
},
error: function (error) {
reject(error.message);
}
});
});
};
const parseExcel = (file) => {
return new Promise((resolve, reject) => {
const headers = [];
const data = [];
readXlsxFile(file)
.then((rows) => {
rows.forEach((row, rowIndex) => {
if (rowIndex === 0) {
// First row contains headers
headers.push(...row);
} else {
// Map data rows to objects using the headers
const rowData = {};
row.forEach((cell, colIndex) => {
// Use headers to map values to the respective columns
rowData[headers[colIndex]] = cell;
});
data.push(rowData);
}
});
// Resolve the promise with the parsed data
resolve(data);
})
.catch((error) => {
// Reject the promise in case of an error
reject(error.message);
});
});
};
const fileInput = document.getElementById(fieldId);
if (!fileInput) {
console.error('Field having field Id: '+fieldId+' not found.');
return;
}
const file = fileInput.files[0];
if (!file) {
console.error('Please select a file.');
return;
}
const reader = new FileReader();
reader.onload = async (e) => {
const fileData = e.target.result;
try {
let parsedData;
// Detect the file type based on the file extension or other criteria
if (file.name.endsWith('.csv')) {
parsedData = await parseCSV(fileData);
} else if (file.name.endsWith('.xlsx') || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
parsedData = await parseExcel(file);
} else {
console.error('Unsupported file type. Please select a CSV or Excel file.');
return;
}
this.set('fileData', parsedData);
} catch (error) {
console.error('Error parsing file:', error);
}
};
reader.readAsBinaryString(file);
},
refreshGrid: function () {
const options = this.props
const rowData = this.props.data;
const timezone = this.props.timezone || false;
const cnames = this.props.cnames
const cwidths = this.props.cwidths
const ctypes = this.props.ctypes
if (!this.$node || !rowData || rowData.length === 0) {
console.debug('AG Grid loaded with no row data.')
return;
}
let gridInstance = this.get('gridInstance') ? this.get('gridInstance') : null;
let pagination_page_size = gridInstance ? gridInstance.paginationGetPageSize() : this.props.pagination_page_size
const enableRowClickEvent = this.props.row_click_event && !this.props.enable_actions && !this.props.row_checkbox_event;
const enableRowDoubleClickEvent = this.props.row_double_click_event && !this.props.enable_actions && !this.props.row_checkbox_event;
const enableCellClickEvent = this.props.row_click_event && (this.props.enable_actions || this.props.row_checkbox_event);
const enableCellDoubleClickEvent = this.props.row_double_click_event && (this.props.enable_actions || this.props.row_checkbox_event);
const actionButtonClassToggles = options.action_button_class_toggles
const actionButtonIconClassToggles = options.action_button_icon_class_toggles
let localeText;
let columnDefs = [];
let groupedColumnDefs = [];
let exportToCSV = this.props.export_to_csv;
let exportToPDF = this.props.export_to_pdf;
let exportToXLS = this.props.export_to_xls;
let cellRenderer;
const gridThemeClass = options.dark_mode ? `${options.grid_theme}-dark` : options.grid_theme;
this.$node.innerHTML = `<div id=${options.id}-grid class="${gridThemeClass}"></div>`;
// Apply theme mode using data attribute
const themeContainer = this.$node.querySelector(`#${options.id}-grid`);
if (themeContainer) {
themeContainer.dataset.agThemeMode = options.dark_mode ? 'dark' : 'light';
}
let idFieldPresent = false;
window.cellClickEvent = (columnName, value, idValue) => {
this.set('fields', {"field": columnName, "data": value});
this.set('id', idValue);
this.dispatchEvent('cell_clicked')
};
window.handleStatusToggle = (event, columnName, value, idValue) => {
const isChecked = event.target.checked;
if (isChecked) {
// Code for when the checkbox is checked
this.set('id', idValue);
this.set('fields', {"field": columnName, "data": value});
this.dispatchEvent('row_status_enabled')
} else {
// Code for when the checkbox is unchecked
this.set('id', idValue);
this.set('fields', {"field": columnName, "data": value});
this.dispatchEvent('row_status_disabled')
}
};
function clickCellRenderer(params) {
const idValue = params.data.id;
const columnName = params.colDef.field;
const value = params.value
return `<div onclick="cellClickEvent('${columnName}', '${value}', '${idValue}')" style="cursor: pointer;">${value}</div>`;
}
onCellClicked = (event) => {
const rowData = event.data;
const columnId = event.column.colId
const excludedColIds = ['checkboxColumn', 'actionsColumn', 'statusColumn'];
if (excludedColIds.includes(columnId)) {
return;
}
this.set('data', rowData);
this.set('id', rowData.id);
this.dispatchEvent('row_clicked')
}
onCellDoubleClicked = (event) => {
const rowData = event.data;
const columnId = event.column.colId
const excludedColIds = ['checkboxColumn', 'actionsColumn', 'statusColumn'];
if (excludedColIds.includes(columnId)) {
return;
}
this.set('data', rowData);
this.set('id', rowData.id);
this.dispatchEvent('row_double_clicked')
}
function actionsRendererForPinnedBottom(params) {
if (params.node && params.node.rowPinned === 'bottom') {
return ''; // Render an empty string for bottom pinned row
} else {
return actionsRenderer(params);
}
}
function checkboxCellRenderer(params) {
const idValue = params.data.id;
const columnName = params.colDef.field;
const value = params.value;
if (params.node.rowPinned == 'bottom') {
// Render an empty cell for the footer row
return '-';
}
// Assuming `value` is a boolean representing the status
const checked = value==true ? "checked" : "";
return `
<div class="col pt-2 pb-1 ps-1 pe-1 d-flex justify-content-center">
<label class="switch switch-success">
<input
type="checkbox" class="switch-input"
${checked}
onclick="handleStatusToggle(event, '${columnName}', '${value}', '${idValue}')"
/>
<span class="switch-toggle-slider" role="status">
</span>
<span class="switch-on">
<i class="bx bx-check"></i>
</span>
<span class="switch-off">
<i class="bx bx-x"></i>
</span>
</label>
</div>
`;
}
function actionsRenderer(params) {
// Default button configurations (Edit, View and Delete)
const defaultButtons = [
{ action: 'Edit', classNames: 'btn-primary btn-xs', tooltip: 'Edit', icon: 'fas fa-pencil-alt' },
{ action: 'View', classNames: 'btn-info btn-xs', tooltip: 'View', icon: 'fas fa-eye' },
{ action: 'Delete', classNames: 'btn-danger btn-xs', tooltip: 'Delete', icon: 'fas fa-trash' },
{ action: 'Button1', classNames: 'btn-primary btn-xs', tooltip: 'Button1', icon: 'fas fa-wrench' },
{ action: 'Button2', classNames: 'btn-info btn-xs', tooltip: 'Button2', icon: 'fas fa-search-plus' },
{ action: 'Button3', classNames: 'btn-success btn-xs', tooltip: 'Button3', icon: 'fas fa-check-circle' },
{ action: 'Button4', classNames: 'btn-warning btn-xs', tooltip: 'Button4', icon: 'fas fa-exclamation-triangle' },
{ action: 'Button5', classNames: 'btn-danger btn-xs', tooltip: 'Button5', icon: 'fas fa-times-circle' },
{ action: 'Button6', classNames: 'btn-secondary btn-xs', tooltip: 'Button6', icon: 'fas fa-link' },
{ action: 'Button7', classNames: 'btn-primary btn-sm', tooltip: 'Button7', icon: 'fas fa-download' },
{ action: 'Button8', classNames: 'btn-info btn-sm', tooltip: 'Button8', icon: 'fas fa-file-pdf' },
{ action: 'Button9', classNames: 'btn-success btn-sm', tooltip: 'Button9', icon: 'fas fa-star' },
{ action: 'Button10', classNames: 'btn-danger btn-sm', tooltip: 'Button10', icon: 'fas fa-trash-alt' },
{ action: 'Button11', classNames: 'btn-primary btn-xs', tooltip: 'Button11', icon: 'fas fa-cog' },
{ action: 'Button12', classNames: 'btn-info btn-xs', tooltip: 'Button12', icon: 'fas fa-search' },
{ action: 'Button13', classNames: 'btn-success btn-xs', tooltip: 'Button13', icon: 'fas fa-thumbs-up' },
{ action: 'Button14', classNames: 'btn-warning btn-xs', tooltip: 'Button14', icon: 'fas fa-bell' },
{ action: 'Button15', classNames: 'btn-danger btn-xs', tooltip: 'Button15', icon: 'fas fa-ban' },
{ action: 'Button16', classNames: 'btn-secondary btn-xs', tooltip: 'Button16', icon: 'fas fa-link' },
{ action: 'Button17', classNames: 'btn-primary btn-sm', tooltip: 'Button17', icon: 'fas fa-file' },
{ action: 'Button18', classNames: 'btn-info btn-sm', tooltip: 'Button18', icon: 'fas fa-print' },
{ action: 'Button19', classNames: 'btn-success btn-sm', tooltip: 'Button19', icon: 'fas fa-heart' },
{ action: 'Button20', classNames: 'btn-danger btn-sm', tooltip: 'Button20', icon: 'fas fa-times' },
{ action: 'Button21', classNames: 'btn-primary btn-sm', tooltip: 'Button21', icon: 'fas fa-arrow-right' },
{ action: 'Button22', classNames: 'btn-info btn-sm', tooltip: 'Button22', icon: 'fas fa-arrow-left' },
{ action: 'Button23', classNames: 'btn-success btn-sm', tooltip: 'Button23', icon: 'fas fa-check' },
{ action: 'Button24', classNames: 'btn-warning btn-sm', tooltip: 'Button24', icon: 'fas fa-exclamation' },
{ action: 'Button25', classNames: 'btn-danger btn-sm', tooltip: 'Button25', icon: 'fas fa-times' },
{ action: 'Button26', classNames: 'btn-secondary btn-sm', tooltip: 'Button26', icon: 'fas fa-refresh' },
{ action: 'Button27', classNames: 'btn-primary btn-sm', tooltip: 'Button27', icon: 'fas fa-plus' },
{ action: 'Button28', classNames: 'btn-info btn-sm', tooltip: 'Button28', icon: 'fas fa-minus' },
{ action: 'Button29', classNames: 'btn-success btn-sm', tooltip: 'Button29', icon: 'fas fa-copy' },
{ action: 'Button30', classNames: 'btn-danger btn-sm', tooltip: 'Button30', icon: 'fas fa-share' }
];
// User-defined button configurations (if any)
const buttons = params.buttons || defaultButtons;
// Create a new container element to hold the buttons
const container = document.createElement('div');
container.style.display = 'flex';
container.style.flexWrap = 'wrap';
container.style.paddingTop = '3px';
buttons.forEach((buttonConfig) => {
const button = document.createElement('button');
button.classList.add('btn');
const classNames = buttonConfig.classNames.split(' ');
classNames.forEach((className) => button.classList.add(className));
button.setAttribute('data-toggle', 'tooltip');
// Call a function to get the dynamic tooltip content
if (buttonConfig.tooltip.endsWith('()')) {
const tooltipFunction = buttonConfig.tooltip.slice(0, -2);
const tooltipText = window[tooltipFunction](params.data)
button.setAttribute('title', tooltipText);
} else {
button.setAttribute('title', buttonConfig.tooltip);
}
button.innerHTML = `<i class="${buttonConfig.icon}"></i> ${buttonConfig.action}`;
container.appendChild(button);
// Handle dynamic classes based on conditions and buttonConfig.id
actionButtonClassToggles.forEach((toggle) => {
if (toggle.btn_id.toLowerCase() === buttonConfig.id && evaluateConditions([toggle.condition], params)) {
button.classList.add(...toggle.class.split(' '));
}
});
actionButtonIconClassToggles.forEach((iconToggle) => {
if (iconToggle.btn_id.toLowerCase() === buttonConfig.id && evaluateConditions([iconToggle.condition], params)) {
const iconElement = button.querySelector('i');
if (iconElement) {
iconElement.classList.add(...iconToggle.class.split(' '));
}
}
});
// Check if the button should be hidden based on the condition string and row data
if (buttonConfig.condition) {
const conditions = buttonConfig.condition.split(/(\|\||&&)/);
const isConditionMet = evaluateConditions(conditions, params);
if (!isConditionMet) {
button.style.setProperty('display', 'none', 'important');
}
}
button.addEventListener('click', function () {
if (typeof buttonConfig.onClick === 'function') {
buttonConfig.onClick(params.data);
}
});
});
// Add spacing between buttons (margin-right)
const buttonSpacing = '5px'; // You can adjust the spacing as needed
const buttonsInContainer = container.querySelectorAll('button');
for (let i = 0; i < buttonsInContainer.length - 1; i++) {
buttonsInContainer[i].style.marginRight = buttonSpacing;
}
return container;
}
function humanize(str) {
if (str == null) return str;
str = String(str)
.trim()
.replace(/([a-z\D])([A-Z]+)/g, '$1_$2')
.replace(/[-\s]+/g, '_')
.toLowerCase()
.replace(/_id$/, '')
.replace(/_/g, ' ')
.trim();
let words = str.split(' ');
words = words.map(word => word.charAt(0).toUpperCase() + word.substr(1));
return words.join(' ');
}
function blankOrNullValueFormatter(params) {
if (params.value == null) {
return "-";
}
if (typeof params.value === "string") {
return params.value.trim() === "" ? "-" : params.value;
}
if (typeof params.value === "object") {
try {
return JSON.stringify(params.value);
} catch (error) {
return "Object cannot be stringified";
}
}
return params.value;
}
function extractConditionParts(condition) {
const operators = ['===', '==', '!=', '>', '<', '>=', '<='];
let operator;
let left;
let right;
for (const op of operators) {
if (condition.includes(op)) {
operator = op;
const parts = condition.split(op).map(part => part.trim());
left = parts[0];
right = parts.slice(1).join(op).trim();
break;
}
}
if (!operator) {
throw new Error('Invalid operator in the condition.');
}
return [left, operator, right];
}
function evaluateConditions(conditions, params) {
let results = [];
let operators = [];
for (let i = 0; i < conditions.length; i++) {
const part = conditions[i].trim();
if (part === '||' || part === '&&') {
operators.push(part);
} else {
const hasOperator = /(==|!=|<=|>=|<|>)/.test(part);
if (!hasOperator) {
const left = part;
const result = params.data[left] !== null && params.data[left] !== undefined && params.data[left] !== "";
results.push(result);
} else {
const [left, operator, right] = extractConditionParts(part);
const result = params.data[left] !== null ? evaluateCondition(params.data[left], operator, right) : false;
results.push(result);
}
}
}
let finalResult = results[0];
for (let i = 0; i < operators.length; i++) {
if (operators[i] === '||') {
finalResult = finalResult || results[i + 1];
} else if (operators[i] === '&&') {
finalResult = finalResult && results[i + 1];
}
}
return finalResult;
}
function evaluateCondition(left, operator, right) {
switch (operator) {
case '===':
return left.toString() === right.toString();
case '==':
return left.toString() == right.toString();
case '!=':
return left.toString() != right.toString();
case '>':
return left.toString() > parseFloat(right);
case '<':
return left.toString() < parseFloat(right);
case '>=':
return left.toString() >= parseFloat(right);
case '<=':
return left.toString() <= parseFloat(right);
default:
return false;
}
}
function formatDate(timestamp) {
const format = options.date_format
const localDate = new Date(timestamp);
const y = localDate.getFullYear();
const n = localDate.getMonth();
const d = localDate.getDate();
const w = localDate.getDay();
const h = localDate.getHours();
const m = localDate.getMinutes();
const s = localDate.getSeconds();
function pad(num, length) {
return ('0000' + num).slice(-length);
}
return format.replace(/([yMdHhmsaAv])(\1+)?/g, part => {
switch (part) {
case 'yyyy':
return pad(y, 4);
case 'yy':
return pad(y, 2);
case 'y':
return y;
case 'MMMM':
return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][n];
case 'MMM':
return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][n];
case 'MM':
return pad(n + 1, 2);
case 'M':
return n + 1;
case 'dddd':
return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][w];
case 'ddd':
return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][w];
case 'dd':
return pad(d, 2);
case 'd':
return d;
case 'HH':
return pad(h, 2);
case 'H':
return h;
case 'hh':
return pad((h % 12) || 12, 2);
case 'h':
return (h % 12) || 12;
case 'mm':
return pad(m, 2);
case 'm':
return m;
case 'ss':
return pad(s, 2);
case 's':
return s;
case 'a':
return h < 12 ? 'am' : 'pm';
case 'A':
return h < 12 ? 'AM' : 'PM';
default:
return part; // Return unchanged for unknown format parts
}
});
}
function getDateForComparison(value, timezone) {
if (value) {
const date = new Date(value);
if (timezone) {
const options = {
timeZone: timezone,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
};
const convertedTimestamp = date.toLocaleString('en-US', options);
const [datePart, timePart] = convertedTimestamp.split(', ');
const [month, day, year] = datePart.split('/');
const [hours, minutes, seconds] = timePart.split(':');
return new Date(`${year}-${month}-${day}T${hours}:${minutes}:${seconds}`);
} else {
return date;
}
} else {
return null;
}
}
function formatTime(params, timezone) {
if (params.value) {
const date = new Date(params.value)
if (timezone) {
const tzOptions = {
timeZone: timezone
};
const convertedTimestamp = date.toLocaleString('en-GB', tzOptions);
const [datePart, timePart] = convertedTimestamp.split(', ');
const [day, month, year] = datePart.split('/');
const [hours, minutes, seconds] = timePart.split(':');
const dateTimezone = new Date(`${year}-${month}-${day}T${hours}:${minutes}:${seconds}`).getTime();
return formatDate(dateTimezone)
} else {
return formatDate(date);
}
}
else {
return '-'
}
}
// comparator for case-insensitive sorting
const caseInsensitiveComparator = (valueA, valueB) => {
// Check for null, undefined, or empty strings
if (valueA === null || valueA === undefined || valueA === '') {
return valueB === null || valueB === undefined || valueB === '' ? 0 : -1;
}
if (valueB === null || valueB === undefined || valueB === '') {
return 1;
}
// Convert values to numbers if they are numeric
const numA = Number(valueA);
const numB = Number(valueB);
// If both values are numbers
if (!isNaN(numA) && !isNaN(numB)) {
return numA - numB;
}
// Convert non-number values to strings for case-insensitive comparison
const strA = typeof valueA === 'string' ? valueA : String(valueA);
const strB = typeof valueB === 'string' ? valueB : String(valueB);
return strA.toLowerCase().localeCompare(strB.toLowerCase());
};
//Custom Row Styles
function createRowStyleFunction(rstyles) {
return function(params) {
if (!rstyles || !Array.isArray(rstyles) || rstyles.length === 0) {
return; // No styles to apply
}
const rowStyle = {};
for (const style of rstyles) {
const condition = style.condition.replace(/\(\)$/, ''); // Remove () if present at the end
const customColor = style.customColor;
let conditionResult;
if (typeof window[condition] === 'function') {
const result = window[condition](params.data);
if (typeof result !== 'boolean') {
console.error('Row condition function must return a boolean value.');
return;
}
conditionResult = result;
}
if (conditionResult) {
rowStyle.background = customColor;
}
}
return rowStyle;
};
}
dateFilterParams = {
comparator: function (filterLocalDateAtMidnight, cellValue) {
const cellDate = getDateForComparison(cellValue, timezone);
const filterDate = new Date(filterLocalDateAtMidnight);
// Compare the date portion of the cell value with the filter value