# easy-invoice/2.3.6/assets/js/addons-page.js

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.3.6. 137 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.3.6/code/assets/js/addons-page.js
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.3.6/raw/assets/js/addons-page.js
- Modified: 2026-05-21T08:29:24+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.3.6/code/assets/js/addons-page.js#L10-L20`.

```javascript
/* Easy Invoice — Addons page interactions */
(function ($) {
    'use strict';

    if (typeof window.EasyInvoiceAddons === 'undefined') return;
    var cfg = window.EasyInvoiceAddons;

    function setButtonLoading($btn, isLoading, loadingText) {
        if (isLoading) {
            $btn.data('orig-html', $btn.html());
            $btn.text(loadingText);
            $btn.addClass('is-loading').prop('disabled', true);
        } else {
            $btn.removeClass('is-loading').prop('disabled', false);
            var orig = $btn.data('orig-html');
            if (orig) $btn.html(orig);
        }
    }

    function toast(message, type) {
        type = type || 'info';
        if (typeof window.EasyInvoiceToast !== 'undefined' && window.EasyInvoiceToast[type]) {
            window.EasyInvoiceToast[type](message);
            return;
        }
        // Fallback: use WP admin notice if no toast helper
        alert(message);
    }

    function showUpgradeDialog($card, payload) {
        var featureName = $card.find('h3').first().text().trim();
        var description = $card.find('p').last().text().trim();
        var upgradeUrl  = payload.upgrade_url
            || $card.find('.ei-addons-btn--upgrade').data('upgrade-url')
            || 'https://matrixaddons.com/plugins/easy-invoice/#pricing';

        if (typeof window.EasyInvoiceConfirmation !== 'undefined' &&
            typeof window.EasyInvoiceConfirmation.showUpgradeDialog === 'function') {
            window.EasyInvoiceConfirmation.showUpgradeDialog({
                featureName: featureName + ' (' + (payload.required_plan_label || 'Pro') + ' plan)',
                description: description,
                onUpgrade: function () {
                    window.open(upgradeUrl, '_blank');
                }
            });
            return;
        }
        if (confirm(featureName + ' requires the ' + (payload.required_plan_label || 'Pro') + ' plan.\nOpen the upgrade page?')) {
            window.open(upgradeUrl, '_blank');
        }
    }

    // Returns the jQuery deferred so bulk callers can wait on completion
    // before reloading the page. When a bulk operation is in flight (the
    // bulk handler sets window.EasyInvoiceAddons.bulkInFlight = true), we
    // skip the per-toggle reload — the bulk handler will issue ONE reload
    // after all of its toggles resolve. Without this guard, the first
    // single-toggle AJAX to come back would window.location.reload() and
    // cancel every other in-flight bulk request.
    function toggleAddon($card, enable) {
        var addonId = $card.data('addon-id');
        var $btn    = $card.find('.ei-addons-btn--toggle');
        setButtonLoading($btn, true, enable ? cfg.strings.enabling : cfg.strings.disabling);

        return $.post(cfg.ajaxUrl, {
            action:   'easy_invoice_toggle_addon',
            _nonce:   cfg.nonce,
            addon_id: addonId,
            enabled:  enable ? 1 : 0
        }).done(function (resp) {
            setButtonLoading($btn, false);

            if (resp && resp.success) {
                toast(resp.data.message, 'success');
                if (!window.EasyInvoiceAddons || !window.EasyInvoiceAddons.bulkInFlight) {
                    setTimeout(function () { window.location.reload(); }, 600);
                }
                return;
            }
            var payload = (resp && resp.data) || {};
            if (payload.code === 'upgrade_required') {
                showUpgradeDialog($card, payload);
                return;
            }
            toast(payload.message || cfg.strings.genericError, 'error');
        }).fail(function () {
            setButtonLoading($btn, false);
            toast(cfg.strings.genericError, 'error');
        });
    }

    $(document).on('click', '.ei-addons-btn--toggle', function (e) {
        e.preventDefault();
        var $btn  = $(this);
        var $card = $btn.closest('.ei-addons-card');
        var action = $btn.data('action');
        toggleAddon($card, action === 'enable');
    });

    $(document).on('click', '.ei-addons-btn--upgrade', function (e) {
        e.preventDefault();
        var $btn  = $(this);
        var $card = $btn.closest('.ei-addons-card');
        showUpgradeDialog($card, {
            required_plan:       $btn.data('required-plan'),
            required_plan_label: $btn.data('required-plan-label'),
            upgrade_url:         $btn.data('upgrade-url')
        });
    });

    // Filter chips — swap Tailwind colour utilities to indicate active state
    var ACTIVE_CLASSES   = ['bg-gray-900', 'text-white'];
    var INACTIVE_CLASSES = ['bg-white', 'text-gray-700', 'border', 'border-gray-300', 'hover:bg-gray-50'];

    $(document).on('click', '#ei-addons-filters .ei-addons-chip', function () {
        var $chip  = $(this);
        var filter = $chip.data('filter');

        $('#ei-addons-filters .ei-addons-chip')
            .removeClass('is-active')
            .removeClass(ACTIVE_CLASSES.join(' '))
            .addClass(INACTIVE_CLASSES.join(' '));

        $chip
            .addClass('is-active')
            .removeClass(INACTIVE_CLASSES.join(' '))
            .addClass(ACTIVE_CLASSES.join(' '));

        $('#ei-addons-grid .ei-addons-card').each(function () {
            var $card = $(this);
            var match = (filter === 'all') || ($card.data('category') === filter);
            $card.toggleClass('is-hidden', !match);
        });
    });

})(jQuery);

```
