nodebb-plugin-equipment-calendar 9.0.6 → 9.0.7

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/library.js CHANGED
@@ -132,7 +132,6 @@ const { v4: uuidv4 } = require('uuid');
132
132
  const crypto = require('crypto');
133
133
 
134
134
  const plugin = {};
135
- const SETTINGS_DB_KEY = 'equipmentCalendar:settings';
136
135
  const SETTINGS_KEY = 'equipmentCalendar';
137
136
 
138
137
  const DEFAULT_SETTINGS = {
@@ -160,6 +159,39 @@ const DEFAULT_SETTINGS = {
160
159
  showRequesterToAll: '0', // 0/1
161
160
  };
162
161
 
162
+ function normalizeSettings(raw) {
163
+ const out = {};
164
+ const keys = Object.keys(DEFAULT_SETTINGS);
165
+ keys.forEach((k) => {
166
+ const def = DEFAULT_SETTINGS[k];
167
+ const str = raw && raw[k];
168
+ if (typeof str !== 'string') {
169
+ out[k] = def;
170
+ return;
171
+ }
172
+ try {
173
+ const v = JSON.parse(str);
174
+ out[k] = (typeof v === typeof def) ? v : def;
175
+ } catch (e) {
176
+ out[k] = def;
177
+ }
178
+ });
179
+ return out;
180
+ }
181
+ async function getSettings() {
182
+ const raw = await meta.settings.get('equipmentCalendar');
183
+ return normalizeSettings(raw);
184
+ }
185
+ async function setSettings(payload) {
186
+ const sets = {};
187
+ Object.keys(payload || {}).forEach((k) => {
188
+ sets[k] = JSON.stringify(payload[k]);
189
+ });
190
+ await setSettings(payload);
191
+ }
192
+
193
+
194
+
163
195
 
164
196
  function parseLocationMap(locationMapJson) {
165
197
  try {
@@ -407,18 +439,6 @@ async function getActiveItems() {
407
439
  return items;
408
440
  }
409
441
 
410
- async function getSettings() {
411
- const defaults = DEFAULT_SETTINGS;
412
- try {
413
- const saved = await db.getObject(SETTINGS_DB_KEY);
414
- const merged = Object.assign({}, defaults, saved || {});
415
- // normalize numbers
416
- merged.paymentTimeoutMinutes = parseInt(merged.paymentTimeoutMinutes, 10) || defaults.paymentTimeoutMinutes;
417
- return merged;
418
- } catch (e) {
419
- return Object.assign({}, defaults);
420
- }
421
- }
422
442
 
423
443
  // --- Data layer ---
424
444
  // Keys:
@@ -1593,8 +1613,8 @@ async function handleAdminSave(req, res) {
1593
1613
  showRequesterToAll: (req.body.showRequesterToAll === '1' || req.body.showRequesterToAll === 'on') ? '1' : '0',
1594
1614
  };
1595
1615
 
1596
- await meta.settings.set(SETTINGS_KEY, values);
1597
- return res.redirect('/admin/plugins/equipment-calendar?saved=1');
1616
+ await setSettings(payload);
1617
+ return res.redirect('/admin/plugins/equipment-calendar?saved=1');
1598
1618
  } catch (e) {
1599
1619
  return res.status(500).send(e.message || 'error');
1600
1620
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodebb-plugin-equipment-calendar",
3
- "version": "9.0.6",
3
+ "version": "9.0.7",
4
4
  "description": "Equipment reservation calendar for NodeBB (FullCalendar, approvals, HelloAsso payments)",
5
5
  "main": "library.js",
6
6
  "scripts": {
package/plugin.json CHANGED
@@ -25,6 +25,9 @@
25
25
  "scripts": [
26
26
  "public/js/client.js"
27
27
  ],
28
- "version": "3.0.0-stable4t-db-settings",
29
- "minver": "4.7.1"
28
+ "version": "3.0.0-stable4u-official-acp",
29
+ "minver": "4.7.1",
30
+ "acpScripts": [
31
+ "public/js/admin.js"
32
+ ]
30
33
  }
@@ -1,20 +1,14 @@
1
- 'use strict';
2
-
3
- /* global define */
4
1
 
5
- define('admin/plugins/equipment-calendar', ['jquery', 'settings', 'alerts'], function ($, Settings, alerts) {
2
+ 'use strict';
3
+ define('admin/plugins/equipment-calendar', ['settings', 'alerts'], function (Settings, alerts) {
6
4
  const Admin = {};
7
-
8
5
  Admin.init = function () {
9
- const $container = $('.equipment-calendar-settings');
10
- Settings.load('equipmentCalendar', $container);
11
-
6
+ Settings.load('equipmentCalendar', $('.equipment-calendar-settings'));
12
7
  $('#save').on('click', function () {
13
- Settings.save('equipmentCalendar', $container, function () {
14
- alerts.success('Sauvegardé');
8
+ Settings.save('equipmentCalendar', $('.equipment-calendar-settings'), function () {
9
+ alerts.success('[[admin/settings:settings-saved]]');
15
10
  });
16
11
  });
17
12
  };
18
-
19
13
  return Admin;
20
14
  });
@@ -174,16 +174,20 @@ function updateTotalPrice() {
174
174
  timeZone: 'UTC',
175
175
  events: events,
176
176
  select: function (info) {
177
- if (!window.EC_CAN_CREATE) return;
178
- const startIso = String(info.startStr || '').slice(0,10); // YYYY-MM-DD
179
- const endEnd = String(info.endStr || '').slice(0,10);
180
- const endIsoInclusive = addDaysIsoLocal(endEnd, -1); // endStr is exclusive
181
- openCreateModal(startIso, endIsoInclusive);
182
- },
177
+ var startIso = String(info.startStr || '').slice(0, 10);
178
+ var endExcl = String(info.endStr || '').slice(0, 10);
179
+ var endIso = endExcl;
180
+ if (endExcl) {
181
+ var d = new Date(endExcl + 'T00:00:00Z');
182
+ d.setUTCDate(d.getUTCDate() - 1);
183
+ endIso = d.toISOString().slice(0, 10);
184
+ }
185
+ window.EC_openReservationModal(startIso, endIso);
186
+ },
183
187
  dateClick: function (info) {
184
- if (!window.EC_CAN_CREATE) return;
185
- openCreateModal(String(info.dateStr||'').slice(0,10), String(info.dateStr||'').slice(0,10));
186
- },
188
+ var startIso = String(info.dateStr || '').slice(0, 10);
189
+ window.EC_openReservationModal(startIso, startIso);
190
+ },
187
191
  eventClick: function (info) {
188
192
  try {
189
193
  info.jsEvent && info.jsEvent.preventDefault && info.jsEvent.preventDefault();
@@ -1,83 +1,74 @@
1
+
1
2
  <div class="acp-page-container">
2
- <div class="d-flex align-items-center justify-content-between flex-wrap gap-2">
3
- <h1 class="mb-0">Equipment Calendar</h1>
4
- <div class="btn-group">
5
- <a class="btn btn-secondary active" href="{config.relative_path}/admin/plugins/equipment-calendar">Paramètres</a>
6
- <a class="btn btn-outline-secondary" href="{config.relative_path}/admin/plugins/equipment-calendar/reservations">Réservations</a>
7
- </div>
8
- </div>
3
+ <h1 class="mb-3">Equipment Calendar</h1>
9
4
 
10
- <form class="equipment-calendar-settings mt-3" method="post" action="{config.relative_path}/admin/plugins/equipment-calendar/save">
11
- <input type="hidden" name="_csrf" value="{csrf_token}">
5
+ <form role="form" class="equipment-calendar-settings">
12
6
  <div class="card card-body mb-3">
13
- <h5>Permissions</h5>
7
+ <h5 class="mb-3">Permissions</h5>
14
8
  <div class="mb-3">
15
9
  <label class="form-label">creatorGroups (séparés par virgule)</label>
16
- <input class="form-control" type="text" name="creatorGroups" value="{settings.creatorGroups}">
10
+ <input class="form-control" type="text" data-field="creatorGroups" value="{settings.creatorGroups}">
17
11
  </div>
18
12
  <div class="mb-3">
19
13
  <label class="form-label">approverGroup</label>
20
- <input class="form-control" type="text" name="approverGroup" value="{settings.approverGroup}">
14
+ <input class="form-control" type="text" data-field="approverGroup" value="{settings.approverGroup}">
21
15
  </div>
22
16
  <div class="mb-0">
23
17
  <label class="form-label">notifyGroup</label>
24
- <input class="form-control" type="text" name="notifyGroup" value="{settings.notifyGroup}">
18
+ <input class="form-control" type="text" data-field="notifyGroup" value="{settings.notifyGroup}">
25
19
  </div>
26
20
  </div>
27
21
 
28
22
  <div class="card card-body mb-3">
29
- <h5>HelloAsso</h5>
23
+ <h5 class="mb-3">HelloAsso</h5>
30
24
  <div class="row g-3">
31
25
  <div class="col-md-6">
32
- <label class="form-label">API base URL</label>
33
- <input class="form-control" type="text" name="ha_apiBaseUrl" value="{settings.ha_apiBaseUrl}" placeholder="https://api.helloasso.com ou https://api.helloasso-sandbox.com">
26
+ <label class="form-label">API base URL (prod ou sandbox)</label>
27
+ <input class="form-control" type="text" data-field="ha_apiBaseUrl" value="{settings.ha_apiBaseUrl}" placeholder="https://api.helloasso.com ou https://api.helloasso-sandbox.com">
34
28
  </div>
35
29
  <div class="col-md-6">
36
30
  <label class="form-label">Organization slug</label>
37
- <input class="form-control" type="text" name="ha_organizationSlug" value="{settings.ha_organizationSlug}">
31
+ <input class="form-control" type="text" data-field="ha_organizationSlug" value="{settings.ha_organizationSlug}">
38
32
  </div>
39
33
  <div class="col-md-6">
40
34
  <label class="form-label">Client ID</label>
41
- <input class="form-control" type="text" name="ha_clientId" value="{settings.ha_clientId}">
35
+ <input class="form-control" type="text" data-field="ha_clientId" value="{settings.ha_clientId}">
42
36
  </div>
43
37
  <div class="col-md-6">
44
38
  <label class="form-label">Client Secret</label>
45
- <input class="form-control" type="password" name="ha_clientSecret" value="{settings.ha_clientSecret}">
39
+ <input class="form-control" type="password" data-field="ha_clientSecret" value="{settings.ha_clientSecret}">
46
40
  </div>
47
41
  <div class="col-md-6">
48
42
  <label class="form-label">Form Type</label>
49
- <input class="form-control" type="text" name="ha_itemsFormType" value="{settings.ha_itemsFormType}" placeholder="shop">
43
+ <input class="form-control" type="text" data-field="ha_itemsFormType" value="{settings.ha_itemsFormType}" placeholder="shop">
50
44
  </div>
51
45
  <div class="col-md-6">
52
46
  <label class="form-label">Form Slug</label>
53
- <input class="form-control" type="text" name="ha_itemsFormSlug" value="{settings.ha_itemsFormSlug}" placeholder="locations-materiel-2026">
47
+ <input class="form-control" type="text" data-field="ha_itemsFormSlug" value="{settings.ha_itemsFormSlug}" placeholder="locations-materiel-2026">
54
48
  </div>
55
49
  <div class="col-12">
56
50
  <label class="form-label">Return URL base (callback)</label>
57
- <input class="form-control" type="text" name="ha_returnUrl" value="{settings.ha_returnUrl}" placeholder="https://www.onekite.com">
51
+ <input class="form-control" type="text" data-field="ha_returnUrl" value="{settings.ha_returnUrl}" placeholder="https://www.onekite.com">
58
52
  </div>
59
53
  </div>
60
54
  </div>
61
55
 
62
56
  <div class="card card-body mb-3">
63
- <h5>Paiement</h5>
57
+ <h5 class="mb-3">Paiement</h5>
64
58
  <div class="row g-3">
65
59
  <div class="col-md-6">
66
60
  <label class="form-label">paymentTimeoutMinutes</label>
67
- <input class="form-control" type="number" min="1" name="paymentTimeoutMinutes" value="{settings.paymentTimeoutMinutes}">
61
+ <input class="form-control" type="number" min="1" data-field="paymentTimeoutMinutes" value="{settings.paymentTimeoutMinutes}">
68
62
  </div>
69
63
  </div>
70
64
  </div>
71
65
 
72
- <button class="btn btn-primary" type="submit">Enregistrer</button>
66
+ <button id="save" type="button" class="btn btn-primary">Enregistrer</button>
73
67
  </form>
74
-
75
- <script>
76
- (function () {
77
- var params = new URLSearchParams(window.location.search || '');
78
- if (params.get('saved') === '1') {
79
- require(['alerts'], function (alerts) { alerts.success('Paramètres enregistrés'); });
80
- }
81
- })();
82
- </script>
83
68
  </div>
69
+
70
+ <script>
71
+ require(['admin/plugins/equipment-calendar'], function (mod) {
72
+ mod.init();
73
+ });
74
+ </script>