nodebb-plugin-onekite-calendar 2.0.4 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog – calendar-onekite
2
2
 
3
+ ## 1.2.13
4
+ - ACP (mode sombre) : correction de la visibilité de la liste d’autocomplete d’adresse (couleurs via variables Bootstrap)
5
+
6
+ ## 1.2.12
7
+ - Modales (calendrier + ACP) : autocomplete adresse rendu identique et compatible Bootstrap input-group (plus de wrapper qui casse l’affichage)
8
+
3
9
  ## 1.2.11
4
10
  - ACP : ajout de la recherche automatique d’adresse (autocomplete Nominatim) dans la modale de validation (unitaire + batch), comme sur le calendrier
5
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-onekite-calendar",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "FullCalendar-based equipment reservation workflow with admin approval & HelloAsso payment for NodeBB",
5
5
  "main": "library.js",
6
6
  "license": "MIT",
package/plugin.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "acpScripts": [
40
40
  "public/admin.js"
41
41
  ],
42
- "version": "2.0.4"
42
+ "version": "2.0.6"
43
43
  }
package/public/admin.js CHANGED
@@ -2,6 +2,36 @@
2
2
  define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts, bootbox) {
3
3
  'use strict';
4
4
 
5
+ // ACP dark mode compatibility: style the address autocomplete dropdown using
6
+ // Bootstrap CSS variables (so it remains readable in dark themes).
7
+ (function ensureOnekiteAdminStyles() {
8
+ try {
9
+ if (document.getElementById('onekite-acp-inline-styles')) return;
10
+ const style = document.createElement('style');
11
+ style.id = 'onekite-acp-inline-styles';
12
+ style.textContent = `
13
+ .onekite-autocomplete-menu {
14
+ background: var(--bs-body-bg, #fff);
15
+ color: var(--bs-body-color, #212529);
16
+ border: 1px solid var(--bs-border-color, rgba(0,0,0,.15));
17
+ box-shadow: 0 .5rem 1rem rgba(0,0,0,.15);
18
+ }
19
+ .onekite-autocomplete-item {
20
+ color: inherit;
21
+ background: transparent;
22
+ }
23
+ .onekite-autocomplete-item:hover,
24
+ .onekite-autocomplete-item:focus {
25
+ background: var(--bs-tertiary-bg, rgba(0,0,0,.05));
26
+ outline: none;
27
+ }
28
+ `;
29
+ document.head.appendChild(style);
30
+ } catch (e) {
31
+ // ignore
32
+ }
33
+ })();
34
+
5
35
  // Cache of pending reservations keyed by rid so delegated click handlers
6
36
  // can open rich modals without embedding large JSON blobs into the DOM.
7
37
  const pendingCache = new Map();
@@ -220,11 +250,18 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
220
250
  if (inputEl.getAttribute('data-onekite-autocomplete') === '1') return;
221
251
  inputEl.setAttribute('data-onekite-autocomplete', '1');
222
252
 
223
- const anchor = inputEl.closest('.input-group') || inputEl.parentNode;
224
- if (!anchor) return;
253
+ // In Bootstrap input-groups (especially in ACP), wrapping the input breaks layout.
254
+ // So we anchor the menu to the closest input-group (or parent) without moving the input.
255
+ const anchor = inputEl.closest && inputEl.closest('.input-group')
256
+ ? inputEl.closest('.input-group')
257
+ : (inputEl.parentNode || document.body);
225
258
 
226
- // Ensure positioning context
227
- if (getComputedStyle(anchor).position === 'static') {
259
+ try {
260
+ const cs = window.getComputedStyle(anchor);
261
+ if (!cs || cs.position === 'static') {
262
+ anchor.style.position = 'relative';
263
+ }
264
+ } catch (e) {
228
265
  anchor.style.position = 'relative';
229
266
  }
230
267
 
@@ -235,14 +272,12 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
235
272
  menu.style.right = '0';
236
273
  menu.style.top = '100%';
237
274
  menu.style.zIndex = '2000';
238
- menu.style.background = '#fff';
239
- menu.style.border = '1px solid rgba(0,0,0,.15)';
275
+ // Colors are handled via CSS variables (supports ACP dark mode).
240
276
  menu.style.borderTop = '0';
241
277
  menu.style.maxHeight = '220px';
242
278
  menu.style.overflowY = 'auto';
243
279
  menu.style.display = 'none';
244
280
  menu.style.borderRadius = '0 0 .375rem .375rem';
245
- menu.style.boxShadow = '0 .25rem .75rem rgba(0,0,0,.08)';
246
281
  anchor.appendChild(menu);
247
282
 
248
283
  let timer = null;
@@ -270,15 +305,12 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
270
305
  btn.style.textAlign = 'left';
271
306
  btn.style.padding = '.35rem .5rem';
272
307
  btn.style.border = '0';
273
- btn.style.background = 'transparent';
274
308
  btn.style.cursor = 'pointer';
275
309
  btn.addEventListener('click', () => {
276
310
  inputEl.value = h.displayName;
277
311
  hide();
278
312
  try { onPick && onPick(h); } catch (e) {}
279
313
  });
280
- btn.addEventListener('mouseenter', () => { btn.style.background = 'rgba(0,0,0,.05)'; });
281
- btn.addEventListener('mouseleave', () => { btn.style.background = 'transparent'; });
282
314
  menu.appendChild(btn);
283
315
  });
284
316
  menu.style.display = 'block';
package/public/client.js CHANGED
@@ -638,10 +638,20 @@ function attachAddressAutocomplete(inputEl, onPick) {
638
638
  if (inputEl.getAttribute('data-onekite-autocomplete') === '1') return;
639
639
  inputEl.setAttribute('data-onekite-autocomplete', '1');
640
640
 
641
- const wrapper = document.createElement('div');
642
- wrapper.style.position = 'relative';
643
- inputEl.parentNode && inputEl.parentNode.insertBefore(wrapper, inputEl);
644
- wrapper.appendChild(inputEl);
641
+ // In Bootstrap input-groups (especially in ACP), wrapping the input breaks layout.
642
+ // So we anchor the menu to the closest input-group (or parent) without moving the input.
643
+ const host = inputEl.closest && inputEl.closest('.input-group')
644
+ ? inputEl.closest('.input-group')
645
+ : (inputEl.parentNode || document.body);
646
+
647
+ try {
648
+ const cs = window.getComputedStyle(host);
649
+ if (!cs || cs.position === 'static') {
650
+ host.style.position = 'relative';
651
+ }
652
+ } catch (e) {
653
+ host.style.position = 'relative';
654
+ }
645
655
 
646
656
  const menu = document.createElement('div');
647
657
  menu.className = 'onekite-autocomplete-menu';
@@ -657,7 +667,7 @@ function attachAddressAutocomplete(inputEl, onPick) {
657
667
  menu.style.overflowY = 'auto';
658
668
  menu.style.display = 'none';
659
669
  menu.style.borderRadius = '0 0 .375rem .375rem';
660
- wrapper.appendChild(menu);
670
+ host.appendChild(menu);
661
671
 
662
672
  let timer = null;
663
673
  let lastQuery = '';
@@ -735,7 +745,7 @@ function attachAddressAutocomplete(inputEl, onPick) {
735
745
  // Close when clicking outside
736
746
  document.addEventListener('click', (e) => {
737
747
  try {
738
- if (!wrapper.contains(e.target)) hide();
748
+ if (!host.contains(e.target)) hide();
739
749
  } catch (err) {}
740
750
  });
741
751