installed plugin Easy Digital Downloads version 3.1.0.3

This commit is contained in:
2022-11-27 15:03:07 +00:00
committed by Gitium
parent 555673545b
commit c5dce2cec6
1200 changed files with 238970 additions and 0 deletions

View File

@ -0,0 +1,76 @@
/* global eddEmailTagsInserter, tb_remove, tb_position, send_to_editor, _, window, document */
/**
* Internal dependencies.
*/
import { searchItems } from './utils.js';
/**
* Make tags clickable and send them to the email content (wp_editor()).
*/
function setupEmailTags() {
// Find all of the buttons.
const insertButtons = document.querySelectorAll( '.edd-email-tags-list-button' );
if ( ! insertButtons ) {
return;
}
/**
* Listen for clicks on tag buttons.
*
* @param {object} node Button node.
*/
_.each( insertButtons, function( node ) {
/**
* Listen for clicks on tag buttons.
*/
node.addEventListener( 'click', function() {
// Close Thickbox.
tb_remove();
window.send_to_editor( node.dataset.to_insert );
} );
} );
}
/**
* Filter tags.
*/
function filterEmailTags() {
const filterInput = document.querySelector( '.edd-email-tags-filter-search' );
const tagItems = document.querySelectorAll( '.edd-email-tags-list-item' );
if ( ! filterInput ) {
return;
}
filterInput.addEventListener( 'keyup', function( event ) {
const searchTerm = event.target.value;
const foundTags = searchItems( eddEmailTagsInserter.items, searchTerm );
_.each( tagItems, function( node ) {
const found = _.findWhere( foundTags, { tag: node.dataset.tag } );
node.style.display = ! found ? 'none' : 'block';
} );
} );
}
/**
* DOM ready.
*/
document.addEventListener( 'DOMContentLoaded', function() {
// Resize Thickbox when media button is clicked.
const mediaButton = document.querySelector( '.edd-email-tags-inserter' );
if ( ! mediaButton ) {
return;
}
mediaButton.addEventListener( 'click', tb_position );
// Clickable tags.
setupEmailTags();
// Filterable tags.
filterEmailTags();
} );

View File

@ -0,0 +1,40 @@
/* global _ */
/**
* Filters an item list given a search term.
*
* @param {Array} items Item list
* @param {string} searchTerm Search term.
*
* @return {Array} Filtered item list.
*/
export const searchItems = function( items, searchTerm ) {
const normalizedSearchTerm = normalizeTerm( searchTerm );
const matchSearch = function( string ) {
return normalizeTerm( string ).indexOf( normalizedSearchTerm ) !== -1;
};
return _.filter( items, function( item ) {
return matchSearch( item.title ) || _.some( item.keywords, matchSearch );
} );
};
/**
* Converts the search term into a normalized term.
*
* @param {string} term The search term to normalize.
*
* @return {string} The normalized search term.
*/
export const normalizeTerm = function( term ) {
// Lowercase.
// Input: "MEDIA"
term = term.toLowerCase();
// Strip leading and trailing whitespace.
// Input: " media "
term = term.trim();
return term;
};

View File

