PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
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 5.2.1 All 155 releases
← All changes | assets/js/mainwp-groups.js +325 -168 5.2 → 6.2.1 View file →
@@ -1,202 +1,359 @@
1 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 - let groupName = jQuery('#mainwp-groups-menu').find('.active').find('#mainwp-hidden-group-name').val();
36 - let 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 - let newName = jQuery('#mainwp-create-group-modal').find('input#mainwp-group-name').val();
46 - let 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 - let 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 - let 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 - let gruopItem = jQuery('#mainwp-groups-menu').find('.active');
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');
81 + }
82 + });
74 83
75 - let _deltag_callback = function () {
76 - let groupID = gruopItem.attr('id');
77 - let data = mainwp_secure_data({
78 - action: 'mainwp_group_delete',
79 - groupId: groupID
80 - });
81 - jQuery.post(ajaxurl, data, function (response) {
82 - response = response.trim();
83 - if (response == 'OK') {
84 - gruopItem.fadeOut(300);
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');
99 + });
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;
85 112 }
86 - });
87 - };
88 113
89 - mainwp_confirm('Are you sure you want to delete this tag?', _deltag_callback);
90 - return false;
91 - });
114 + // Check if button is already disabled (loading)
115 + if ($button.hasClass('disabled') || $button.data('loading')) {
116 + return false;
117 + }
92 118
93 - // Update group name
94 - jQuery(document).on('click', '#mainwp-update-new-group-button', function () {
95 - let groupID = jQuery('#mainwp-groups-menu').find('.active').attr('id');
96 - let newName = jQuery('#mainwp-rename-group-modal').find('input#mainwp-group-name').val();
97 - let newColor = jQuery('#mainwp-rename-group-modal').find('input#mainwp-new-tag-color').val();
98 - let data = mainwp_secure_data({
99 - action: 'mainwp_group_rename',
100 - groupId: groupID,
101 - newName: newName,
102 - newColor: newColor
119 + let selected_sites = [];
120 + jQuery("input[name='sites']:checked").each(function () {
121 + selected_sites.push(jQuery(this).val());
122 + });
123 +
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);
130 +
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);
141 +
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 + }
150 +
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;
103 164 });
104 165
105 - jQuery.post(ajaxurl, data, function (response) {
106 - if (response.error) {
107 - return;
108 - }
109 - jQuery('#mainwp-create-group-modal').modal({
110 - onHide: function () {
111 - window.location.reload();
112 - return false;
113 - }
114 - }).modal('hide');
115 - }, 'json');
166 + // Delete a Tag
167 + jQuery(document).on('click', '#mainwp-delete-group-button', function () {
168 + let gruopItem = jQuery('#mainwp-groups-menu').find('.active');
116 169
117 - return false;
118 - });
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 + };
119 183
120 - // Select all sites
121 - jQuery('#mainwp-manage-groups-sites-table th input[type="checkbox"]').on('change', function () {
122 - let checkboxes = jQuery('#mainwp-manage-groups-sites-table').find(':checkbox');
123 - if (jQuery(this).prop('checked')) {
124 - checkboxes.prop('checked', true);
125 - checkboxes.parents('tr').addClass('selected');
126 - } else {
127 - checkboxes.prop('checked', false);
128 - checkboxes.parents('tr').removeClass('selected');
129 - }
130 - });
184 + mainwp_confirm('Are you sure you want to delete this tag?', _deltag_callback);
185 + return false;
186 + });
131 187
132 - // Set class 'active' to selected sites table row
133 - jQuery('.mainwp-site-checkbox').on('change', function () {
134 - if (jQuery(this).prop('checked')) {
135 - jQuery(this).parents('tr').addClass('selected');
136 - } else {
137 - jQuery(this).parents('tr').removeClass('selected');
138 - }
139 - });
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');
140 192
141 - // Save selected sites for a group
142 - jQuery(document).on('click', '#mainwp-save-sites-groups-selection-button', function (e) {
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 + });
143 202
144 - e.preventDefault();
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);
145 209
146 - let groupID = jQuery('#mainwp-groups-menu').find('.active').attr('id');
147 - let sites = jQuery('#mainwp-manage-groups-sites-table').find('input.mainwp-site-checkbox:checked');
148 - let sitesIDs = [];
149 210
150 - for (let id of sites) {
151 - sitesIDs.push(jQuery(id).val());
152 - }
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');
153 227
154 - if (groupID == undefined) {
155 - return;
156 - }
228 + return false;
229 + });
157 230
158 - let data = mainwp_secure_data({
159 - action: 'mainwp_group_updategroup',
160 - groupId: groupID,
161 - websiteIds: sitesIDs
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 + }
162 241 });
163 242
164 - jQuery(this).addClass('disabled');
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 + });
165 251
166 - jQuery.post(ajaxurl, data, function () {
167 - jQuery(this).removeClass('disabled');
168 - jQuery('#mainwp-message-zone').stop(true, true);
169 - jQuery('#mainwp-message-zone').show();
170 - jQuery('#mainwp-message-zone').fadeOut(3000);
171 - }, 'json');
172 - });
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);
173 257
174 - // Load group sites
175 - let show_group_items = function (group) {
176 - let groupID = jQuery(group).attr('id');
177 - let data = mainwp_secure_data({
178 - action: 'mainwp_group_getsites',
179 - groupId: groupID
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 + }
180 272 });
181 - jQuery('.dimmer').addClass('active');
182 - jQuery.post(ajaxurl, data, function (response) {
183 - jQuery('.dimmer').removeClass('active');
184 - response = response.trim();
185 - if (response == 'ERROR') {
186 - return;
187 - }
188 - let dtApi = jQuery('#mainwp-manage-groups-sites-table').dataTable().api();
189 - mainwp_datatable_fix_to_update_selected_rows_status(dtApi, 'deselected'); // clear saved state.
190 - jQuery('input.mainwp-site-checkbox').prop('checked', false);
191 - jQuery('input.mainwp-site-checkbox').closest('tr').removeClass('selected');
192 - let sites = JSON.parse(response);
193 - for (let id of sites) {
194 - jQuery('input[value="' + id + '"].mainwp-site-checkbox').prop('checked', true);
195 - jQuery('input[value="' + id + '"].mainwp-site-checkbox').closest('tr').addClass('selected');
196 - }
197 - mainwp_datatable_fix_to_update_selected_rows_status(dtApi, 'selected'); // clear saved state.
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');
198 305 });
199 - return false;
200 - }
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 + }
201 358
202 359 });