PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / assets / js / admin-dashboard.js

admin-dashboard.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at assets/js/admin-dashboard.js

245 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Blockenberg — Block Manager Dashboard JS
3 *
4 * Handles: search, category tabs, toggle switches, bulk actions,
5 * unsaved-changes indicator, and AJAX save.
6 */
7 (function ($) {
8 'use strict';
9
10 /* ── DOM refs ─────────────────────────────── */
11 var $grid = $('#bkbg-grid');
12 var $cards = $grid.find('.bkbg-card');
13 var $sections = $grid.find('.bkbg-category-section');
14 var $tabs = $('#bkbg-category-tabs');
15 var $search = $('#bkbg-search');
16 var $saveBtn = $('#bkbg-save');
17 var $enableAll = $('#bkbg-enable-all');
18 var $disableAll = $('#bkbg-disable-all');
19 var $toast = $('#bkbg-toast');
20 var $empty = $('#bkbg-empty');
21 var $enabledCount = $('#bkbg-enabled-count');
22
23 var dirty = false;
24 var saving = false;
25 var activeCategory = 'all';
26 var toastTimer;
27
28 /* ── Helpers ──────────────────────────────── */
29 function showToast(msg, type) {
30 clearTimeout(toastTimer);
31 $toast
32 .text(msg)
33 .removeClass('bkbg-toast--success bkbg-toast--error')
34 .addClass('bkbg-toast--visible' + (type ? ' bkbg-toast--' + type : ''));
35 toastTimer = setTimeout(function () {
36 $toast.removeClass('bkbg-toast--visible');
37 }, 3000);
38 }
39
40 function updateEnabledCount() {
41 var total = $cards.length;
42 var enabled = $cards.find('.bkbg-toggle__input:checked').length;
43 $enabledCount.text(enabled);
44 }
45
46 function setDirty() {
47 if (!dirty) {
48 dirty = true;
49 $saveBtn.addClass('bkbg-btn--unsaved');
50 }
51 }
52
53 function clearDirty() {
54 dirty = false;
55 $saveBtn.removeClass('bkbg-btn--unsaved');
56 }
57
58 function getDisabledBlocks() {
59 var disabled = [];
60 $cards.find('.bkbg-toggle__input').each(function () {
61 if (!this.checked) {
62 disabled.push($(this).data('block'));
63 }
64 });
65 return disabled;
66 }
67
68 function applyVisibility() {
69 var query = $.trim($search.val()).toLowerCase();
70 var visibleSections = {};
71 var totalVisible = 0;
72
73 $cards.each(function () {
74 var $card = $(this);
75 var category = $card.closest('.bkbg-category-section').data('category');
76 var matchCat = activeCategory === 'all' || category === activeCategory;
77 var matchSearch = true;
78
79 if (query) {
80 var title = $card.data('title') || '';
81 var slug = $card.data('slug') || '';
82 var keywords = $card.data('keywords') || '';
83 matchSearch = title.indexOf(query) !== -1 ||
84 slug.indexOf(query) !== -1 ||
85 keywords.indexOf(query) !== -1;
86 }
87
88 if (matchCat && matchSearch) {
89 $card.removeClass('bkbg-card--hidden');
90 visibleSections[category] = true;
91 totalVisible++;
92 } else {
93 $card.addClass('bkbg-card--hidden');
94 }
95 });
96
97 /* Show/hide category sections */
98 $sections.each(function () {
99 var cat = $(this).data('category');
100
101 if (activeCategory !== 'all' && cat !== activeCategory) {
102 $(this).hide();
103 return;
104 }
105
106 if (visibleSections[cat]) {
107 $(this).show();
108 } else {
109 $(this).hide();
110 }
111 });
112
113 /* Empty state */
114 if (totalVisible === 0) {
115 $empty.show();
116 } else {
117 $empty.hide();
118 }
119 }
120
121 /* ── Category tabs ───────────────────────── */
122 $tabs.on('click', '.bkbg-tab', function () {
123 $tabs.find('.bkbg-tab').removeClass('bkbg-tab--active');
124 $(this).addClass('bkbg-tab--active');
125 activeCategory = $(this).data('category');
126 applyVisibility();
127 });
128
129 /* ── Search ──────────────────────────────── */
130 var searchDebounce;
131 $search.on('input', function () {
132 clearTimeout(searchDebounce);
133 searchDebounce = setTimeout(applyVisibility, 150);
134 });
135
136 /* ── Toggle switch ───────────────────────── */
137 $grid.on('change', '.bkbg-toggle__input', function () {
138 var $card = $(this).closest('.bkbg-card');
139 if (this.checked) {
140 $card.removeClass('bkbg-card--disabled');
141 } else {
142 $card.addClass('bkbg-card--disabled');
143 }
144 updateEnabledCount();
145 setDirty();
146 });
147
148 /* ── Card click (toggle on card click) ──── */
149 $grid.on('click', '.bkbg-card', function (e) {
150 /* Don't toggle when clicking the toggle itself */
151 if ($(e.target).closest('.bkbg-toggle').length) {
152 return;
153 }
154 var $cb = $(this).find('.bkbg-toggle__input');
155 $cb.prop('checked', !$cb.prop('checked')).trigger('change');
156 });
157
158 /* ── Bulk: Enable All / Disable All (visible) ─── */
159 $enableAll.on('click', function () {
160 $cards.not('.bkbg-card--hidden').find('.bkbg-toggle__input').each(function () {
161 if (!this.checked) {
162 $(this).prop('checked', true).trigger('change');
163 }
164 });
165 });
166
167 $disableAll.on('click', function () {
168 $cards.not('.bkbg-card--hidden').find('.bkbg-toggle__input').each(function () {
169 if (this.checked) {
170 $(this).prop('checked', false).trigger('change');
171 }
172 });
173 });
174
175 /* ── Per-category enable/disable ─────────── */
176 $grid.on('click', '.bkbg-cat-toggle', function () {
177 var action = $(this).data('action');
178 var cat = $(this).data('cat');
179 var $sec = $grid.find('.bkbg-category-section[data-category="' + cat + '"]');
180 var check = action === 'enable';
181
182 $sec.find('.bkbg-toggle__input').each(function () {
183 if (this.checked !== check) {
184 $(this).prop('checked', check).trigger('change');
185 }
186 });
187 });
188
189 /* ── Save ────────────────────────────────── */
190 $saveBtn.on('click', function () {
191 if (saving) return;
192 saving = true;
193 $saveBtn.addClass('bkbg-btn--saving');
194 showToast(bkbgDashboard.i18n.saving);
195
196 var disabled = getDisabledBlocks();
197
198 $.ajax({
199 url: bkbgDashboard.ajaxUrl,
200 method: 'POST',
201 data: {
202 action: 'bkbg_save_disabled_blocks',
203 nonce: bkbgDashboard.nonce,
204 disabled: JSON.stringify(disabled)
205 },
206 success: function (resp) {
207 if (resp.success) {
208 clearDirty();
209 showToast(bkbgDashboard.i18n.saved, 'success');
210 } else {
211 showToast(bkbgDashboard.i18n.error, 'error');
212 }
213 },
214 error: function () {
215 showToast(bkbgDashboard.i18n.error, 'error');
216 },
217 complete: function () {
218 saving = false;
219 $saveBtn.removeClass('bkbg-btn--saving');
220 }
221 });
222 });
223
224 /* ── Keyboard shortcut: Ctrl/Cmd+S ─────── */
225 $(document).on('keydown', function (e) {
226 if ((e.ctrlKey || e.metaKey) && e.key === 's') {
227 e.preventDefault();
228 if (dirty) {
229 $saveBtn.trigger('click');
230 }
231 }
232 });
233
234 /* ── Warn before leaving with unsaved changes ── */
235 $(window).on('beforeunload', function () {
236 if (dirty) {
237 return true;
238 }
239 });
240
241 /* ── Init ────────────────────────────────── */
242 updateEnabledCount();
243
244 })(jQuery);
245