@ -0,0 +1,75 @@
/* global EDDExtensionManager, ajaxurl */
; ( function ( document, $ ) {
'use strict';
$( '.edd-extension-manager__action' ).on( 'click', function ( e ) {
e.preventDefault();
var $btn = $( this ),
action = $btn.attr( 'data-action' ),
plugin = $btn.attr( 'data-plugin' ),
type = $btn.attr( 'data-type' ),
ajaxAction = '';
if ( $btn.attr( 'disabled' ) ) {
return;
}
switch ( action ) {
case 'activate':
ajaxAction = 'edd_activate_extension';
$btn.text( EDDExtensionManager.activating );
break;
case 'install':
ajaxAction = 'edd_install_extension';
$btn.text( EDDExtensionManager.installing );
break;
default:
return;
}
$btn.removeClass( 'button-primary' ).attr( 'disabled', true ).addClass( 'updating-message' );
var data = {
action: ajaxAction,
nonce: EDDExtensionManager.extension_manager_nonce,
plugin: plugin,
type: type,
pass: $btn.attr( 'data-pass' ),
id: $btn.attr( 'data-id' ),
product: $btn.attr( 'data-product' ),
};
$.post( ajaxurl, data )
.done( function ( res ) {
console.log( res );
var thisStep = $btn.closest( '.edd-extension-manager__step' );
if ( res.success ) {
var nextStep = thisStep.next();
if ( nextStep.length ) {
thisStep.fadeOut();
nextStep.prepend( '<div class="notice inline-notice notice-success"><p>' + res.data.message + '</p></div>' );
nextStep.fadeIn();
}
} else {
thisStep.fadeOut();
var message = res.data.message;
/**
* The install class returns an array of error messages, and res.data.message will be undefined.
* In that case, we'll use the standard failure messages.
*/
if ( ! message ) {
if ( 'plugin' !== type ) {
message = EDDExtensionManager.extension_install_failed;
} else {
message = EDDExtensionManager.plugin_install_failed;
}
}
thisStep.after( '<div class="notice inline-notice notice-warning"><p>' + message + '</p></div>' );
}
} );
} );
} )( document, jQuery );

View File

@ -0,0 +1,130 @@
jQuery( document ).ready( function ( $ ) {
/**
* Connect to PayPal
*/
$( '#edd-paypal-commerce-connect' ).on( 'click', function ( e ) {
e.preventDefault();
// Clear errors.
var errorContainer = $( '#edd-paypal-commerce-errors' );
errorContainer.empty().removeClass( 'notice notice-error' );
var button = document.getElementById( 'edd-paypal-commerce-connect' );
button.classList.add( 'updating-message' );
button.disabled = true;
$.post( ajaxurl, {
action: 'edd_paypal_commerce_connect',
_ajax_nonce: $( this ).data( 'nonce' )
}, function( response ) {
if ( ! response.success ) {
console.log( 'Connection failure', response.data );
button.classList.remove( 'updating-message' );
button.disabled = false;
// Set errors.
errorContainer.html( '<p>' + response.data + '</p>' ).addClass( 'notice notice-error' );
return;
}
var paypalLinkEl = document.getElementById( 'edd-paypal-commerce-link' );
paypalLinkEl.href = response.data.signupLink + '&displayMode=minibrowser';
paypalLinkEl.click();
} );
} );
/**
* Checks the PayPal connection & webhook status.
*/
function eddPayPalGetAccountStatus() {
var accountInfoEl = document.getElementById( 'edd-paypal-commerce-connect-wrap' );
if ( accountInfoEl ) {
$.post( ajaxurl, {
action: 'edd_paypal_commerce_get_account_info',
_ajax_nonce: accountInfoEl.getAttribute( 'data-nonce' )
}, function( response ) {
var newHtml = '<p>' + eddPayPalConnectVars.defaultError + '</p>';
if ( response.success ) {
newHtml = response.data.account_status;
if ( response.data.actions && response.data.actions.length ) {
newHtml += '<p class="edd-paypal-connect-actions">' + response.data.actions.join( ' ' ) + '</p>';
}
} else if ( response.data && response.data.message ) {
newHtml = response.data.message;
}
accountInfoEl.innerHTML = newHtml;
// Remove old status messages.
accountInfoEl.classList.remove( 'notice-success', 'notice-warning', 'notice-error' );
// Add new one.
var newClass = response.success && response.data.status ? 'notice-' + response.data.status : 'notice-error';
accountInfoEl.classList.add( newClass );
} );
}
}
eddPayPalGetAccountStatus();
/**
* Create webhook
*/
$( document ).on( 'click', '.edd-paypal-connect-action', function ( e ) {
e.preventDefault();
var button = $( this );
button.prop( 'disabled', true );
button.addClass( 'updating-message' );
var errorWrap = $( '#edd-paypal-commerce-connect-wrap' ).find( '.edd-paypal-actions-error-wrap' );
if ( errorWrap.length ) {
errorWrap.remove();
}
$.post( ajaxurl, {
action: button.data( 'action' ),
_ajax_nonce: button.data( 'nonce' )
}, function( response ) {
button.prop( 'disabled', false );
button.removeClass( 'updating-message' );
if ( response.success ) {
button.addClass( 'updated-message' );
// Refresh account status.
eddPayPalGetAccountStatus();
} else {
button.parent().after( '<p class="edd-paypal-actions-error-wrap">' + response.data + '</p>' );
}
} );
} );
} );
window.eddPayPalOnboardingCallback = function eddPayPalOnboardingCallback( authCode, shareId ) {
var connectButton = document.getElementById( 'edd-paypal-commerce-connect' );
var errorContainer = document.getElementById( 'edd-paypal-commerce-errors' );
jQuery.post( ajaxurl, {
action: 'edd_paypal_commerce_get_access_token',
auth_code: authCode,
share_id: shareId,
_ajax_nonce: connectButton.getAttribute( 'data-nonce' )
}, function( response ) {
connectButton.classList.remove( 'updating-message' );
if ( ! response.success ) {
connectButton.disabled = false;
errorContainer.innerHTML = '<p>' + response.data + '</p>';
errorContainer.classList.add( 'notice notice-error' );
return;
}
connectButton.classList.add( 'updated-message' );
window.location.reload();
} );
}

