UNPKG

@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
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