admin.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. (function ($) {
  2. 'use strict';
  3. $(document).ready(function () {
  4. // ========================================
  5. // Product edit page: Free Photo tab
  6. // ========================================
  7. if ($('#studiou_fpp_product_data').length) {
  8. initProductTab();
  9. }
  10. // ========================================
  11. // Product edit page: Variation quantity discount tiers
  12. // ========================================
  13. initVariationQtyTiers();
  14. // ========================================
  15. // Admin summary page
  16. // ========================================
  17. if ($('.studiou-fpp-admin-wrap').length) {
  18. initSummaryPage();
  19. }
  20. function initVariationQtyTiers() {
  21. // Add tier row
  22. $(document).on('click', '.studiou-fpp-qty-tier-add', function (e) {
  23. e.preventDefault();
  24. var $btn = $(this);
  25. var loop = $btn.data('loop');
  26. var $tbody = $btn.closest('.studiou-fpp-qty-tiers-field').find('.studiou-fpp-qty-tiers-table tbody');
  27. var idx = Date.now() + '_' + Math.floor(Math.random() * 10000);
  28. var row =
  29. '<tr class="studiou-fpp-qty-tier-row">' +
  30. '<td><input type="number" min="1" step="1" name="studiou_fpp_qty_tiers[' + loop + '][' + idx + '][from_qty]" value="" /></td>' +
  31. '<td><input type="number" min="0" max="100" step="0.01" name="studiou_fpp_qty_tiers[' + loop + '][' + idx + '][percent]" value="" /></td>' +
  32. '<td><button type="button" class="button studiou-fpp-qty-tier-remove">&times;</button></td>' +
  33. '</tr>';
  34. $tbody.append(row);
  35. markVariationChanged($btn);
  36. });
  37. // Remove tier row
  38. $(document).on('click', '.studiou-fpp-qty-tier-remove', function (e) {
  39. e.preventDefault();
  40. var $btn = $(this);
  41. $btn.closest('tr').remove();
  42. markVariationChanged($btn);
  43. });
  44. // Mark variation as modified on any input change inside the tier table
  45. $(document).on('change input', '.studiou-fpp-qty-tiers-table input', function () {
  46. markVariationChanged($(this));
  47. });
  48. function markVariationChanged($el) {
  49. var $variation = $el.closest('.woocommerce_variation');
  50. if ($variation.length) {
  51. $variation.addClass('variation-needs-update');
  52. $('button.cancel-variation-changes, button.save-variation-changes').removeAttr('disabled');
  53. $('#variable_product_options').trigger('woocommerce_variations_input_changed');
  54. }
  55. }
  56. }
  57. function initProductTab() {
  58. // Show/hide new media category form
  59. $('.studiou-fpp-add-media-cat-btn').on('click', function () {
  60. $('.studiou-fpp-new-media-cat-form').toggle();
  61. });
  62. $('.studiou-fpp-cancel-media-cat-btn').on('click', function () {
  63. $('.studiou-fpp-new-media-cat-form').hide();
  64. $('#studiou_fpp_new_cat_name').val('');
  65. });
  66. // Save new media category
  67. $('.studiou-fpp-save-media-cat-btn').on('click', function () {
  68. var name = $('#studiou_fpp_new_cat_name').val().trim();
  69. if (!name) {
  70. return;
  71. }
  72. var $btn = $(this);
  73. $btn.prop('disabled', true);
  74. $.ajax({
  75. url: studiouWcfpp.ajaxUrl,
  76. type: 'POST',
  77. data: {
  78. action: 'studiou_wcfpp_add_media_category',
  79. nonce: studiouWcfpp.nonce,
  80. name: name
  81. },
  82. success: function (response) {
  83. if (response.success) {
  84. var $select = $('#_studiou_fpp_media_category');
  85. $select.append(
  86. $('<option>', {
  87. value: response.data.term_id,
  88. text: response.data.name,
  89. selected: true
  90. })
  91. );
  92. $('.studiou-fpp-new-media-cat-form').hide();
  93. $('#studiou_fpp_new_cat_name').val('');
  94. } else {
  95. alert(response.data ? response.data.message : studiouWcfpp.i18n.error);
  96. }
  97. },
  98. error: function () {
  99. alert(studiouWcfpp.i18n.error);
  100. },
  101. complete: function () {
  102. $btn.prop('disabled', false);
  103. }
  104. });
  105. });
  106. }
  107. function initSummaryPage() {
  108. var $noticeArea = $('.studiou-fpp-admin-notice-area');
  109. // Select all
  110. $('#studiou-fpp-select-all').on('change', function () {
  111. $('.studiou-fpp-file-cb').prop('checked', $(this).is(':checked'));
  112. });
  113. // Individual status change
  114. $('.studiou-fpp-status-select').on('change', function () {
  115. var fileId = $(this).data('file-id');
  116. var status = $(this).val();
  117. var $el = $(this);
  118. $.ajax({
  119. url: studiouWcfpp.ajaxUrl,
  120. type: 'POST',
  121. data: {
  122. action: 'studiou_wcfpp_update_status',
  123. nonce: studiouWcfpp.nonce,
  124. file_id: fileId,
  125. status: status
  126. },
  127. success: function (response) {
  128. if (response.success) {
  129. showAdminNotice(studiouWcfpp.i18n.statusUpdated, 'success');
  130. } else {
  131. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  132. }
  133. },
  134. error: function () {
  135. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  136. }
  137. });
  138. });
  139. // Delete single
  140. $(document).on('click', '.studiou-fpp-delete-single', function () {
  141. var fileId = $(this).data('file-id');
  142. if (!confirm(studiouWcfpp.i18n.confirmDeleteSingle)) {
  143. return;
  144. }
  145. $.ajax({
  146. url: studiouWcfpp.ajaxUrl,
  147. type: 'POST',
  148. data: {
  149. action: 'studiou_wcfpp_delete_files',
  150. nonce: studiouWcfpp.nonce,
  151. file_ids: [fileId]
  152. },
  153. success: function (response) {
  154. if (response.success) {
  155. $('tr[data-file-id="' + fileId + '"]').fadeOut(300, function () {
  156. $(this).remove();
  157. });
  158. showAdminNotice(response.data.message, 'success');
  159. } else {
  160. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  161. }
  162. },
  163. error: function () {
  164. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  165. }
  166. });
  167. });
  168. // Bulk action apply
  169. $('#studiou-fpp-bulk-apply').on('click', function () {
  170. var action = $('#studiou-fpp-bulk-action').val();
  171. if (!action) {
  172. return;
  173. }
  174. var fileIds = getSelectedFileIds();
  175. if (fileIds.length === 0) {
  176. showAdminNotice(studiouWcfpp.i18n.noFilesSelected, 'error');
  177. return;
  178. }
  179. var confirmMsg = '';
  180. if (action === 'delete') {
  181. confirmMsg = studiouWcfpp.i18n.confirmDelete;
  182. } else if (action === 'download_zip') {
  183. confirmMsg = studiouWcfpp.i18n.confirmDownloadZip;
  184. } else if (action.startsWith('status_')) {
  185. confirmMsg = studiouWcfpp.i18n.confirmStatusChange;
  186. }
  187. if (confirmMsg && !confirm(confirmMsg)) {
  188. return;
  189. }
  190. if (action === 'download_zip') {
  191. bulkDownloadZip(fileIds);
  192. } else if (action === 'delete') {
  193. bulkDelete(fileIds);
  194. } else if (action.startsWith('status_')) {
  195. var status = action.replace('status_', '');
  196. bulkUpdateStatus(fileIds, status);
  197. }
  198. });
  199. function getSelectedFileIds() {
  200. var ids = [];
  201. $('.studiou-fpp-file-cb:checked').each(function () {
  202. ids.push($(this).val());
  203. });
  204. return ids;
  205. }
  206. function bulkDownloadZip(fileIds) {
  207. showBulkSpinner(true);
  208. showAdminNotice(studiouWcfpp.i18n.generatingZip, 'info');
  209. $.ajax({
  210. url: studiouWcfpp.ajaxUrl,
  211. type: 'POST',
  212. data: {
  213. action: 'studiou_wcfpp_download_zip',
  214. nonce: studiouWcfpp.nonce,
  215. file_ids: fileIds
  216. },
  217. success: function (response) {
  218. if (response.success) {
  219. // Trigger download
  220. window.location.href = response.data.download_url;
  221. showAdminNotice(
  222. response.data.file_count + ' file(s) in archive.',
  223. 'success'
  224. );
  225. } else {
  226. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  227. }
  228. },
  229. error: function () {
  230. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  231. },
  232. complete: function () {
  233. showBulkSpinner(false);
  234. }
  235. });
  236. }
  237. function bulkDelete(fileIds) {
  238. showBulkSpinner(true);
  239. $.ajax({
  240. url: studiouWcfpp.ajaxUrl,
  241. type: 'POST',
  242. data: {
  243. action: 'studiou_wcfpp_delete_files',
  244. nonce: studiouWcfpp.nonce,
  245. file_ids: fileIds
  246. },
  247. success: function (response) {
  248. if (response.success) {
  249. fileIds.forEach(function (id) {
  250. $('tr[data-file-id="' + id + '"]').fadeOut(300, function () {
  251. $(this).remove();
  252. });
  253. });
  254. showAdminNotice(response.data.message, 'success');
  255. } else {
  256. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  257. }
  258. },
  259. error: function () {
  260. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  261. },
  262. complete: function () {
  263. showBulkSpinner(false);
  264. }
  265. });
  266. }
  267. function bulkUpdateStatus(fileIds, status) {
  268. showBulkSpinner(true);
  269. $.ajax({
  270. url: studiouWcfpp.ajaxUrl,
  271. type: 'POST',
  272. data: {
  273. action: 'studiou_wcfpp_bulk_status',
  274. nonce: studiouWcfpp.nonce,
  275. file_ids: fileIds,
  276. status: status
  277. },
  278. success: function (response) {
  279. if (response.success) {
  280. // Update dropdowns
  281. fileIds.forEach(function (id) {
  282. $('tr[data-file-id="' + id + '"] .studiou-fpp-status-select').val(status);
  283. });
  284. showAdminNotice(response.data.message, 'success');
  285. } else {
  286. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  287. }
  288. },
  289. error: function () {
  290. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  291. },
  292. complete: function () {
  293. showBulkSpinner(false);
  294. }
  295. });
  296. }
  297. function showBulkSpinner(show) {
  298. $('#studiou-fpp-bulk-spinner').css('visibility', show ? 'visible' : 'hidden');
  299. }
  300. function showAdminNotice(message, type) {
  301. var cls = 'notice-' + (type === 'error' ? 'error' : (type === 'info' ? 'info' : 'success'));
  302. $noticeArea.html(
  303. '<div class="notice ' + cls + ' is-dismissible"><p>' + escHtml(message) + '</p>' +
  304. '<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss</span></button></div>'
  305. );
  306. $noticeArea.find('.notice-dismiss').on('click', function () {
  307. $(this).closest('.notice').fadeOut(200, function () { $(this).remove(); });
  308. });
  309. }
  310. }
  311. function escHtml(str) {
  312. var div = document.createElement('div');
  313. div.appendChild(document.createTextNode(str));
  314. return div.innerHTML;
  315. }
  316. });
  317. })(jQuery);