View File

@ -0,0 +1,168 @@
import { recaptureRemoteInstall } from './recapture';
import './gateways/paypal';
/**
* Settings screen JS
*/
const EDD_Settings = {
init: function() {
this.general();
this.misc();
this.gateways();
this.emails();
},
general: function() {
const edd_color_picker = $( '.edd-color-picker' );
if ( edd_color_picker.length ) {
edd_color_picker.wpColorPicker();
}
// Settings Upload field JS
if ( typeof wp === 'undefined' || '1' !== edd_vars.new_media_ui ) {
// Old Thickbox uploader
const edd_settings_upload_button = $( '.edd_settings_upload_button' );
if ( edd_settings_upload_button.length > 0 ) {
window.formfield = '';
$( document.body ).on( 'click', edd_settings_upload_button, function( e ) {
e.preventDefault();
window.formfield = $( this ).parent().prev();
window.tbframe_interval = setInterval( function() {
jQuery( '#TB_iframeContent' ).contents().find( '.savesend .button' ).val( edd_vars.use_this_file ).end().find( '#insert-gallery, .wp-post-thumbnail' ).hide();
}, 2000 );
tb_show( edd_vars.add_new_download, 'media-upload.php?TB_iframe=true' );
} );
window.edd_send_to_editor = window.send_to_editor;
window.send_to_editor = function( html ) {
if ( window.formfield ) {
imgurl = $( 'a', '<div>' + html + '</div>' ).attr( 'href' );
window.formfield.val( imgurl );
window.clearInterval( window.tbframe_interval );
tb_remove();
} else {
window.edd_send_to_editor( html );
}
window.send_to_editor = window.edd_send_to_editor;
window.formfield = '';
window.imagefield = false;
};
}
} else {
// WP 3.5+ uploader
var file_frame;
window.formfield = '';
$( document.body ).on( 'click', '.edd_settings_upload_button', function( e ) {
e.preventDefault();
const button = $( this );
window.formfield = $( this ).parent().prev();
// If the media frame already exists, reopen it.
if ( file_frame ) {
//file_frame.uploader.uploader.param( 'post_id', set_to_post_id );
file_frame.open();
return;
}
// Create the media frame.
file_frame = wp.media.frames.file_frame = wp.media( {
title: button.data( 'uploader_title' ),
library: { type: 'image' },
button: { text: button.data( 'uploader_button_text' ) },
multiple: false,
} );
file_frame.on( 'menu:render:default', function( view ) {
// Store our views in an object.
const views = {};
// Unset default menu items
view.unset( 'library-separator' );
view.unset( 'gallery' );
view.unset( 'featured-image' );
view.unset( 'embed' );
// Initialize the views in our view object.
view.set( views );
} );
// When an image is selected, run a callback.
file_frame.on( 'select', function() {
const selection = file_frame.state().get( 'selection' );
selection.each( function( attachment, index ) {
attachment = attachment.toJSON();
window.formfield.val( attachment.url );
} );
} );
// Finally, open the modal
file_frame.open();
} );
// WP 3.5+ uploader
var file_frame;
window.formfield = '';
}
},
misc: function() {
const downloadMethod = $( 'select[name="edd_settings[download_method]"]' ),
symlink = downloadMethod.parent().parent().next();
// Hide Symlink option if Download Method is set to Direct
if ( downloadMethod.val() === 'direct' ) {
symlink.css( 'opacity', '0.4' );
symlink.find( 'input' ).prop( 'checked', false ).prop( 'disabled', true );
}
// Toggle download method option
downloadMethod.on( 'change', function() {
if ( $( this ).val() === 'direct' ) {
symlink.css( 'opacity', '0.4' );
symlink.find( 'input' ).prop( 'checked', false ).prop( 'disabled', true );
} else {
symlink.find( 'input' ).prop( 'disabled', false );
symlink.css( 'opacity', '1' );
}
} );
},
gateways: function() {
$( '#edd-payment-gateways input[type="checkbox"]' ).on( 'change', function() {
const gateway = $( this ),
gateway_key = gateway.data( 'gateway-key' ),
default_gateway = $( '#edd_settings\\[default_gateway\\]' ),
option = default_gateway.find( 'option[value="' + gateway_key + '"]' );
// Toggle enable/disable based
option.prop( 'disabled', function( i, v ) {
return ! v;
} );
// Maybe deselect
if ( option.prop( 'selected' ) ) {
option.prop( 'selected', false );
}
default_gateway.trigger( 'chosen:updated' );
} );
},
emails: function() {
$('#edd-recapture-connect').on('click', function(e) {
e.preventDefault();
$(this).html( edd_vars.wait + ' <span class="edd-loading"></span>' );
document.body.style.cursor = 'wait';
recaptureRemoteInstall();
});
}
};
jQuery( document ).ready( function( $ ) {
EDD_Settings.init();
} );

