nodebb-plugin-calendar-onekite 11.1.7 → 11.1.8
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 +35 -22
- package/package.json +1 -1
- package/public/admin.js +6 -6
- package/public/client.js +3 -3
- package/templates/admin/plugins/calendar-onekite.tpl +87 -83
package/library.js
CHANGED
|
@@ -5,27 +5,44 @@ const api = require('./lib/api');
|
|
|
5
5
|
const admin = require('./lib/admin');
|
|
6
6
|
const scheduler = require('./lib/scheduler');
|
|
7
7
|
|
|
8
|
+
const routeHelpers = require.main.require('./src/routes/helpers');
|
|
9
|
+
|
|
8
10
|
const Plugin = {};
|
|
9
11
|
|
|
10
12
|
Plugin.init = async function (params) {
|
|
11
|
-
const { router } = params;
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
13
|
+
const { router, middleware } = params;
|
|
14
|
+
|
|
15
|
+
// Public page
|
|
16
|
+
routeHelpers.setupPageRoute(router, '/calendar', [
|
|
17
|
+
middleware.exposeUid,
|
|
18
|
+
middleware.buildHeader,
|
|
19
|
+
], controllers.renderCalendar);
|
|
20
|
+
|
|
21
|
+
// ACP page
|
|
22
|
+
routeHelpers.setupAdminPageRoute(router, '/admin/plugins/calendar-onekite', [], admin.renderAdmin);
|
|
23
|
+
|
|
24
|
+
// API routes (NodeBB will mount these under /api/v3)
|
|
25
|
+
routeHelpers.setupApiRoute(router, 'get', '/plugins/calendar-onekite/events', [middleware.exposeUid], api.getEvents);
|
|
26
|
+
routeHelpers.setupApiRoute(router, 'get', '/plugins/calendar-onekite/items', [middleware.exposeUid], api.getItems);
|
|
27
|
+
routeHelpers.setupApiRoute(router, 'post', '/plugins/calendar-onekite/reservations', [
|
|
28
|
+
middleware.exposeUid,
|
|
29
|
+
middleware.ensureLoggedIn,
|
|
30
|
+
], api.createReservation);
|
|
31
|
+
|
|
32
|
+
// Admin API routes (also under /api/v3/admin/...)
|
|
33
|
+
const adminMiddlewares = [
|
|
34
|
+
middleware.exposeUid,
|
|
35
|
+
middleware.ensureLoggedIn,
|
|
36
|
+
middleware.admin.checkPrivileges,
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
routeHelpers.setupApiRoute(router, 'get', '/admin/plugins/calendar-onekite/settings', adminMiddlewares, admin.getSettings);
|
|
40
|
+
routeHelpers.setupApiRoute(router, 'put', '/admin/plugins/calendar-onekite/settings', adminMiddlewares, admin.saveSettings);
|
|
41
|
+
routeHelpers.setupApiRoute(router, 'get', '/admin/plugins/calendar-onekite/pending', adminMiddlewares, admin.listPending);
|
|
42
|
+
routeHelpers.setupApiRoute(router, 'put', '/admin/plugins/calendar-onekite/reservations/:rid/approve', adminMiddlewares, admin.approveReservation);
|
|
43
|
+
routeHelpers.setupApiRoute(router, 'put', '/admin/plugins/calendar-onekite/reservations/:rid/refuse', adminMiddlewares, admin.refuseReservation);
|
|
44
|
+
routeHelpers.setupApiRoute(router, 'post', '/admin/plugins/calendar-onekite/purge', adminMiddlewares, admin.purgeByYear);
|
|
45
|
+
|
|
29
46
|
scheduler.start();
|
|
30
47
|
};
|
|
31
48
|
|
|
@@ -38,8 +55,4 @@ Plugin.addAdminNavigation = async function (header) {
|
|
|
38
55
|
return header;
|
|
39
56
|
};
|
|
40
57
|
|
|
41
|
-
// Keep compatibility with older NodeBB plugin routing hooks
|
|
42
|
-
Plugin.addPageRoute = async function (routes) { return routes; };
|
|
43
|
-
Plugin.addApiRoute = async function (routes) { return routes; };
|
|
44
|
-
|
|
45
58
|
module.exports = Plugin;
|
package/package.json
CHANGED
package/public/admin.js
CHANGED
|
@@ -105,7 +105,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
105
105
|
const listEl = qs('#calendar-onekite-pending-list');
|
|
106
106
|
if (!listEl) return;
|
|
107
107
|
try {
|
|
108
|
-
const resp = await http('GET', '/api/admin/plugins/calendar-onekite/pending');
|
|
108
|
+
const resp = await http('GET', '/api/v3/admin/plugins/calendar-onekite/pending');
|
|
109
109
|
listEl.innerHTML = renderPending(resp.pending || []);
|
|
110
110
|
} catch (e) {
|
|
111
111
|
listEl.innerHTML = '<div class="alert alert-danger">Impossible de charger les demandes en attente.</div>';
|
|
@@ -125,7 +125,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
125
125
|
|
|
126
126
|
if (btn.classList.contains('js-approve')) {
|
|
127
127
|
try {
|
|
128
|
-
await http('PUT', `/api/admin/plugins/calendar-onekite/reservations/${rid}/approve`);
|
|
128
|
+
await http('PUT', `/api/v3/admin/plugins/calendar-onekite/reservations/${rid}/approve`);
|
|
129
129
|
alertSuccess('Réservation validée, lien de paiement envoyé.');
|
|
130
130
|
await refreshPending();
|
|
131
131
|
} catch (e) {
|
|
@@ -141,7 +141,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
141
141
|
});
|
|
142
142
|
});
|
|
143
143
|
try {
|
|
144
|
-
await http('PUT', `/api/admin/plugins/calendar-onekite/reservations/${rid}/refuse`, { note });
|
|
144
|
+
await http('PUT', `/api/v3/admin/plugins/calendar-onekite/reservations/${rid}/refuse`, { note });
|
|
145
145
|
alertSuccess('Réservation refusée, email envoyé.');
|
|
146
146
|
await refreshPending();
|
|
147
147
|
} catch (e) {
|
|
@@ -160,7 +160,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
160
160
|
ev.preventDefault();
|
|
161
161
|
const payload = getFormData();
|
|
162
162
|
try {
|
|
163
|
-
await http('
|
|
163
|
+
await http('PUT', '/api/v3/admin/plugins/calendar-onekite/settings', payload);
|
|
164
164
|
if (savedEl) {
|
|
165
165
|
savedEl.classList.remove('d-none');
|
|
166
166
|
setTimeout(() => savedEl.classList.add('d-none'), 2000);
|
|
@@ -181,7 +181,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
181
181
|
ev.preventDefault();
|
|
182
182
|
const year = qs('[name="year"]', form)?.value || '';
|
|
183
183
|
try {
|
|
184
|
-
const resp = await http('POST', '/api/admin/plugins/calendar-onekite/purge', { year });
|
|
184
|
+
const resp = await http('POST', '/api/v3/admin/plugins/calendar-onekite/purge', { year });
|
|
185
185
|
const y = resp?.result?.year;
|
|
186
186
|
const purged = resp?.result?.purged;
|
|
187
187
|
if (resultEl) resultEl.innerHTML = `<div class="alert alert-success">Année ${y}: ${purged} réservation(s) supprimée(s).</div>`;
|
|
@@ -193,7 +193,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
193
193
|
|
|
194
194
|
async function init() {
|
|
195
195
|
try {
|
|
196
|
-
const resp = await http('GET', '/api/admin/plugins/calendar-onekite');
|
|
196
|
+
const resp = await http('GET', '/api/v3/admin/plugins/calendar-onekite/settings');
|
|
197
197
|
setForm(resp.settings || {});
|
|
198
198
|
} catch (e) {
|
|
199
199
|
alertError('Impossible de charger les paramètres.');
|
package/public/client.js
CHANGED
|
@@ -67,7 +67,7 @@ define('forum/calendar-onekite', ['alerts', 'bootbox'], function (alerts, bootbo
|
|
|
67
67
|
},
|
|
68
68
|
events: async function (info, success, failure) {
|
|
69
69
|
try {
|
|
70
|
-
const resp = await http('GET', `/api/calendar-onekite/events?start=${encodeURIComponent(info.startStr)}&end=${encodeURIComponent(info.endStr)}`);
|
|
70
|
+
const resp = await http('GET', `/api/v3/plugins/calendar-onekite/events?start=${encodeURIComponent(info.startStr)}&end=${encodeURIComponent(info.endStr)}`);
|
|
71
71
|
success(resp.events || resp);
|
|
72
72
|
} catch (err) {
|
|
73
73
|
failure(err);
|
|
@@ -107,7 +107,7 @@ define('forum/calendar-onekite', ['alerts', 'bootbox'], function (alerts, bootbo
|
|
|
107
107
|
async function openReservationDialog(startStr, endStr) {
|
|
108
108
|
let itemsResp;
|
|
109
109
|
try {
|
|
110
|
-
itemsResp = await http('GET', '/api/calendar-onekite/items');
|
|
110
|
+
itemsResp = await http('GET', '/api/v3/plugins/calendar-onekite/items');
|
|
111
111
|
} catch (e) {
|
|
112
112
|
return bootbox.alert('Impossible de récupérer la liste du matériel (HelloAsso). Vérifiez les paramètres dans l’ACP.');
|
|
113
113
|
}
|
|
@@ -162,7 +162,7 @@ define('forum/calendar-onekite', ['alerts', 'bootbox'], function (alerts, bootbo
|
|
|
162
162
|
};
|
|
163
163
|
|
|
164
164
|
try {
|
|
165
|
-
await http('POST', '/api/calendar-onekite/reservations', payload);
|
|
165
|
+
await http('POST', '/api/v3/plugins/calendar-onekite/reservations', payload);
|
|
166
166
|
alertSuccess('Demande envoyée (en attente de validation).');
|
|
167
167
|
calendar.refetchEvents();
|
|
168
168
|
} catch (err) {
|
|
@@ -1,103 +1,107 @@
|
|
|
1
1
|
<div class="acp-page-container">
|
|
2
2
|
<div class="row">
|
|
3
|
-
<div class="col-lg-
|
|
4
|
-
<
|
|
3
|
+
<div class="col-lg-8">
|
|
4
|
+
<h3 class="mb-3">Calendar OneKite</h3>
|
|
5
5
|
|
|
6
|
-
<form id="calendar-onekite-settings"
|
|
7
|
-
<div class="mb-3">
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
|
|
6
|
+
<form id="calendar-onekite-settings">
|
|
7
|
+
<div class="card mb-3">
|
|
8
|
+
<div class="card-header">Accès & workflow</div>
|
|
9
|
+
<div class="card-body">
|
|
10
|
+
<div class="mb-3">
|
|
11
|
+
<label class="form-label">Groupes autorisés à déposer une demande (CSV)</label>
|
|
12
|
+
<input class="form-control" name="allowedGroups" placeholder="registered-users,membres" />
|
|
13
|
+
</div>
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
<div class="mb-3">
|
|
16
|
+
<label class="form-label">Groupes à notifier par email (CSV)</label>
|
|
17
|
+
<input class="form-control" name="notifyGroups" placeholder="administrators" />
|
|
18
|
+
</div>
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
<div class="row">
|
|
21
|
+
<div class="col-md-6 mb-3">
|
|
22
|
+
<label class="form-label">Durée de blocage en attente (minutes)</label>
|
|
23
|
+
<input class="form-control" name="pendingHoldMinutes" type="number" min="1" value="5" />
|
|
24
|
+
</div>
|
|
25
|
+
<div class="col-md-6 mb-3">
|
|
26
|
+
<label class="form-label">Fréquence de nettoyage (secondes)</label>
|
|
27
|
+
<input class="form-control" name="cleanupIntervalSeconds" type="number" min="10" value="60" />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="form-check">
|
|
32
|
+
<input class="form-check-input" type="checkbox" name="showUsernamesOnCalendar" id="showUsernamesOnCalendar" />
|
|
33
|
+
<label class="form-check-label" for="showUsernamesOnCalendar">Afficher les usernames sur le calendrier</label>
|
|
34
|
+
</div>
|
|
26
35
|
</div>
|
|
27
36
|
</div>
|
|
28
37
|
|
|
29
|
-
<
|
|
38
|
+
<div class="card mb-3">
|
|
39
|
+
<div class="card-header">HelloAsso</div>
|
|
40
|
+
<div class="card-body">
|
|
41
|
+
<div class="row">
|
|
42
|
+
<div class="col-md-4 mb-3">
|
|
43
|
+
<label class="form-label">Environnement</label>
|
|
44
|
+
<select class="form-select" name="helloassoEnv">
|
|
45
|
+
<option value="sandbox">Sandbox</option>
|
|
46
|
+
<option value="prod">Production</option>
|
|
47
|
+
</select>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="col-md-4 mb-3">
|
|
50
|
+
<label class="form-label">Client ID</label>
|
|
51
|
+
<input class="form-control" name="helloassoClientId" />
|
|
52
|
+
</div>
|
|
53
|
+
<div class="col-md-4 mb-3">
|
|
54
|
+
<label class="form-label">Client Secret</label>
|
|
55
|
+
<input class="form-control" name="helloassoClientSecret" type="password" />
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
30
58
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<input class="form-control" name="helloassoClientId" />
|
|
55
|
-
</div>
|
|
56
|
-
<div class="col-md-6">
|
|
57
|
-
<label class="form-label">Client Secret</label>
|
|
58
|
-
<input class="form-control" name="helloassoClientSecret" />
|
|
59
|
-
</div>
|
|
60
|
-
<div class="col-12">
|
|
61
|
-
<label class="form-label">Return URL (optionnel)</label>
|
|
62
|
-
<input class="form-control" name="helloassoReturnUrl" placeholder="https://www.onekite.com/calendar" />
|
|
59
|
+
<div class="row">
|
|
60
|
+
<div class="col-md-4 mb-3">
|
|
61
|
+
<label class="form-label">Organization Slug</label>
|
|
62
|
+
<input class="form-control" name="helloassoOrganizationSlug" />
|
|
63
|
+
</div>
|
|
64
|
+
<div class="col-md-4 mb-3">
|
|
65
|
+
<label class="form-label">Form Type</label>
|
|
66
|
+
<input class="form-control" name="helloassoFormType" placeholder="event, membership, crowdfunding..." />
|
|
67
|
+
</div>
|
|
68
|
+
<div class="col-md-4 mb-3">
|
|
69
|
+
<label class="form-label">Form Slug</label>
|
|
70
|
+
<input class="form-control" name="helloassoFormSlug" />
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<div class="mb-3">
|
|
75
|
+
<label class="form-label">Return URL (optionnel)</label>
|
|
76
|
+
<input class="form-control" name="helloassoReturnUrl" placeholder="https://www.onekite.com/calendar" />
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<div class="alert alert-info mb-0">
|
|
80
|
+
Les items du matériel sont récupérés depuis HelloAsso (items du formulaire).
|
|
81
|
+
</div>
|
|
63
82
|
</div>
|
|
64
83
|
</div>
|
|
65
84
|
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
</div>
|
|
85
|
+
<button class="btn btn-primary" type="submit">Enregistrer</button>
|
|
86
|
+
<span id="calendar-onekite-saved" class="badge text-bg-success ms-2 d-none">Enregistré</span>
|
|
87
|
+
</form>
|
|
70
88
|
|
|
71
|
-
|
|
72
|
-
<i class="fa fa-save"></i> Enregistrer
|
|
73
|
-
</button>
|
|
89
|
+
<hr class="my-4" />
|
|
74
90
|
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
<h4>Demandes en attente</h4>
|
|
92
|
+
<div id="calendar-onekite-pending-list" class="mt-3"></div>
|
|
93
|
+
</div>
|
|
77
94
|
|
|
78
|
-
|
|
79
|
-
<
|
|
80
|
-
|
|
95
|
+
<div class="col-lg-4">
|
|
96
|
+
<h4>Purge</h4>
|
|
97
|
+
<form id="calendar-onekite-purge" class="card">
|
|
98
|
+
<div class="card-body">
|
|
81
99
|
<label class="form-label">Année (YYYY)</label>
|
|
82
100
|
<input class="form-control" name="year" placeholder="2025" />
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<button class="btn btn-danger" type="submit"><i class="fa fa-trash"></i> Purger</button>
|
|
86
|
-
</div>
|
|
87
|
-
<div class="col-12">
|
|
88
|
-
<div class="form-text">Supprime toutes les réservations de l’année (ainsi que l’historique).</div>
|
|
101
|
+
<button class="btn btn-danger mt-3" type="submit">Purger</button>
|
|
102
|
+
<div id="calendar-onekite-purge-result" class="mt-3"></div>
|
|
89
103
|
</div>
|
|
90
104
|
</form>
|
|
91
|
-
<div class="mt-2" id="calendar-onekite-purge-result"></div>
|
|
92
|
-
</div>
|
|
93
|
-
|
|
94
|
-
<div class="col-lg-5">
|
|
95
|
-
<h2>Demandes en attente</h2>
|
|
96
|
-
<div class="alert alert-info">
|
|
97
|
-
Les demandes en attente expirent automatiquement après la durée définie.
|
|
98
|
-
</div>
|
|
99
|
-
|
|
100
|
-
<div id="calendar-onekite-pending-list"></div>
|
|
101
105
|
</div>
|
|
102
106
|
</div>
|
|
103
107
|
</div>
|
|
@@ -106,8 +110,8 @@
|
|
|
106
110
|
(function () {
|
|
107
111
|
function boot() {
|
|
108
112
|
if (!window.require) return setTimeout(boot, 50);
|
|
109
|
-
window.require(['admin/plugins/calendar-onekite'], function (
|
|
110
|
-
|
|
113
|
+
window.require(['admin/plugins/calendar-onekite'], function (mod) {
|
|
114
|
+
mod.init();
|
|
111
115
|
});
|
|
112
116
|
}
|
|
113
117
|
boot();
|