PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
6.2.3 6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 All 156 releases
← All changes | assets/js/mainwp-groups.js +328 -166 5.0.3.2 → 6.2.2 View file →
@@ -1,197 +1,359 @@
1 -jQuery(document).ready(function () {
1 +jQuery(function () {
2 2
3 - // Init the groups menu
4 - jQuery('#mainwp-groups-menu').find('a.item').on('click', function () {
5 - jQuery(this).addClass('active green');
6 - jQuery(this).siblings().removeClass('active green');
7 - jQuery(this).find('.label').addClass('green');
8 - jQuery(this).siblings().find('.label').removeClass('green');
9 - jQuery('#mainwp-delete-group-button').removeClass('disabled');
10 - jQuery('#mainwp-rename-group-button').removeClass('disabled');
11 - jQuery('#mainwp-save-sites-groups-selection-button').removeClass('disabled');
12 - show_group_items(this);
13 - });
3 + // Auto-select newly created group from URL parameter
4 + let urlParams = new URLSearchParams(globalThis.location.search);
5 + let newGroupId = urlParams.get('new-tag');
14 6
15 - // Trigger the create a new group modal
16 - jQuery(document).on('click', '#mainwp-new-sites-group-button', function () {
17 - jQuery('#mainwp-create-group-modal').modal({
18 - onHide: function () {
19 - window.location.href = location.href;
20 - },
21 - onShow: function () {
22 - jQuery('#mainwp-create-group-modal').find('input#mainwp-group-name').val('');
23 - jQuery('#mainwp-create-group-modal').find('input#mainwp-new-tag-color').val('');
24 - }
25 - }).modal('show');
26 - });
7 + jQuery(document).ready(function () {
8 + if (newGroupId) {
9 + // Find the menu item with the new group ID
10 + let newGroupItem = jQuery('#mainwp-groups-menu').find('a.item#' + newGroupId);
27 11
28 - // Trigger the edit group modal
29 - jQuery(document).on('click', '#mainwp-rename-group-button', function () {
30 - jQuery('#mainwp-rename-group-modal').modal({
31 - onHide: function () {
32 - window.location.href = location.href;
33 - },
34 - onShow: function () {
35 - var groupName = jQuery('#mainwp-groups-menu').find('.active').find('#mainwp-hidden-group-name').val();
36 - var groupColor = jQuery('#mainwp-groups-menu').find('.active').find('#mainwp-hidden-group-color').val();
37 - jQuery('#mainwp-rename-group-modal').find('input#mainwp-group-name').val(groupName);
38 - jQuery('#mainwp-rename-group-modal').find('input#mainwp-new-tag-color').val(groupColor);
39 - }
40 - }).modal('show');
41 - });
12 + if (newGroupItem.length > 0) {
13 + // Trigger click on the new group item to select it
14 + newGroupItem.trigger('click');
15 + // Show success message
16 + feedback('mainwp-message-zone', 'Tag created successfully.', 'ui green message');
42 17
43 - // Create a new group
44 - jQuery(document).on('click', '#mainwp-save-new-group-button', function () {
45 - var newName = jQuery('#mainwp-create-group-modal').find('input#mainwp-group-name').val();
46 - var newColor = jQuery('#mainwp-create-group-modal').find('input#mainwp-new-tag-color').val();
18 + // Auto-hide message after 5 seconds
19 + setTimeout(() => {
20 + jQuery('#mainwp-message-zone').fadeOut();
21 + }, 5000);
47 22
48 - var data = mainwp_secure_data({
49 - action: 'mainwp_group_add',
50 - newName: newName,
51 - newColor: newColor
23 + // Remove the URL parameter without reloading the page
24 + let cleanUrl = globalThis.location.pathname + globalThis.location.search.replace(/[?&]new-tag=[^&]+/, '').replace(/^&/, '?');
25 + if (cleanUrl.endsWith('?')) {
26 + cleanUrl = cleanUrl.slice(0, -1);
27 + }
28 + globalThis.history.replaceState({}, document.title, cleanUrl);
29 + }
30 + }
31 + })
32 +
33 + // Init the groups menu
34 + jQuery('#mainwp-groups-menu').find('a.item').on('click', function () {
35 + jQuery(this).addClass('active green');
36 + jQuery(this).siblings().removeClass('active green');
37 + jQuery(this).find('.label').addClass('green');
38 + jQuery(this).siblings().find('.label').removeClass('green');
39 + jQuery('#mainwp-delete-group-button').removeClass('disabled');
40 + jQuery('#mainwp-rename-group-button').removeClass('disabled');
41 + jQuery('#mainwp-save-sites-groups-selection-button').removeClass('disabled');
42 + jQuery('#mainwp-message-zone').fadeOut();
43 + show_group_items(this);
44 + apply_tag_fade_effect(this);
45 +
52 46 });
53 - jQuery.post(ajaxurl, data, function (response) {
54 - try {
55 - resp = JSON.parse(response);
56 47
57 - if (resp.error != undefined)
58 - return;
59 - } catch (err) {
60 - // to fix js error.
61 - }
62 - jQuery('#mainwp-create-group-modal').modal({
63 - onHide: function () {
64 - window.location.reload();
48 +
49 + // Trigger the create a new group modal
50 + jQuery(document).on('click', '#mainwp-new-sites-group-button', function () {
51 + jQuery('#mainwp-create-group-modal').modal({
52 + onHide: function () {
53 + mainwp_forceReload();
54 + },
55 + onShow: function () {
56 + jQuery('#mainwp-create-group-modal').find('input[name="mainwp-group-name"]').val('');
57 + jQuery('#mainwp-create-group-modal').find('input#mainwp-new-tag-color').val('');
58 + // Disable button initially.
59 + jQuery('#mainwp-save-new-group-button').addClass('disabled');
60 + }
61 + }).modal('show');
62 + });
63 +
64 + // Enable/disable create button based on input validation
65 + jQuery(document).on('input', '#mainwp-create-group-modal input[name="mainwp-group-name"], #mainwp-rename-group-modal input[name="mainwp-group-name"]', function () {
66 + let groupName = jQuery(this).val().trim();
67 + if (groupName.length > 0) {
68 + jQuery('#mainwp-save-new-group-button').removeClass('disabled');
69 + jQuery('#mainwp-update-new-group-button').removeClass('disabled');
70 + } else {
71 + jQuery('#mainwp-save-new-group-button').addClass('disabled');
72 + jQuery('#mainwp-update-new-group-button').addClass('disabled');
65 73 }
66 - }).modal('hide');
67 74 });
68 - return false;
69 - });
70 75
71 - // Delete a group
72 - jQuery(document).on('click', '#mainwp-delete-group-button', function () {
73 - var gruopItem = jQuery('#mainwp-groups-menu').find('.active');
74 - mainwp_confirm('Are you sure you want to delete this tag?', function () {
75 - var groupID = gruopItem.attr('id');
76 - var data = mainwp_secure_data({
77 - action: 'mainwp_group_delete',
78 - groupId: groupID
79 - });
80 - jQuery.post(ajaxurl, data, function (gruopItem) {
81 - return function (response) {
82 - response = response.trim();
83 - if (response == 'OK') {
84 - gruopItem.fadeOut(300);
85 - }
76 + // Enable update button when color changes in rename modal
77 + jQuery(document).on('input change', '#mainwp-rename-group-modal input#mainwp-new-tag-color', function () {
78 + let groupName = jQuery('#mainwp-rename-group-modal').find('input[name="mainwp-group-name"]').val().trim();
79 + if (groupName.length > 0) {
80 + jQuery('#mainwp-update-new-group-button').removeClass('disabled');
86 81 }
87 - }(gruopItem));
88 82 });
89 - return false;
90 - });
91 83
92 - // Update group name
93 - jQuery(document).on('click', '#mainwp-update-new-group-button', function () {
94 - var groupID = jQuery('#mainwp-groups-menu').find('.active').attr('id');
95 - var newName = jQuery('#mainwp-rename-group-modal').find('input#mainwp-group-name').val();
96 - var newColor = jQuery('#mainwp-rename-group-modal').find('input#mainwp-new-tag-color').val();
97 - var data = mainwp_secure_data({
98 - action: 'mainwp_group_rename',
99 - groupId: groupID,
100 - newName: newName,
101 - newColor: newColor
84 + // Trigger the edit group modal
85 + jQuery(document).on('click', '#mainwp-rename-group-button', function () {
86 + jQuery('#mainwp-rename-group-modal').modal({
87 + onHide: function () {
88 + mainwp_forceReload();
89 + },
90 + onShow: function () {
91 + let groupName = jQuery('#mainwp-groups-menu').find('.active').find('#mainwp-hidden-group-name').val();
92 + let groupColor = jQuery('#mainwp-groups-menu').find('.active').find('#mainwp-hidden-group-color').val();
93 + jQuery('#mainwp-rename-group-modal').find('input[name="mainwp-group-name"]').val(groupName);
94 + jQuery('#mainwp-rename-group-modal').find('input#mainwp-new-tag-color').val(groupColor);
95 + // Disable button initially.
96 + jQuery('#mainwp-update-new-group-button').addClass('disabled');
97 + }
98 + }).modal('show');
102 99 });
103 - jQuery.post(ajaxurl, data, function () {
104 - return function (response) {
105 - if (response.error) {
106 - return;
100 +
101 + // Create a new group
102 + jQuery(document).on('click', '#mainwp-save-new-group-button', function (e) {
103 +
104 + let $button = jQuery(this);
105 + let $modal = jQuery('#mainwp-create-group-modal');
106 + let newName = $modal.find('input[name="mainwp-group-name"]').val().trim();
107 + let newColor = $modal.find('input#mainwp-new-tag-color').val();
108 +
109 + // Validate input
110 + if (newName.length === 0) {
111 + return false;
107 112 }
108 - jQuery('#mainwp-create-group-modal').modal({
109 - onHide: function () {
110 - window.location.reload();
113 +
114 + // Check if button is already disabled (loading)
115 + if ($button.hasClass('disabled') || $button.data('loading')) {
111 116 return false;
112 - }
113 - }).modal('hide');
114 - }
115 - }(), 'json');
116 - return false;
117 - });
117 + }
118 118
119 - // Select all sites
120 - jQuery('#mainwp-manage-groups-sites-table th input[type="checkbox"]').on('change', function () {
121 - var checkboxes = jQuery('#mainwp-manage-groups-sites-table').find(':checkbox');
122 - if (jQuery(this).prop('checked')) {
123 - checkboxes.prop('checked', true);
124 - checkboxes.parents('tr').addClass('active');
125 - } else {
126 - checkboxes.prop('checked', false);
127 - checkboxes.parents('tr').removeClass('active');
128 - }
129 - });
119 + let selected_sites = [];
120 + jQuery("input[name='sites']:checked").each(function () {
121 + selected_sites.push(jQuery(this).val());
122 + });
130 123
131 - // Set class 'active' to selected sites table row
132 - jQuery('.mainwp-site-checkbox').on('change', function () {
133 - if (jQuery(this).prop('checked')) {
134 - jQuery(this).parents('tr').addClass('active');
135 - } else {
136 - jQuery(this).parents('tr').removeClass('active');
137 - }
138 - });
124 + // Disable button and show loading state.
125 + let originalText = $button.html();
126 + $button.data('loading', true);
127 + $button.addClass('disabled');
128 + $button.html('<i class="spinner loading icon"></i> Creating...');
129 + $modal.find('input').prop('disabled', true);
139 130
140 - // Save selected sites for a group
141 - jQuery(document).on('click', '#mainwp-save-sites-groups-selection-button', function () {
142 - var groupID = jQuery('#mainwp-groups-menu').find('.active').attr('id');
143 - var sites = jQuery('#mainwp-manage-groups-sites-table').find('input.mainwp-site-checkbox:checked');
144 - var sitesIDs = [];
131 + let data = mainwp_secure_data({
132 + //action: 'mainwp_group_add',
133 + action: 'mainwp_group_sites_add',
134 + selected_sites: selected_sites,
135 + newName: newName,
136 + newColor: newColor
137 + });
138 + jQuery.post(ajaxurl, data, function (response) {
139 + try {
140 + let resp = JSON.parse(response);
145 141
146 - for (var i = 0; i < sites.length; i++) {
147 - sitesIDs.push(jQuery(sites[i]).val());
148 - }
142 + if (resp.error != undefined) {
143 + // Remove loading state on error
144 + $button.data("loading", false);
145 + $button.removeClass("disabled");
146 + $button.html(originalText);
147 + $modal.find("input").prop("disabled", false);
148 + return;
149 + }
149 150
150 - if (groupID == undefined) {
151 - return;
152 - }
151 + globalThis.location.href = "admin.php?page=ManageGroups&new-tag=" + resp.success;
152 + } catch {
153 + // to fix js error.
154 + // Remove loading state on error
155 + $button.data("loading", false);
156 + $button.removeClass("disabled");
157 + $button.html(originalText);
158 + $modal.find("input").prop("disabled", false);
159 + }
160 + });
161 + e.preventDefault();
162 + e.stopPropagation();
163 + return true;
164 + });
153 165
154 - var data = mainwp_secure_data({
155 - action: 'mainwp_group_updategroup',
156 - groupId: groupID,
157 - websiteIds: sitesIDs
166 + // Delete a Tag
167 + jQuery(document).on('click', '#mainwp-delete-group-button', function () {
168 + let gruopItem = jQuery('#mainwp-groups-menu').find('.active');
169 +
170 + let _deltag_callback = function () {
171 + let groupID = gruopItem.attr('id');
172 + let data = mainwp_secure_data({
173 + action: 'mainwp_group_delete',
174 + groupId: groupID
175 + });
176 + jQuery.post(ajaxurl, data, function (response) {
177 + response = response.trim();
178 + if (response == 'OK') {
179 + mainwp_forceReload();
180 + }
181 + });
182 + };
183 +
184 + mainwp_confirm('Are you sure you want to delete this tag?', _deltag_callback);
185 + return false;
158 186 });
159 187
160 - jQuery(this).addClass('disabled');
188 + // Update group name
189 + jQuery(document).on('click', '#mainwp-update-new-group-button', function () {
190 + let $button = jQuery(this);
191 + let $modal = jQuery('#mainwp-rename-group-modal');
161 192
162 - jQuery.post(ajaxurl, data, function () {
163 - jQuery(this).removeClass('disabled');
164 - jQuery('#mainwp-message-zone').stop(true, true);
165 - jQuery('#mainwp-message-zone').show();
166 - jQuery('#mainwp-message-zone').fadeOut(3000);
167 - return;
168 - }, 'json');
193 + let groupID = jQuery('#mainwp-groups-menu').find('.active').attr('id');
194 + let newName = $modal.find('input[name="mainwp-group-name"]').val();
195 + let newColor = $modal.find('input#mainwp-new-tag-color').val();
196 + let data = mainwp_secure_data({
197 + action: 'mainwp_group_rename',
198 + groupId: groupID,
199 + newName: newName,
200 + newColor: newColor
201 + });
169 202
170 - });
203 + // Disable button and show loading state.
204 + let originalText = $button.html();
205 + $button.data('loading', true);
206 + $button.addClass('disabled');
207 + $button.html('<i class="spinner loading icon"></i> Updating...');
208 + $modal.find('input').prop('disabled', true);
171 209
172 - // Load group sites
173 - show_group_items = function (group) {
174 - var groupID = jQuery(group).attr('id');
175 - var data = mainwp_secure_data({
176 - action: 'mainwp_group_getsites',
177 - groupId: groupID
210 +
211 + jQuery.post(ajaxurl, data, function (response) {
212 + if (response.error) {
213 + // Remove loading state on error
214 + $button.data("loading", false);
215 + $button.removeClass("disabled");
216 + $button.html(originalText);
217 + $modal.find("input").prop("disabled", false);
218 + return;
219 + }
220 + jQuery('#mainwp-create-group-modal').modal({
221 + onHide: function () {
222 + mainwp_forceReload();
223 + return false;
224 + }
225 + }).modal('hide');
226 + }, 'json');
227 +
228 + return false;
178 229 });
179 - jQuery('.dimmer').addClass('active');
180 - jQuery.post(ajaxurl, data, function (response) {
181 - jQuery('.dimmer').removeClass('active');
182 - response = response.trim();
183 - if (response == 'ERROR') {
184 - return;
185 - }
186 - jQuery('input.mainwp-site-checkbox').prop('checked', false);
187 - jQuery('input.mainwp-site-checkbox').closest('tr').removeClass('active');
188 - var sites = JSON.parse(response);
189 - for (var i = 0; i < sites.length; i++) {
190 - jQuery('input[value="' + sites[i] + '"].mainwp-site-checkbox').prop('checked', true);
191 - jQuery('input[value="' + sites[i] + '"].mainwp-site-checkbox').closest('tr').addClass('active');
192 - }
230 +
231 + // Select all sites
232 + jQuery('#mainwp-manage-groups-sites-table th input[type="checkbox"]').on('change', function () {
233 + let checkboxes = jQuery('#mainwp-manage-groups-sites-table').find(':checkbox');
234 + if (jQuery(this).prop('checked')) {
235 + checkboxes.prop('checked', true);
236 + checkboxes.parents('tr').addClass('selected active');
237 + } else {
238 + checkboxes.prop('checked', false);
239 + checkboxes.parents('tr').removeClass('selected active');
240 + }
193 241 });
194 - return false;
195 - }
242 +
243 + // Set class 'active' to selected sites table row
244 + jQuery('.mainwp-site-checkbox').on('change', function () {
245 + if (jQuery(this).prop('checked')) {
246 + jQuery(this).parents('tr').addClass('selected active');
247 + } else {
248 + jQuery(this).parents('tr').removeClass('selected active');
249 + }
250 + });
251 +
252 + // Keep update selected tag site ids.
253 + jQuery(document).on('change', '#mainwp-manage-groups-sites-table .mainwp-site-checkbox', function () {
254 + let tag_siteids = jQuery('#mainwp-save-sites-groups-selection-button').attr('selected-tag-siteids');
255 + if (tag_siteids !== undefined) {
256 + tag_siteids = '' == tag_siteids ? [] : JSON.parse(tag_siteids);
257 +
258 + const valSiteId = jQuery(this).val();
259 + if (jQuery(this).is(':checked')) {
260 + if (!tag_siteids.includes(valSiteId)) {
261 + tag_siteids.push(valSiteId);
262 + }
263 + } else {
264 + const index = tag_siteids.indexOf(valSiteId);
265 + if (index !== -1) {
266 + tag_siteids.splice(index, 1);
267 + }
268 + }
269 +
270 + jQuery('#mainwp-save-sites-groups-selection-button').attr('selected-tag-siteids', tag_siteids.length ? JSON.stringify(tag_siteids) : '')
271 + }
272 + });
273 +
274 +
275 + // Save selected sites for a group
276 + jQuery(document).on('click', '#mainwp-save-sites-groups-selection-button', function (e) {
277 +
278 + e.preventDefault();
279 +
280 + let groupID = jQuery('#mainwp-groups-menu').find('.active').attr('id');
281 + let tag_siteids = jQuery('#mainwp-save-sites-groups-selection-button').attr('selected-tag-siteids');
282 +
283 + if (groupID == undefined) {
284 + return;
285 + }
286 + let data = mainwp_secure_data({
287 + action: 'mainwp_group_updategroup',
288 + groupId: groupID,
289 + websiteIds: tag_siteids == '' ? [] : JSON.parse(tag_siteids),
290 + });
291 +
292 + jQuery(this).addClass('disabled');
293 +
294 + jQuery.post(ajaxurl, data, function (response) {
295 + jQuery('#mainwp-save-sites-groups-selection-button').removeClass('disabled');
296 + if (response?.result === true) {
297 + feedback('mainwp-message-zone', 'Selection saved successfully.', 'ui green message');
298 + setTimeout(() => {
299 + jQuery('#mainwp-message-zone').fadeOut();
300 + }, 5000);
301 + } else {
302 + feedback('mainwp-message-zone', 'Undefined error occurred. Please try again.', 'ui green message');
303 + }
304 + }, 'json');
305 + });
306 +
307 + // Load group sites
308 + let show_group_items = function (group) {
309 + let groupID = jQuery(group).attr('id');
310 + let data = mainwp_secure_data({
311 + action: 'mainwp_group_getsites',
312 + groupId: groupID
313 + });
314 + jQuery('.dimmer').addClass('active');
315 + let dtApi = jQuery('#mainwp-manage-groups-sites-table').dataTable().api();
316 + let searchValue = dtApi.search();
317 + dtApi.search('').draw();
318 + jQuery.post(ajaxurl, data, function (response) {
319 + jQuery('.dimmer').removeClass('active');
320 + response = response.trim();
321 + if (response == 'ERROR') {
322 + dtApi.search(searchValue).draw();
323 + return;
324 + }
325 + mainwp_datatable_fix_to_update_selected_rows_status(dtApi, 'deselected'); // clear saved state.
326 + jQuery('input.mainwp-site-checkbox').prop('checked', false);
327 + jQuery('input.mainwp-site-checkbox').closest('tr').removeClass('selected active');
328 + let sites = JSON.parse(response);
329 + for (let id of sites) {
330 + jQuery('input[value="' + id + '"].mainwp-site-checkbox').prop('checked', true);
331 + jQuery('input[value="' + id + '"].mainwp-site-checkbox').closest('tr').addClass('selected active');
332 + }
333 + jQuery('#mainwp-save-sites-groups-selection-button').attr('selected-tag-siteids', sites?.length ? response : '');
334 + mainwp_datatable_fix_to_update_selected_rows_status(dtApi, 'selected active'); // clear saved state.
335 + dtApi.search(searchValue).draw();
336 + });
337 +
338 + return false;
339 + }
340 +
341 + // Apply fade effect to tags in the sites table
342 + let apply_tag_fade_effect = function (menuItem) {
343 + // Get the selected tag ID from the menu item
344 + let selectedTagId = jQuery(menuItem).attr('id');
345 +
346 + if (!selectedTagId) {
347 + // If no tag is selected, reset all tags to full opacity
348 + jQuery('#mainwp-manage-groups-sites-table span.ui.tag.label').css('opacity', '1');
349 + return;
350 + }
351 +
352 + // Fade all tags to 10% opacity
353 + jQuery('#mainwp-manage-groups-sites-table span.ui.tag.label').css('opacity', '0.1');
354 +
355 + // Restore full opacity for the selected tag
356 + jQuery('#mainwp-manage-groups-sites-table span.ui.tag.label[tag_id="' + selectedTagId + '"]').css('opacity', '1');
357 + }
196 358
197 359 });