View File

@ -0,0 +1,18 @@
export const recaptureRemoteInstall = () => {
var data = {
'action': 'edd_recapture_remote_install',
};
jQuery.post( ajaxurl, data, function( response ) {
if( ! response.success ) {
if( confirm( response.data.error ) ) {
location.reload();
return;
}
}
window.location.href = 'https://recapture.io/register';
});
}

View File

@ -0,0 +1,24 @@
/* global Backbone */
/**
* Internal dependencies.
*/
import TaxRate from './../models/tax-rate.js';
/**
* A collection of multiple tax rates.
*/
const TaxRates = Backbone.Collection.extend( {
// Map the model.
model: TaxRate,
/**
* Set initial state.
*/
initialize: function() {
this.showAll = false;
this.selected = [];
},
} );
export default TaxRates;

View File

@ -0,0 +1,47 @@
/* global _, eddTaxRates */
/**
* Internal dependencies.
*/
import TaxRate from './models/tax-rate.js';
import TaxRates from './collections/tax-rates.js';
import Manager from './views/manager.js';
import { jQueryReady } from 'utils/jquery.js';
/**
* DOM ready.
*/
jQueryReady( () => {
// Show notice if taxes are not enabled.
const noticeEl = document.getElementById( 'edd-tax-disabled-notice' );
if ( noticeEl ) {
noticeEl.classList.add( 'notice' );
noticeEl.classList.add( 'notice-warning' );
}
// Start manager with a blank collection.
const manager = new Manager( {
collection: new TaxRates(),
} );
const rates = [];
// Normalize rate data.
_.each( eddTaxRates.rates, ( rate ) => rates.push( {
id: rate.id,
country: rate.name,
region: rate.description,
global: 'country' === rate.scope,
amount: rate.amount,
status: rate.status,
} ) );
// Add initial rates.
manager.collection.set( rates, {
silent: true,
} );
// Render manager.
manager.render();
} );

