Advertisement
IDeckstein

Untitled

Sep 12th, 2023
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
jQuery 35.21 KB | None | 0 0
  1. jQuery(document).ready(function ($) {    
  2.  
  3.     //Date sort plugin
  4.     $.fn.dataTable.moment('x');
  5.  
  6.     // Main function to run when table exists on the page
  7.     if ($('#idemailwiz_campaign_table').length) {
  8.         idemailwiz_do_ajax('idwiz_get_campaign_table_view', idAjax_data_tables.nonce, {}, campaign_table_success_response, campaign_table_error_response);
  9.     }
  10.  
  11.     let table;
  12.  
  13.     // Success and Error Callbacks
  14.     function campaign_table_success_response(data) {
  15.         // Initialize DataTables with the parsed data
  16.         table = $('#idemailwiz_campaign_table').DataTable({
  17.             data: data,
  18.             order: [[3, 'asc'], [2, 'desc']],
  19.             autoWidth: false,
  20.             fixedColumns: { left: 2 },
  21.             columns: wizcampaigns_columns,
  22.             buttons: wizcampaigns_buttons,
  23.             language: wizcampaign_language,
  24.             dom: '<"#wiztable_top_wrapper"><"wiztable_toolbar" <"#wiztable_top_search" f><"#wiztable_top_dates">  B>t',
  25.             fixedHeader: { header: true, footer: false },
  26.             colReorder: { realtime: false },
  27.             scroller: true,
  28.             scrollX: true,
  29.             scrollY: '700px',
  30.             paging: true,
  31.             scrollResize: true,
  32.             scrollCollapse: true,
  33.             processing: true,
  34.             select: { selector: "td:not(:first-child)" },
  35.             stateRestore: {
  36.                 create: true,
  37.                 remove: true,
  38.                 rename: true,
  39.                 save: true
  40.             },
  41.             drawCallback: idwiz_dt_draw_callback,
  42.             initComplete: idwiz_dt_init_callback,
  43.         });
  44.  
  45.         // Event listeners to enable/disable "Actions" button
  46.         setupRowSelectionEvents(table);
  47.    
  48.         // Handle state save and restore
  49.         setupStateHandling(table);
  50.     }
  51.  
  52.     function campaign_table_error_response(errorThrown) {
  53.         console.log(errorThrown);
  54.     }
  55.  
  56.      // Handle state save and restore
  57.     function setupStateHandling(table) {
  58.        
  59.         table.on('stateSaveParams', function(e, settings, data) {
  60.             // Save the current values of the date pickers
  61.             data.startDate = $('#wiztable_startDate').val();
  62.             data.endDate = $('#wiztable_endDate').val();
  63.         });
  64.  
  65.         table.on('stateLoadParams', function(e, settings, data) {
  66.             // Delay the restoration of the date picker values
  67.             setTimeout(function() {
  68.                 $('#wiztable_startDate').val(data.startDate);
  69.                 $('#wiztable_endDate').val(data.endDate);
  70.             }, 500);
  71.         });  
  72.     }
  73.  
  74.  
  75.     // Event listeners to enable/disable "Actions" button
  76.     function setupRowSelectionEvents(table) {
  77.         table.on('select', function (e, dt, type, indexes) {
  78.             if (type === 'row') {
  79.                 table.button('Actions:name').enable();
  80.             }
  81.         });
  82.  
  83.         table.on('deselect', function (e, dt, type, indexes) {
  84.             if (type === 'row') {
  85.                 if (!table.rows({ selected: true }).any()) {
  86.                     table.button('Actions:name').disable();
  87.                 }
  88.             }
  89.         });
  90.     }
  91.  
  92.    
  93.  
  94.  
  95.     // Main Init callback function
  96.     function idwiz_dt_init_callback(settings, json) {
  97.         appendDateSelector();
  98.         addDateFilter();
  99.         addDateChangeListener();
  100.         addCampaignNavigation();
  101.     }
  102.  
  103.  
  104.     // Main draw callback function
  105.     function idwiz_dt_draw_callback(settings, json) {
  106.         var api = this.api();
  107.  
  108.         // Hide the loader and title
  109.         $('#idemailwiz_tableLoader').hide();
  110.         $('#saved_state_title').text('');
  111.  
  112.         // Move some buttons
  113.         moveButtons();
  114.  
  115.         // Create the counter column
  116.         updateCounterColumn(api);
  117.  
  118.         // Readjust the column widths
  119.         api.columns.adjust();
  120.  
  121.         // Get current record count and calculate totals and rates
  122.         var metrics = calculateMetrics(api);
  123.  
  124.         // Update the HTML element with the calculated total and rates
  125.         updateMetricsHTML(metrics);
  126.     }
  127.  
  128.     // Sync Button
  129.     $(document).on('click', '.sync-db', function() {
  130.         handle_idwiz_sync_buttons("idemailwiz_ajax_sync", idAjax_data_tables.nonce);
  131.     });
  132.  
  133.     let lastCallTime = 0;
  134.     const debounceTime = 500; // 500 milliseconds
  135.     // Custom function to handle Ajax for state saving and loading
  136.     function idwiz_handle_states(data, callback) {
  137.         const currentTime = Date.now();
  138.  
  139.         if (currentTime - lastCallTime < debounceTime) {
  140.             console.log("Function call debounced");
  141.             return;
  142.         }
  143.  
  144.         lastCallTime = currentTime;
  145.         console.log("idwiz_handle_states called with data:", data);
  146.        
  147.         // Include the action type in the data to be sent to the server
  148.         var ajaxData = {
  149.             dataTableAction: data.action, // This is the DataTables action like "load" or "save"
  150.             stateRestore: data.stateRestore
  151.         };
  152.  
  153.         idemailwiz_do_ajax(
  154.             'idwiz_handle_dt_states',
  155.             idAjax_data_tables.nonce,
  156.             ajaxData,
  157.             function(response) {
  158.                 console.log(response);
  159.                 if (data.action == 'load' && response.success) {
  160.                     callback(response.data); // Pass the state data back to DataTables
  161.                 } else {
  162.                     console.log('State action successful:', response);
  163.                     table.draw();
  164.                 }
  165.             },
  166.             function(error) {
  167.                 console.log('Error:', error);
  168.                 console.log('Status:', error.status);
  169.                 console.log('Status Text:', error.statusText);
  170.                 console.log('Response Text:', error.responseText);
  171.             }
  172.         );
  173.     }
  174.  
  175.     // Append date range into DataTables DOM
  176.     function appendDateSelector() {
  177.         var dateSelector = '<div id="idemailwiz_date_range"><label><input type="date" id="wiztable_startDate"></label>&nbsp;thru&nbsp;<label><input type="date" id="wiztable_endDate"></label></div>';
  178.         $('#wiztable_top_dates').append(dateSelector);
  179.     }
  180.  
  181.     // Add date filter search logic
  182.     function addDateFilter() {
  183.         $.fn.dataTable.ext.search.push(
  184.             function(settings, data, dataIndex, rowData) {
  185.                 var startDateInput = $('#wiztable_startDate').val();
  186.                 var endDateInput = $('#wiztable_endDate').val();
  187.    
  188.                 // Check if the date filter is being used
  189.                 if (startDateInput || endDateInput) {
  190.                     // Exclude records with "N/A" date
  191.                     if (!rowData.campaign_start) return false;
  192.    
  193.                     var campaignDate = new Date(parseInt(rowData.campaign_start)).toISOString().split('T')[0]; // UTC date string
  194.    
  195.                     if (startDateInput && campaignDate < startDateInput) return false;
  196.                     if (endDateInput && campaignDate > endDateInput) return false;
  197.                 }
  198.                 return true;
  199.             }
  200.         );
  201.     }
  202.  
  203.     // Refresh the table when the dates are changed
  204.     function addDateChangeListener() {
  205.         $('#wiztable_startDate, #wiztable_endDate').change(function() {
  206.             $('.idemailwiz_table').DataTable().draw();
  207.         });
  208.     }
  209.  
  210.     // Add click event to navigate to single campaign page
  211.     function addCampaignNavigation() {
  212.         $('.idemailwiz_table').on('click', 'td.details-control', function() {
  213.             var table = $('.idemailwiz_table').DataTable();
  214.             var tr = $(this).closest('tr');
  215.             var row = table.row(tr);
  216.  
  217.             // Access the campaign_id from the row's data
  218.             var campaignId = row.data().campaign_id;
  219.  
  220.             // Construct the URL
  221.             var url = "https://localhost/metrics/campaign/?id=" + campaignId;
  222.  
  223.             // Open the URL in a new tab
  224.             window.open(url, '_blank');
  225.         });
  226.     }
  227.  
  228.        
  229.  
  230.     // Function to move buttons to their respective locations
  231.     function moveButtons() {
  232.         var advSearch = $('.btn-advanced-search').closest('.dt-button');
  233.         advSearch.insertAfter('#wiztable_top_search');
  234.            
  235.         var FYbutton = $('.dt-button.fiscal-year')
  236.         var prevMonthButton = $('.dt-button.prev-month');
  237.         var thisMonthButton = $('.dt-button.current-month');
  238.         var nextMonthButton = $('.dt-button.next-month');
  239.         thisMonthButton.insertAfter('#wiztable_top_dates');
  240.         prevMonthButton.insertBefore(thisMonthButton);
  241.         nextMonthButton.insertAfter(thisMonthButton);
  242.            
  243.         FYbutton.insertAfter(nextMonthButton);
  244.     }
  245.  
  246.     // Function to update the counter column
  247.     function updateCounterColumn(api) {
  248.         var info = api.page.info();
  249.         var start = info.start;
  250.         api.column(0, { page: 'current' }).nodes().each(function (cell, i) {
  251.             cell.innerHTML = i + 1 + start;
  252.         });
  253.     }
  254.  
  255.     // Function to calculate metrics based on the DataTable API
  256.     function calculateMetrics(api) {
  257.         var metrics = [];
  258.  
  259.         // Define a function to calculate the sum of a column
  260.         var sumColumn = function(columnName) {
  261.             var data = api.column(columnName + ':name', {search:'applied'}).data();
  262.             if (data.toArray) {
  263.                 data = data.toArray();
  264.             }
  265.             return data.reduce(function(a, b) {
  266.                 return a + Number(b) || 0;
  267.             }, 0);
  268.         };
  269.  
  270.         // Define a function to calculate the ratio
  271.         var calculateRatio = function(numerator, denominator) {
  272.             return denominator ? (numerator / denominator) * 100 : 0;
  273.         };
  274.  
  275.         // Calculate the totals
  276.         var totalSends = sumColumn('unique_email_sends');
  277.         var totalDelivered = sumColumn('unique_delivered');
  278.         var totalOpens = sumColumn('unique_email_opens');
  279.         var totalClicks = sumColumn('unique_email_clicks');
  280.         var totalUnsubs = sumColumn('unique_unsubscribes');
  281.         var totalPurchases = sumColumn('unique_purchases');
  282.         var totalRevenue = sumColumn('revenue');
  283.  
  284.         // Calculate the rates
  285.         var openRate = calculateRatio(totalOpens, totalSends);
  286.         var delivRate = calculateRatio(totalDelivered, totalSends);
  287.         var clickRate = calculateRatio(totalClicks, totalSends);
  288.         var unsubRate = calculateRatio(totalUnsubs, totalSends);
  289.         var cto = calculateRatio(totalClicks, totalOpens);
  290.         var cvr = calculateRatio(totalPurchases, totalOpens);
  291.        
  292.         // Push metrics into the array
  293.         metrics.push({ label: 'Campaigns', value: api.rows({search:'applied'}).count().toLocaleString() });
  294.         metrics.push({ label: 'Sends', value: totalSends.toLocaleString() });
  295.         metrics.push({ label: 'Delivered', value: totalDelivered.toLocaleString() });
  296.         metrics.push({ label: 'Deliv. Rate', value: delivRate.toFixed(2) + '%' });
  297.         metrics.push({ label: 'Opens', value: totalOpens.toLocaleString() });
  298.         metrics.push({ label: 'Open Rate', value: openRate.toFixed(2) + '%' });
  299.         metrics.push({ label: 'Clicks', value: totalClicks.toLocaleString() });
  300.         metrics.push({ label: 'CTR', value: clickRate.toFixed(2) + '%' });
  301.         metrics.push({ label: 'CTO', value: cto.toFixed(2) + '%' });
  302.         metrics.push({ label: 'Unsubs', value: totalUnsubs.toLocaleString() });
  303.         metrics.push({ label: 'Unsub. Rate', value: unsubRate.toFixed(2) + '%' });
  304.         metrics.push({ label: 'Purchases', value: totalPurchases.toLocaleString() });
  305.         metrics.push({ label: 'Revenue', value: '$' + totalRevenue.toLocaleString() });
  306.         metrics.push({ label: 'CVR', value: cvr.toFixed(2) + '%' });
  307.  
  308.         return metrics;
  309.     }
  310.  
  311.  
  312.     // Function to update metrics HTML
  313.     function updateMetricsHTML(metrics) {
  314.         var html = '<table class="wiztable_view_metrics_table"><tr>';
  315.         metrics.forEach(function(metric) {
  316.             html += `<td><span class="metric_view_label">${metric.label}</span><span class="metric_view_value"> ${metric.value}</span></td>`;
  317.         });
  318.         html += '</tr></table>';
  319.         $('#wiztable_view_metrics').html(html);
  320.     }
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.     var wizcampaigns_columns = [
  328.         {
  329.             "className": 'row-counter',
  330.             "title": '#',
  331.             "name": 'row-counter',
  332.             "orderable": false,
  333.             "data": null,
  334.             "width": "20px",
  335.         },
  336.         {
  337.             "className": 'details-control customColName',
  338.             "title": '<i class="fa-solid fa-arrow-up-right-from-square"></i>',
  339.             "name": 'details-control',
  340.             "orderable": false,
  341.             "data": null,
  342.             "defaultContent": '<i class="fa-solid fa-circle-info"></i>',
  343.             "colvisName": 'Details'
  344.         },
  345.         {
  346.             "data": "campaign_start",
  347.             "name": "campaign_start",
  348.             "title": "Sent At",
  349.             "className": "idwiz_searchBuilder_enabled",
  350.             "searchBuilderType": "date",
  351.             "render": function(data) {
  352.                 return new Date(parseInt(data))
  353.                     .toLocaleString('en-US', {
  354.                     month: 'numeric',
  355.                     day: 'numeric',
  356.                     year: 'numeric',
  357.                     hour: 'numeric',
  358.                     minute: 'numeric',
  359.                     hour12: true  
  360.                     });
  361.                 },
  362.             "type": "date",
  363.         },
  364.         {
  365.             "data": "campaign_type",
  366.             "name": "campaign_type",
  367.             "title": "Type",
  368.             "className": "idwiz_searchBuilder_enabled",
  369.             "searchBuilderType": "string",
  370.         },
  371.         {
  372.             "data": "message_medium",
  373.             "name": "message_medium",
  374.             "title": "Medium",
  375.             "className": "idwiz_searchBuilder_enabled",
  376.             "searchBuilderType": "string",
  377.         },
  378.         {
  379.             "data": "campaign_name",
  380.             "name": "campaign_name",
  381.             "title": "Campaign Name",
  382.             "render": $.fn.dataTable.render.ellipsis(50, true),
  383.             "className": "idwiz_searchBuilder_enabled",
  384.             "searchBuilderType": "string",
  385.         },
  386.         {
  387.             "data": "campaign_labels",
  388.             "name": "campaign_labels",
  389.             "title": "Labels",
  390.             "className": "idwiz_searchBuilder_enabled",
  391.             "searchBuilderType": "string",
  392.         },
  393.         {
  394.             "data": "experiment_ids",
  395.             "name": "experiment_ids",
  396.             "title": '<i class="fa fa-flask"></i>',
  397.             "searchBuilderTitle": 'Has Experiment',
  398.             "searchBuilderType": "string",
  399.             "searchBuilder.defaultConditions": "==",
  400.             "className": "idwiz_searchBuilder_enabled customColName",
  401.             "type": "bool",
  402.             "render": function(data, type) {
  403.                 if (type === 'display') {
  404.                     return data ? '<i class="fa fa-flask"></i>' : '';
  405.                 }
  406.                 if (type === 'filter') {
  407.                     return !data ? 'True' : 'False';
  408.                 }
  409.                 return data;
  410.             },
  411.             "searchBuilder": {
  412.                 "orthogonal": {
  413.                     "search": "filter",
  414.                     "display": "filter",
  415.                 }
  416.             },
  417.             "colvisName": 'Has Experiment'
  418.         },
  419.         {
  420.             "data": "unique_email_sends",
  421.             "name": "unique_email_sends",
  422.             "title": "Sends",
  423.             "type": "num",
  424.             "render": $.fn.dataTable.render.number(',', ''),
  425.             "className": "idwiz_searchBuilder_enabled",
  426.             "searchBuilderType": "num-fmt",
  427.         },
  428.         {
  429.             "data": "unique_delivered",
  430.             "name": "unique_delivered",
  431.             "title": "Delivered",
  432.             "type": "num",
  433.             "render": $.fn.dataTable.render.number(',', ''),
  434.             "className": "idwiz_searchBuilder_enabled",
  435.             "searchBuilderType": "num-fmt",
  436.         },
  437.         {
  438.             "data": "wiz_delivery_rate",
  439.             "name": "wiz_delivery_rate",
  440.             "title": "Deliv. Rate",
  441.             "render": function (data) { return parseFloat(data).toFixed(2) + '%'; },
  442.             "className": "idwiz_searchBuilder_enabled",
  443.             "searchBuilderType": "num-fmt",
  444.         },
  445.         {
  446.             "data": "unique_email_opens",
  447.             "name": "unique_email_opens",
  448.             "title": "Opens",
  449.             "render": $.fn.dataTable.render.number(',', ''),
  450.             "className": "idwiz_searchBuilder_enabled",
  451.             "searchBuilderType": "num-fmt",
  452.         },
  453.         {
  454.             "data": "wiz_open_rate",
  455.             "name": "wiz_open_rate",
  456.             "title": "Open Rate",
  457.             "render": function (data) { return parseFloat(data).toFixed(2) + '%'; },
  458.             "className": "idwiz_searchBuilder_enabled",
  459.             "searchBuilderType": "num-fmt",
  460.         },
  461.         {
  462.             "data": "unique_email_clicks",
  463.             "name": "unique_email_clicks",
  464.             "title": "Clicks",
  465.             "render": $.fn.dataTable.render.number(',', ''),
  466.             "className": "idwiz_searchBuilder_enabled",
  467.             "searchBuilderType": "num-fmt",
  468.         },
  469.         {
  470.             "data": "wiz_ctr",
  471.             "name": "wiz_ctr",
  472.             "title": "CTR",
  473.             "render": function (data) { return parseFloat(data).toFixed(2) + '%'; },
  474.             "className": "idwiz_searchBuilder_enabled",
  475.             "searchBuilderType": "num-fmt",
  476.         },
  477.         {
  478.             "data": "wiz_cto",
  479.             "name": "wiz_cto",
  480.             "title": "CTO",
  481.             "render": function (data) { return parseFloat(data).toFixed(2) + '%'; },
  482.             "className": "idwiz_searchBuilder_enabled",
  483.             "searchBuilderType": "num-fmt",
  484.         },
  485.         {
  486.             "data": "unique_unsubscribes",
  487.             "name": "unique_unsubscribes",
  488.             "title": "Unsubs.",
  489.             "render": function(data, type, row) {
  490.                 return $.fn.dataTable.render.number(',', '').display(data);
  491.             },
  492.             "className": "idwiz_searchBuilder_enabled",
  493.             "searchBuilderType": "num-fmt",
  494.         },
  495.         {
  496.             "data": "wiz_unsub_rate",
  497.             "name": "wiz_unsub_rate",
  498.             "title": "Unsub. Rate",
  499.             "render": function (data) { return parseFloat(data).toFixed(2) + '%'; },
  500.             "className": "idwiz_searchBuilder_enabled",
  501.             "searchBuilderType": "num-fmt",
  502.         },
  503.         {
  504.             "data": "unique_purchases",
  505.             "name": "unique_purchases",
  506.             "title": "Purchases",
  507.             "render": function(data, type, row) {
  508.                 return $.fn.dataTable.render.number(',', '').display(data);
  509.             },
  510.             "className": "idwiz_searchBuilder_enabled",
  511.             "searchBuilderType": "num-fmt",
  512.         },
  513.         {
  514.             "data": "wiz_cvr",
  515.             "name": "wiz_cvr",
  516.             "title": "CVR",
  517.             "render": function (data) { return parseFloat(data).toFixed(2) + '%'; },
  518.             "className": "idwiz_searchBuilder_enabled",
  519.             "searchBuilderType": "num-fmt",
  520.         },
  521.         {
  522.             "data": "revenue",
  523.             "name": "revenue",
  524.             "title": "Revenue",
  525.             "render": function (data) { return '$' + parseFloat(data).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); },
  526.             "className": "idwiz_searchBuilder_enabled",
  527.             "searchBuilderType": "num-fmt",
  528.         },
  529.         {
  530.             "data": "template_subject",
  531.             "name": "template_subject",
  532.             "title": "Subject Line",
  533.             "render": $.fn.dataTable.render.ellipsis(40, true),
  534.             "className": "idwiz_searchBuilder_enabled",
  535.             "searchBuilderType": "string",
  536.         },
  537.         {
  538.             "data": "template_preheader",
  539.             "name": "template_preheader",
  540.             "title": "Pre Header",
  541.             "render": $.fn.dataTable.render.ellipsis(40, true),
  542.             "className": "idwiz_searchBuilder_enabled",
  543.             "searchBuilderType": "string",
  544.         },
  545.                
  546.         {
  547.             "data": "campaign_id",
  548.             "name": "campaign_id",
  549.             "title": "ID",
  550.             "className": "idwiz_searchBuilder_enabled",
  551.             "searchBuilderType": "num",
  552.             "searchBuilder.defaultConditions": "==",
  553.         },
  554.                
  555.     ];
  556.  
  557.     var wizcampaigns_buttons = [
  558.         {
  559.             extend: 'searchBuilder',
  560.             background: false,
  561.             text: '<i class="fa-solid fa-sliders"></i>',
  562.             className: 'btn-advanced-search wiz-dt-button',
  563.             attr: {
  564.                 'title': 'Advanced search and filter',
  565.             },
  566.             config: {
  567.                 columns: '.idwiz_searchBuilder_enabled',
  568.             },
  569.             // Add a class to the popover for SearchBuilder so we can resize it with CSS
  570.             action: function (e, dt, node, config) {
  571.                 this.popover(config._searchBuilder.getNode(), {
  572.                     collectionLayout: 'wiz_sbpopover'
  573.                 });
  574.                 // Need to redraw the contents to calculate the correct positions for the elements
  575.                 if (config._searchBuilder.s.topGroup !== undefined) {
  576.                     config._searchBuilder.s.topGroup.dom.container.trigger('dtsb-redrawContents');
  577.                 }
  578.                 if (config._searchBuilder.s.topGroup.s.criteria.length === 0) {
  579.                     $('.' + $.fn.dataTable.Group.classes.add).click();
  580.                 }
  581.             },
  582.                    
  583.  
  584.         },
  585.         {
  586.             text: '<i class="fa-solid fa-angle-left"></i>',
  587.             className: 'wiz-dt-button skinny prev-month',
  588.             action: function ( e, dt, node, config ) {
  589.                 var table = $('.idemailwiz_table').DataTable();
  590.                 table.button('.next-month').enable();  // Enable the "Next" button
  591.  
  592.                 var startDateStr = $('#wiztable_startDate').val();
  593.                 var startDate = startDateStr ? new Date(startDateStr) : new Date();
  594.                 startDate.setUTCHours(0, 0, 0, 0);
  595.  
  596.                 var today = new Date();
  597.                 today.setUTCHours(0, 0, 0, 0);
  598.  
  599.                 if (isNaN(startDate.getTime()) || !startDateStr) {
  600.                     startDate = new Date(Date.UTC(today.getUTCFullYear(), today.getUTCMonth(), 1));
  601.                 }
  602.  
  603.                 startDate.setUTCMonth(startDate.getUTCMonth() - 1);
  604.                 var endDate = new Date(Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth() + 1, 0));
  605.  
  606.                 $('#wiztable_startDate').val(startDate.toISOString().split('T')[0]);
  607.                 $('#wiztable_endDate').val(endDate.toISOString().split('T')[0]);
  608.                 $('#saved_state_title').text(`Custom View: ${startDate.toLocaleString('default', { month: 'long', timeZone: 'UTC' })}, ${startDate.getUTCFullYear()}`);
  609.                 table.draw();
  610.             }
  611.         },
  612.         {
  613.             text: function() {
  614.                 var today = new Date();
  615.                 var monthAbbr = today.toLocaleString('default', { month: 'short' });  // Get the three-letter abbreviation
  616.                 var yearTwoDigit = today.getFullYear() % 100;  // Get the last two digits of the year
  617.                 return `<i class="fa-regular fa-calendar"></i>&nbsp;&nbsp;${monthAbbr} '${yearTwoDigit}`;
  618.            },
  619.            action: function ( e, dt, node, config ) {
  620.                var today = new Date();
  621.                var firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
  622.                var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
  623.  
  624.                $('#wiztable_startDate').val(firstDayOfMonth.toISOString().split('T')[0]);
  625.                $('#wiztable_endDate').val(lastDayOfMonth.toISOString().split('T')[0]);
  626.                $('#saved_state_title').text(`Custom View: ${today.toLocaleString('default', { month: 'long' })}, ${today.getFullYear()}`);
  627.                $('.idemailwiz_table').DataTable().draw();
  628.            },
  629.            className: 'wiz-dt-button current-month',
  630.        },
  631.        {
  632.            text: '<i class="fa-solid fa-angle-right"></i>',
  633.            className: 'wiz-dt-button skinny next-month',
  634.            action: function ( e, dt, node, config ) {
  635.                var table = $('.idemailwiz_table').DataTable();
  636.  
  637.                var startDateStr = $('#wiztable_startDate').val();
  638.                var startDate = startDateStr ? new Date(startDateStr) : new Date();
  639.                startDate.setUTCHours(0, 0, 0, 0);
  640.  
  641.                var today = new Date();
  642.                today.setUTCHours(0, 0, 0, 0);
  643.  
  644.                if (isNaN(startDate.getTime()) || !startDateStr) {
  645.                    startDate = new Date(Date.UTC(today.getUTCFullYear(), today.getUTCMonth(), 1));
  646.                    table.button('.next-month').disable();  // Disable the "Next" button when fields are empty or unorthodox
  647.                    return;
  648.                }
  649.  
  650.                if (startDate.getUTCFullYear() < today.getUTCFullYear() || (startDate.getUTCFullYear() === today.getUTCFullYear() && startDate.getUTCMonth() < today.getUTCMonth())) {
  651.                    startDate.setUTCMonth(startDate.getUTCMonth() + 1);
  652.                    var endDate = new Date(Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth() + 1, 0));
  653.  
  654.                    $('#wiztable_startDate').val(startDate.toISOString().split('T')[0]);
  655.                    $('#wiztable_endDate').val(endDate.toISOString().split('T')[0]);
  656.                    $('#saved_state_title').text(`Custom View: ${startDate.toLocaleString('default', { month: 'long', timeZone: 'UTC' })}, ${startDate.getUTCFullYear()}`);
  657.                    table.draw();
  658.                }
  659.  
  660.                if (startDate.getUTCFullYear() === today.getUTCFullYear() && startDate.getUTCMonth() >= today.getUTCMonth()) {
  661.                    table.button('.next-month').disable();  // Disable the "Next" button
  662.                } else {
  663.                    table.button('.next-month').enable();  // Enable the "Next" button
  664.                }
  665.            }
  666.        },
  667.                
  668.        {
  669.            text: function() {
  670.                var today = new Date();
  671.                var year = today.getFullYear();
  672.        
  673.                // Fiscal year starts on November 1st of the previous year
  674.                if (today.getMonth() >= 10) {  // January is 0, November is 10
  675.                    year += 1;
  676.                }
  677.        
  678.                var yearTwoDigit = year % 100;
  679.                return `<i class="fa-regular fa-calendar"></i>&nbsp;&nbsp;FY '${yearTwoDigit}`;
  680.             },
  681.             action: function ( e, dt, node, config ) {
  682.                 var today = new Date();
  683.                 var fiscalYearStart = new Date(today.getFullYear(), 10, 1);  // Nov 1
  684.                 var fiscalYearEnd = new Date(today.getFullYear() + 1, 9, 31);  // Oct 31
  685.                 if (today < fiscalYearStart) {
  686.                     fiscalYearStart.setFullYear(fiscalYearStart.getFullYear() - 1);
  687.                     fiscalYearEnd.setFullYear(fiscalYearEnd.getFullYear() - 1);
  688.                 }
  689.                 $('#wiztable_startDate').val(fiscalYearStart.toISOString().split('T')[0]);
  690.                 $('#wiztable_endDate').val(fiscalYearEnd.toISOString().split('T')[0]);
  691.                 $('#saved_state_title').text(`Custom View: ${fiscalYearStart.getFullYear()} Fiscal Year`);
  692.                 $('.idemailwiz_table').DataTable().draw();
  693.             },
  694.             className: 'wiz-dt-button fiscal-year',
  695.         },
  696.  
  697.         {
  698.             extend: 'selected',
  699.             text: '<i class="fa-regular fa-plus"></i>',
  700.             name: 'Actions',
  701.             className: 'wiz-dt-button',
  702.             attr: {
  703.                 'title': 'Actions',
  704.             },
  705.             action: function(e, dt, node, config) {
  706.             // Retrieve selected row indices
  707.             let selectedRowIndices = dt.rows({ selected: true }).indexes().toArray();
  708.  
  709.             // Extract campaign IDs from selected rows
  710.             let selectedCampaignIds = selectedRowIndices.map(index => {
  711.                 return dt.cell(index, 'campaign_id:name').data();
  712.             });
  713.                    
  714.             Swal.fire({
  715.                 title: 'Add to Initiative',
  716.                 html: '<select id="initiative-select"></select>',
  717.                 showCancelButton: true,
  718.                 cancelButtonText: 'Cancel',
  719.                 confirmButtonText: 'Add campaigns',  
  720.                 preConfirm: () => {
  721.                 let selectedInitiative = $('#initiative-select').val();
  722.                     // Perform AJAX call to add campaigns to the selected initiative
  723.                     idemailwiz_do_ajax(
  724.                         'idemailwiz_add_remove_campaign_from_initiative',
  725.                         idAjax_data_tables.nonce,
  726.                         {
  727.                         initiative_id: selectedInitiative,
  728.                         campaign_ids: selectedCampaignIds,
  729.                         campaignAction: 'add',
  730.                         },
  731.                         function(successData) {
  732.                         console.log(successData);
  733.                         alert('Campaigns have been added to initiative!');
  734.                         },
  735.                         function(errorData) {
  736.                         // Handle error
  737.                         console.error("Failed to add campaigns to initiative", errorData);
  738.                         }
  739.                     );
  740.                 },
  741.                 didOpen: () => {
  742.                 $('#initiative-select').select2({
  743.                     minimumInputLength: 0,
  744.                     placeholder: "Search initiatives...",
  745.                     allowClear: true,
  746.                     ajax: {
  747.                     delay: 250,
  748.                     transport: function(params, success, failure) {
  749.                         idemailwiz_do_ajax(
  750.                         'idemailwiz_get_initiatives_for_select',
  751.                         idAjax_data_tables.nonce,
  752.                         {
  753.                             q: params.data.term,
  754.                         },
  755.                         function(data) {
  756.                             success({results: data});
  757.                         },
  758.                         function(error) {
  759.                             console.error("Failed to fetch initiatives", error);
  760.                             failure();
  761.                         }
  762.                         );
  763.                          }
  764.                      }
  765.                      });
  766.                     }
  767.                 });
  768.             }
  769.         },
  770.         {
  771.             text: '<i class="fa-solid fa-rotate"></i>',
  772.             className: 'wiz-dt-button sync-db sync-everything',
  773.             attr:  {
  774.                 "data-sync-db": "everything",
  775.                 "title": "Sync Databases"
  776.             },
  777.             autoClose: true,
  778.             background: false,
  779.         },
  780.         {
  781.             extend: 'spacer',
  782.             style: 'bar'
  783.         },                    
  784.         {
  785.             extend: 'collection',
  786.             text: '<i class="fa-solid fa-table-columns"></i>',
  787.             className: 'wiz-dt-button',
  788.             attr: {
  789.                 'title': 'Show/hide columns',
  790.             },
  791.             align: 'button-right',
  792.             buttons: [
  793.                 {
  794.                     extend: 'colvis',
  795.                     columnText: function ( dt, idx, title ) {
  796.                         if ( idx == dt.colReorder.transpose( 1 ) ) {
  797.                             return 'Info';
  798.                         }
  799.                         if ( idx == dt.colReorder.transpose( 7 ) ) {
  800.                             return 'Has Experiment';
  801.                         } else {
  802.                             return title;
  803.                         }
  804.                     }
  805.                 },
  806.                 {
  807.                     extend: 'colvisRestore',
  808.                     text: 'Restore Defaults',
  809.                     className: 'wizcols_restore',
  810.                     align: 'button-right',
  811.                 }
  812.             ],
  813.             background: false,
  814.         },
  815.         {
  816.             extend: 'collection',
  817.             text: '<i class="fa-regular fa-hand-pointer"></i>',
  818.             className: 'wiz-dt-button',
  819.             attr: {
  820.                 'title': 'Selection mode',
  821.             },
  822.             align: 'button-right',
  823.             autoClose: true,
  824.             buttons: [
  825.                 'selectNone',
  826.                 'selectRows',
  827.                 'selectColumns',
  828.                 'selectCells',
  829.             ],
  830.             background: false,
  831.         },
  832.         {
  833.             extend: 'spacer',
  834.             style: 'bar'
  835.         },
  836.                
  837.         {
  838.             extend: 'collection',
  839.             text: '<i class="fa-solid fa-floppy-disk"></i>',
  840.             className: 'wiz-dt-button saved-views',
  841.             attr: {
  842.             'title': 'View options',
  843.             },
  844.             align: 'button-right',
  845.             background: false,
  846.             buttons: [
  847.             {
  848.                 extend: 'createState',
  849.                 text: 'Create View',
  850.                 attr: {
  851.                 'title': 'Create View',
  852.                 },
  853.                 config: {    
  854.                 creationModal: true,
  855.                 }
  856.             },
  857.             {
  858.                 extend: 'savedStates',
  859.                 text: 'Saved Views',
  860.                 className: 'saved-views',
  861.                 background: false,
  862.                 attr: {
  863.                     'title': 'Saved Views',
  864.                 },
  865.                 config: {
  866.                     ajax: idwiz_handle_states
  867.                 }
  868.             }
  869.             ]
  870.         },
  871.                
  872.         {
  873.             extend: 'collection',
  874.             text: '<i class="fa-solid fa-file-arrow-down"></i>',
  875.             className: 'wiz-dt-button',
  876.             attr: {
  877.                 'title': 'Export current view',
  878.             },
  879.             align: 'button-right',
  880.             autoClose: true,
  881.             buttons: [
  882.                 'copy',
  883.                 'csv',
  884.                 'excel' ],
  885.             background: false,
  886.         },
  887.                
  888.  
  889.     ];
  890.  
  891.     var wizcampaign_language = {
  892.         buttons: {
  893.             createState: 'Create View',
  894.             removeState: 'Delete View',
  895.             renameState: 'Rename View',
  896.             savedStates: 'Saved Views',
  897.         },
  898.         stateRestore: {
  899.             creationModal:{
  900.                 title: 'Create new View',
  901.                 button: 'Create View'
  902.             },
  903.             emptyError: 'Please enter a valid name!',
  904.             removeError: 'Error removing View.',
  905.             removeTitle: 'Delete View'
  906.         },
  907.         searchBuilder: {
  908.             data: 'Select column...',
  909.             title: 'Advanced Campaign Filter',
  910.             button: {
  911.                 0: '<i class="fa-solid fa-sliders"></i> Filters',
  912.                 _: '<i class="fa-solid fa-sliders"></i> Filters (%d)'
  913.             },
  914.         },
  915.         search: '',
  916.         searchPlaceholder: 'Quick search',
  917.                
  918.     }
  919.  
  920. });
  921.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement