admin.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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 === 'download_csv') {
  193. bulkDownloadCsv(fileIds);
  194. } else if (action === 'delete') {
  195. bulkDelete(fileIds);
  196. } else if (action.startsWith('status_')) {
  197. var status = action.replace('status_', '');
  198. bulkUpdateStatus(fileIds, status);
  199. }
  200. });
  201. function getSelectedFileIds() {
  202. var ids = [];
  203. $('.studiou-fpp-file-cb:checked').each(function () {
  204. ids.push($(this).val());
  205. });
  206. return ids;
  207. }
  208. function bulkDownloadZip(fileIds) {
  209. showBulkSpinner(true);
  210. showAdminNotice(studiouWcfpp.i18n.generatingZip, 'info');
  211. $.ajax({
  212. url: studiouWcfpp.ajaxUrl,
  213. type: 'POST',
  214. data: {
  215. action: 'studiou_wcfpp_download_zip',
  216. nonce: studiouWcfpp.nonce,
  217. file_ids: fileIds
  218. },
  219. success: function (response) {
  220. if (response.success) {
  221. // Trigger download
  222. window.location.href = response.data.download_url;
  223. showAdminNotice(
  224. response.data.file_count + ' file(s) in archive.',
  225. 'success'
  226. );
  227. } else {
  228. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  229. }
  230. },
  231. error: function () {
  232. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  233. },
  234. complete: function () {
  235. showBulkSpinner(false);
  236. }
  237. });
  238. }
  239. function bulkDownloadCsv(fileIds) {
  240. showBulkSpinner(true);
  241. showAdminNotice(studiouWcfpp.i18n.generatingCsv || studiouWcfpp.i18n.generatingZip, 'info');
  242. $.ajax({
  243. url: studiouWcfpp.ajaxUrl,
  244. type: 'POST',
  245. data: {
  246. action: 'studiou_wcfpp_download_csv',
  247. nonce: studiouWcfpp.nonce,
  248. file_ids: fileIds
  249. },
  250. success: function (response) {
  251. if (response.success) {
  252. window.location.href = response.data.download_url;
  253. showAdminNotice(
  254. response.data.row_count + ' row(s) exported.',
  255. 'success'
  256. );
  257. } else {
  258. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  259. }
  260. },
  261. error: function () {
  262. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  263. },
  264. complete: function () {
  265. showBulkSpinner(false);
  266. }
  267. });
  268. }
  269. function bulkDelete(fileIds) {
  270. showBulkSpinner(true);
  271. $.ajax({
  272. url: studiouWcfpp.ajaxUrl,
  273. type: 'POST',
  274. data: {
  275. action: 'studiou_wcfpp_delete_files',
  276. nonce: studiouWcfpp.nonce,
  277. file_ids: fileIds
  278. },
  279. success: function (response) {
  280. if (response.success) {
  281. fileIds.forEach(function (id) {
  282. $('tr[data-file-id="' + id + '"]').fadeOut(300, function () {
  283. $(this).remove();
  284. });
  285. });
  286. showAdminNotice(response.data.message, 'success');
  287. } else {
  288. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  289. }
  290. },
  291. error: function () {
  292. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  293. },
  294. complete: function () {
  295. showBulkSpinner(false);
  296. }
  297. });
  298. }
  299. function bulkUpdateStatus(fileIds, status) {
  300. showBulkSpinner(true);
  301. $.ajax({
  302. url: studiouWcfpp.ajaxUrl,
  303. type: 'POST',
  304. data: {
  305. action: 'studiou_wcfpp_bulk_status',
  306. nonce: studiouWcfpp.nonce,
  307. file_ids: fileIds,
  308. status: status
  309. },
  310. success: function (response) {
  311. if (response.success) {
  312. // Update dropdowns
  313. fileIds.forEach(function (id) {
  314. $('tr[data-file-id="' + id + '"] .studiou-fpp-status-select').val(status);
  315. });
  316. showAdminNotice(response.data.message, 'success');
  317. } else {
  318. showAdminNotice(response.data ? response.data.message : studiouWcfpp.i18n.error, 'error');
  319. }
  320. },
  321. error: function () {
  322. showAdminNotice(studiouWcfpp.i18n.error, 'error');
  323. },
  324. complete: function () {
  325. showBulkSpinner(false);
  326. }
  327. });
  328. }
  329. function showBulkSpinner(show) {
  330. $('#studiou-fpp-bulk-spinner').css('visibility', show ? 'visible' : 'hidden');
  331. }
  332. function showAdminNotice(message, type) {
  333. var cls = 'notice-' + (type === 'error' ? 'error' : (type === 'info' ? 'info' : 'success'));
  334. $noticeArea.html(
  335. '<div class="notice ' + cls + ' is-dismissible"><p>' + escHtml(message) + '</p>' +
  336. '<button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss</span></button></div>'
  337. );
  338. $noticeArea.find('.notice-dismiss').on('click', function () {
  339. $(this).closest('.notice').fadeOut(200, function () { $(this).remove(); });
  340. });
  341. }
  342. }
  343. function escHtml(str) {
  344. var div = document.createElement('div');
  345. div.appendChild(document.createTextNode(str));
  346. return div.innerHTML;
  347. }
  348. });
  349. })(jQuery);