View File

@ -0,0 +1,34 @@
/* global Backbone */
/**
* Model a tax rate.
*/
const TaxRate = Backbone.Model.extend( {
defaults: {
id: '',
country: '',
region: '',
global: true,
amount: 0,
status: 'active',
unsaved: false,
selected: false,
},
/**
* Format a rate amount (adds a %)
*
* @todo This should support dynamic decimal types.
*/
formattedAmount: function() {
let amount = 0;
if ( this.get( 'amount' ) ) {
amount = parseFloat( this.get( 'amount' ) ).toFixed( 2 );
}
return `${ amount }%`;
},
} );
export default TaxRate;

View File

@ -0,0 +1,55 @@
/* global wp, _ */
/**
* Apply bulk actions.
*/
const BulkActions = wp.Backbone.View.extend( {
// See https://codex.wordpress.org/Javascript_Reference/wp.template
template: wp.template( 'edd-admin-tax-rates-table-bulk-actions' ),
// Watch events.
events: {
'click .edd-admin-tax-rates-table-filter': 'filter',
'change .edd-admin-tax-rates-table-hide input': 'showHide',
},
/**
* Bulk actions for selected items.
*
* Currently only supports changing the status.
*
* @param {Object} event Event.
*/
filter: function( event ) {
event.preventDefault();
// @hack - need to access the DOM directly here because the dropdown is not tied to the button event.
const status = document.getElementById( 'edd-admin-tax-rates-table-bulk-actions' );
_.each( this.collection.selected, ( cid ) => {
const model = this.collection.get( {
cid: cid,
} );
model.set( 'status', status.value );
} );
this.collection.trigger( 'filtered' );
},
/**
* Toggle show active/inactive rates.
*
* @param {Object} event Event.
*/
showHide: function( event ) {
this.collection.showAll = event.target.checked;
// @hack -- shouldn't access this table directly.
document.getElementById( 'edd_tax_rates' ).classList.toggle( 'has-inactive', this.collection.showAll );
this.collection.trigger( 'filtered' );
},
} );
export default BulkActions;

View File

@ -0,0 +1,65 @@
/* global wp */
/**
* Internal dependencies.
*/
import Table from './table.js';
import BulkActions from './bulk-actions.js';
/**
* Manage tax rates.
*/
const Manager = wp.Backbone.View.extend( {
// Append to this element.
el: '#edd-admin-tax-rates',
/**
* Set bind changes to collection.
*/
initialize: function() {
this.listenTo( this.collection, 'add change', this.makeDirty );
// Clear unload confirmation when submitting parent form.
document.querySelector( '.edd-settings-form #submit' ).addEventListener( 'click', this.makeClean );
},
/**
* Output the manager.
*/
render: function() {
this.views.add( new BulkActions( {
collection: this.collection,
} ) );
this.views.add( new Table( {
collection: this.collection,
} ) );
},
/**
* Collection has changed so warn the user before exiting.
*/
makeDirty: function() {
window.onbeforeunload = this.confirmUnload;
},
/**
* When submitting the main form remove the dirty check.
*/
makeClean: function() {
window.onbeforeunload = null;
},
/**
* Confirm page unload.
*
* @param {Object} event Close event.
*/
confirmUnload: function( event ) {
event.preventDefault();
return '';
},
} );
export default Manager;

View File

@ -0,0 +1,38 @@
/* global wp, _ */
/**
* Internal dependencies.
*/
import { getChosenVars } from 'utils/chosen.js';
const RegionField = wp.Backbone.View.extend( {
/**
* Bind passed arguments.
*
* @param {Object} options Extra options passed.
*/
initialize: function( options ) {
_.extend( this, options );
},
/**
* Create a list of options.
*/
render: function() {
if ( this.global ) {
return;
}
if ( 'nostates' === this.states ) {
this.setElement( '<input type="text" id="tax_rate_region" />' );
} else {
this.$el.html( this.states );
this.$el.find( 'select' ).each( function() {
const el = $( this );
el.chosen( getChosenVars( el ) );
} );
}
},
} );
export default RegionField;

View File

@ -0,0 +1,236 @@
/* global wp */
/**
* Internal dependencies.
*/
import TaxRate from './../models/tax-rate.js';
import RegionField from './../views/region-field.js';
import { getChosenVars } from 'utils/chosen.js';
/**
* Add a new rate "form".
*/
const TableAdd = wp.Backbone.View.extend( {
// Use <tfoot>
tagName: 'tfoot',
// Set class.
className: 'add-new',
// See https://codex.wordpress.org/Javascript_Reference/wp.template
template: wp.template( 'edd-admin-tax-rates-table-add' ),
// Watch events.
events: {
'click button': 'addTaxRate',
'keypress': 'maybeAddTaxRate',
'change #tax_rate_country': 'setCountry',
// Can be select or input.
'keyup #tax_rate_region': 'setRegion',
'change #tax_rate_region': 'setRegion',
'change input[type="checkbox"]': 'setGlobal',
// Can be click increase or keyboard.
'keyup #tax_rate_amount': 'setAmount',
'change #tax_rate_amount': 'setAmount',
},
/**
* Set initial state and bind changes to model.
*/
initialize: function() {
this.model = new TaxRate( {
global: true,
unsaved: true,
} );
this.listenTo( this.model, 'change:country', this.updateRegion );
this.listenTo( this.model, 'change:global', this.updateRegion );
},
/**
* Render. Only overwritten so we can reinit chosen once cleared.
*/
render: function() {
wp.Backbone.View.prototype.render.apply( this, arguments );
this.$el.find( 'select' ).each( function() {
const el = $( this );
el.chosen( getChosenVars( el ) );
} );
return this;
},
/**
* Show a list of states or an input field.
*/
updateRegion: function() {
const self = this;
const data = {
action: 'edd_get_shop_states',
country: this.model.get( 'country' ),
nonce: eddTaxRates.nonce,
field_name: 'tax_rate_region',
};
$.post( ajaxurl, data, function( response ) {
self.views.set( '#tax_rate_region_wrapper', new RegionField( {
states: response,
global: self.model.get( 'global' ),
} ) );
} );
},
/**
* Set a country value.
*
* @param {Object} event Event.
*/
setCountry: function( event ) {
let country = event.target.options[ event.target.selectedIndex ].value;
let regionGlobalCheckbox = document.getElementById( "tax_rate_region_global" );
if ( 'all' === country ) {
country = '*';
regionGlobalCheckbox.checked = true;
this.model.set( 'region', '' );
this.model.set( 'global', true );
regionGlobalCheckbox.readOnly = true;
regionGlobalCheckbox.disabled = true;
} else {
regionGlobalCheckbox.disabled = false;
regionGlobalCheckbox.readOnly = false;
}
this.model.set( 'country', country );
},
/**
* Set a region value.
*
* @param {Object} event Event.
*/
setRegion: function( event ) {
let value = false;
if ( event.target.value ) {
value = event.target.value;
} else {
value = event.target.options[ event.target.selectedIndex ].value;
}
this.model.set( 'region', value );
},
/**
* Set a global scope.
*
* @param {Object} event Event.
*/
setGlobal: function( event ) {
let isChecked = event.target.checked;
this.model.set( 'global', isChecked );
if ( true === isChecked ) {
this.model.set( 'region', '' );
}
},
/**
* Set an amount value.
*
* @param {Object} event Event.
*/
setAmount: function( event ) {
this.model.set( 'amount', event.target.value );
},
/**
* Monitors keyepress for "Enter" key.
*
* We cannot use the `submit` event because we cannot nest <form>
* elements inside the settings API.
*
* @param {Object} event Keypress event.
*/
maybeAddTaxRate: function( event ) {
if ( 13 !== event.keyCode ) {
return;
}
this.addTaxRate( event );
},
/**
* Add a single rate when the "form" is submitted.
*
* @param {Object} event Event.
*/
addTaxRate: function( event ) {
event.preventDefault();
const { i18n } = eddTaxRates;
if ( ! this.model.get( 'country' ) ) {
alert( i18n.emptyCountry );
return;
}
let addingRegion = this.model.get( 'region' );
let addingCountry = this.model.get( 'country' );
let addingGlobal = '' === this.model.get( 'region' );
// For the purposes of this query, the * is really an empty query.
if ( '*' === addingCountry ) {
addingCountry = '';
addingRegion = '';
addingGlobal = false;
}
const existingCountryWide = this.collection.where( {
region: addingRegion,
country: addingCountry,
global: addingGlobal,
status: 'active',
} );
if ( existingCountryWide.length > 0 ) {
const countryString = '' === addingCountry
? '*'
: addingCountry;
const regionString = '' === addingRegion
? ''
: ': ' + addingRegion;
const taxRateString = countryString + regionString;
alert( i18n.duplicateRate.replace( '%s', `"${ taxRateString }"` ) );
return;
}
if ( this.model.get( 'amount' ) <= 0 ) {
alert( i18n.emptyTax );
return;
}
// Merge cid as ID to make this a unique model.
this.collection.add( _.extend(
this.model.attributes,
{
id: this.model.cid,
}
) );
this.render();
this.initialize();
},
} );
export default TableAdd;

View File

@ -0,0 +1,33 @@
/* global wp, _ */
/**
* Output a table header and footer.
*/
const TableMeta = wp.Backbone.View.extend( {
// See https://codex.wordpress.org/Javascript_Reference/wp.template
template: wp.template( 'edd-admin-tax-rates-table-meta' ),
// Watch events.
events: {
'change [type="checkbox"]': 'selectAll',
},
/**
* Select all items in the collection.
*
* @param {Object} event Event.
*/
selectAll: function( event ) {
const checked = event.target.checked;
_.each( this.collection.models, ( model ) => {
// Check individual models.
model.set( 'selected', checked );
// Add to global selection.
this.collection.selected.push( model.cid );
} );
},
} );
export default TableMeta;

View File

@ -0,0 +1,17 @@
/* global wp */
/**
* Empty tax rates table.
*/
const TableRowEmpty = wp.Backbone.View.extend( {
// Insert as a <tr>
tagName: 'tr',
// Set class.
className: 'edd-tax-rate-row edd-tax-rate-row--is-empty',
// See https://codex.wordpress.org/Javascript_Reference/wp.template
template: wp.template( 'edd-admin-tax-rates-table-row-empty' ),
} );
export default TableRowEmpty;

View File

@ -0,0 +1,119 @@
/* global wp, _ */
/**
* A row inside a table of rates.
*/
const TableRow = wp.Backbone.View.extend( {
// Insert as a <tr>
tagName: 'tr',
// Set class.
className: function() {
return 'edd-tax-rate-row edd-tax-rate-row--' + this.model.get( 'status' );
},
// See https://codex.wordpress.org/Javascript_Reference/wp.template
template: wp.template( 'edd-admin-tax-rates-table-row' ),
// Watch events.
events: {
'click .remove': 'removeRow',
'click .activate': 'activateRow',
'click .deactivate': 'deactivateRow',
'change [type="checkbox"]': 'selectRow',
},
/**
* Bind model to view.
*/
initialize: function() {
this.listenTo( this.model, 'change', this.render );
},
/**
* Render
*/
render: function() {
this.$el.html( this.template( {
...this.model.toJSON(),
formattedAmount: this.model.formattedAmount(),
} ) );
// Ensure the wrapper class has the new name.
this.$el.attr( 'class', _.result( this, 'className' ) );
},
/**
* Remove a rate (can only be done if it has not been saved to the database).
*
* Don't use this.model.destroy() to avoid sending a DELETE request.
*
* @param {Object} event Event.
*/
removeRow: function( event ) {
event.preventDefault();
this.collection.remove( this.model );
},
/**
* Activate a rate.
*
* @param {Object} event Event.
*/
activateRow: function( event ) {
event.preventDefault();
const { i18n } = eddTaxRates;
const existingCountryWide = this.collection.where( {
region: this.model.get( 'region' ),
country: this.model.get( 'country' ),
global: '' === this.model.get( 'region' ),
status: 'active',
} );
if ( existingCountryWide.length > 0 ) {
const regionString = '' === this.model.get( 'region' )
? ''
: ': ' + this.model.get( 'region' );
const taxRateString = this.model.get( 'country' ) + regionString;
alert( i18n.duplicateRate.replace( '%s', `"${ taxRateString }"` ) );
return;
}
this.model.set( 'status', 'active' );
},
/**
* Deactivate a rate.
*
* @param {Object} event Event.
*/
deactivateRow: function( event ) {
event.preventDefault();
this.model.set( 'status', 'inactive' );
},
/**
* Select or deselect for bulk actions.
*
* @param {Object} event Event.
*/
selectRow: function( event ) {
const checked = event.target.checked;
if ( ! checked ) {
this.collection.selected = _.reject( this.collection.selected, ( cid ) => {
return cid === this.model.cid;
} );
} else {
this.collection.selected.push( this.model.cid );
}
},
} );
export default TableRow;

View File

@ -0,0 +1,65 @@
/* global wp, _ */
/**
* Internal dependencies.
*/
import TableRowEmpty from './table-row-empty.js';
import TableRow from './table-row.js';
/**
* A bunch of rows inside a table of rates.
*/
const TableRows = wp.Backbone.View.extend( {
// Insert as a <tbody>
tagName: 'tbody',
/**
* Bind events to collection.
*/
initialize: function() {
this.listenTo( this.collection, 'add', this.render );
this.listenTo( this.collection, 'remove', this.render );
this.listenTo( this.collection, 'filtered change', this.filtered );
},
/**
* Render a collection of rows.
*/
render: function() {
// Clear to handle sorting.
this.views.remove();
// Show empty placeholder.
if ( 0 === this.collection.models.length ) {
return this.views.add( new TableRowEmpty() );
}
// Add items.
_.each( this.collection.models, ( rate ) => {
this.views.add( new TableRow( {
collection: this.collection,
model: rate,
} ) );
} );
},
/**
* Show an empty state if all items are deactivated.
*/
filtered: function() {
const disabledRates = this.collection.where( {
status: 'inactive',
} );
// Check if all rows are invisible, and show the "No Items" row if so
if ( disabledRates.length === this.collection.models.length && ! this.collection.showAll ) {
this.views.add( new TableRowEmpty() );
// Possibly re-render the view
} else {
this.render();
}
},
} );
export default TableRows;

View File

@ -0,0 +1,50 @@
/* global wp */
/**
* Internal dependencies.
*/
import TableMeta from './table-meta.js';
import TableRows from './table-rows.js';
import TableAdd from './table-add.js';
/**
* Manage the tax rate rows in a table.
*/
const Table = wp.Backbone.View.extend( {
// Render as a <table> tag.
tagName: 'table',
// Set class.
className: 'wp-list-table widefat fixed tax-rates',
// Set ID.
id: 'edd_tax_rates',
/**
* Output a table with a header, body, and footer.
*/
render: function() {
this.views.add( new TableMeta( {
tagName: 'thead',
collection: this.collection,
} ) );
this.views.add( new TableRows( {
collection: this.collection,
} ) );
this.views.add( new TableAdd( {
collection: this.collection,
} ) );
this.views.add( new TableMeta( {
tagName: 'tfoot',
collection: this.collection,
} ) );
// Trigger the `filtered` action to show/hide rows accordingly
this.collection.trigger( 'filtered' );
},
} );
export default Table;