nodebb-plugin-onekite-calendar 2.0.85 → 2.0.87
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/lib/admin.js +3 -3
- package/lib/api.js +28 -9
- package/lib/db.js +24 -0
- package/package.json +1 -1
- package/public/admin.js +30 -1
- package/templates/admin/plugins/calendar-onekite.tpl +1 -1
package/lib/admin.js
CHANGED
|
@@ -367,9 +367,9 @@ admin.listGroups = async function (req, res) {
|
|
|
367
367
|
const Groups = require.main.require('./src/groups');
|
|
368
368
|
const q = String((req.query && req.query.q) || '').trim().toLowerCase();
|
|
369
369
|
const names = await Groups.getGroups('groups:createtime', 0, 500);
|
|
370
|
-
const filtered =
|
|
371
|
-
|
|
372
|
-
|
|
370
|
+
const filtered = (names || [])
|
|
371
|
+
.filter(n => n && !Groups.isPrivilegeGroup(n))
|
|
372
|
+
.filter(n => !q || String(n).toLowerCase().includes(q));
|
|
373
373
|
res.json(filtered.slice(0, 100));
|
|
374
374
|
} catch (e) {
|
|
375
375
|
res.json([]);
|
package/lib/api.js
CHANGED
|
@@ -1192,8 +1192,15 @@ api.getItems = async function (req, res) {
|
|
|
1192
1192
|
maint = new Set((ids || []).map(String));
|
|
1193
1193
|
} catch (e) {}
|
|
1194
1194
|
|
|
1195
|
+
const itemIds = normalized.map((it) => String(it.id));
|
|
1196
|
+
let locations = {};
|
|
1197
|
+
try {
|
|
1198
|
+
locations = await dbLayer.getMaintenanceLocations(itemIds);
|
|
1199
|
+
} catch (e) {}
|
|
1200
|
+
|
|
1195
1201
|
const out = normalized.map((it) => Object.assign({}, it, {
|
|
1196
1202
|
maintenance: maint.has(String(it.id)),
|
|
1203
|
+
location: locations[String(it.id)] || '',
|
|
1197
1204
|
}));
|
|
1198
1205
|
|
|
1199
1206
|
res.json(out);
|
|
@@ -1963,15 +1970,27 @@ api.setMaintenance = async function (req, res) {
|
|
|
1963
1970
|
if (!ok) return res.status(403).json({ error: 'not-allowed' });
|
|
1964
1971
|
const itemId = String(req.params.itemId || '').trim();
|
|
1965
1972
|
if (!itemId) return res.status(400).json({ error: 'missing-itemId' });
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1973
|
+
|
|
1974
|
+
const hasEnabled = req.body && 'enabled' in req.body;
|
|
1975
|
+
const hasLocation = req.body && 'location' in req.body;
|
|
1976
|
+
if (!hasEnabled && !hasLocation) return res.status(400).json({ error: 'missing-fields' });
|
|
1977
|
+
|
|
1978
|
+
if (hasLocation) {
|
|
1979
|
+
await dbLayer.setMaintenanceLocation(itemId, String(req.body.location || ''));
|
|
1980
|
+
}
|
|
1981
|
+
|
|
1982
|
+
if (hasEnabled) {
|
|
1983
|
+
const enabled = !!(req.body.enabled === true || req.body.enabled === '1' || req.body.enabled === 1);
|
|
1984
|
+
await dbLayer.setItemMaintenance(itemId, enabled);
|
|
1985
|
+
await auditLog(enabled ? 'maintenance_on' : 'maintenance_off', uid, {
|
|
1986
|
+
targetType: 'item',
|
|
1987
|
+
targetId: itemId,
|
|
1988
|
+
});
|
|
1989
|
+
// Maintenance impacts availability; ask clients to refetch.
|
|
1990
|
+
realtime.emitCalendarUpdated({ kind: 'maintenance', action: enabled ? 'on' : 'off', itemId });
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
return res.json({ ok: true, itemId });
|
|
1975
1994
|
};
|
|
1976
1995
|
|
|
1977
1996
|
// Bulk toggle: enable/disable maintenance for ALL catalog items.
|
package/lib/db.js
CHANGED
|
@@ -16,6 +16,7 @@ const KEY_OUTING_OBJ = (oid) => `calendar-onekite:outings:${oid}`;
|
|
|
16
16
|
|
|
17
17
|
// Maintenance (simple ON/OFF per item, no dates)
|
|
18
18
|
const KEY_MAINTENANCE_ZSET = 'calendar-onekite:maintenance:itemIds';
|
|
19
|
+
const KEY_MAINTENANCE_META = (itemId) => `calendar-onekite:maintenance:meta:${itemId}`;
|
|
19
20
|
|
|
20
21
|
// Audit log (partitioned by year)
|
|
21
22
|
const KEY_AUDIT_ZSET = (year) => `calendar-onekite:audit:${year}`;
|
|
@@ -103,6 +104,27 @@ async function setItemMaintenance(itemId, enabled) {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
|
|
107
|
+
async function getMaintenanceLocations(itemIds) {
|
|
108
|
+
if (!Array.isArray(itemIds) || !itemIds.length) return {};
|
|
109
|
+
const keys = itemIds.map((id) => KEY_MAINTENANCE_META(String(id)));
|
|
110
|
+
let metas = [];
|
|
111
|
+
try {
|
|
112
|
+
metas = await db.getObjects(keys);
|
|
113
|
+
} catch (e) {}
|
|
114
|
+
const result = {};
|
|
115
|
+
itemIds.forEach((id, i) => {
|
|
116
|
+
const meta = metas && metas[i];
|
|
117
|
+
result[String(id)] = (meta && meta.location) ? String(meta.location) : '';
|
|
118
|
+
});
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function setMaintenanceLocation(itemId, location) {
|
|
123
|
+
const id = String(itemId || '').trim();
|
|
124
|
+
if (!id) return;
|
|
125
|
+
await db.setObjectField(KEY_MAINTENANCE_META(id), 'location', String(location || '').trim());
|
|
126
|
+
}
|
|
127
|
+
|
|
106
128
|
async function setAllMaintenance(enabled, itemIds) {
|
|
107
129
|
// Clear set first (fast)
|
|
108
130
|
await db.delete(KEY_MAINTENANCE_ZSET);
|
|
@@ -242,6 +264,8 @@ module.exports = {
|
|
|
242
264
|
isItemInMaintenance,
|
|
243
265
|
setItemMaintenance,
|
|
244
266
|
setAllMaintenance,
|
|
267
|
+
getMaintenanceLocations,
|
|
268
|
+
setMaintenanceLocation,
|
|
245
269
|
|
|
246
270
|
// Audit
|
|
247
271
|
addAuditEntry,
|
package/package.json
CHANGED
package/public/admin.js
CHANGED
|
@@ -1518,15 +1518,17 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
1518
1518
|
const id = String(it.id);
|
|
1519
1519
|
const name = String(it.name || '').replace(/</g, '<').replace(/>/g, '>');
|
|
1520
1520
|
const checked = it.maintenance ? 'checked' : '';
|
|
1521
|
+
const location = String(it.location || '').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
1521
1522
|
return `<tr data-itemid="${id}">
|
|
1522
1523
|
<td>${name}</td>
|
|
1524
|
+
<td><input type="text" class="form-control form-control-sm onekite-maint-location" value="${location}" placeholder="Emplacement..." style="min-width:180px;"></td>
|
|
1523
1525
|
<td>
|
|
1524
1526
|
<div class="form-check form-switch">
|
|
1525
1527
|
<input class="form-check-input onekite-maint-toggle" type="checkbox" ${checked} />
|
|
1526
1528
|
</div>
|
|
1527
1529
|
</td>
|
|
1528
1530
|
</tr>`;
|
|
1529
|
-
}).join('') || '<tr><td colspan="
|
|
1531
|
+
}).join('') || '<tr><td colspan="3" class="text-muted">Aucun matériel.</td></tr>';
|
|
1530
1532
|
}
|
|
1531
1533
|
|
|
1532
1534
|
async function refreshMaintenance() {
|
|
@@ -1585,6 +1587,33 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
1585
1587
|
showAlert('error', 'Impossible de modifier la maintenance.');
|
|
1586
1588
|
}
|
|
1587
1589
|
});
|
|
1590
|
+
|
|
1591
|
+
maintTableBody.addEventListener('input', (ev) => {
|
|
1592
|
+
const el = ev && ev.target;
|
|
1593
|
+
if (!el || !el.classList || !el.classList.contains('onekite-maint-location')) return;
|
|
1594
|
+
const tr = el.closest('tr');
|
|
1595
|
+
const itemId = tr ? tr.getAttribute('data-itemid') : '';
|
|
1596
|
+
if (!itemId) return;
|
|
1597
|
+
// Keep cache in sync so re-renders preserve typed value
|
|
1598
|
+
maintItemsCache = maintItemsCache.map((it) => (String(it.id) === String(itemId) ? Object.assign({}, it, { location: el.value }) : it));
|
|
1599
|
+
});
|
|
1600
|
+
|
|
1601
|
+
maintTableBody.addEventListener('focusout', async (ev) => {
|
|
1602
|
+
const el = ev && ev.target;
|
|
1603
|
+
if (!el || !el.classList || !el.classList.contains('onekite-maint-location')) return;
|
|
1604
|
+
const tr = el.closest('tr');
|
|
1605
|
+
const itemId = tr ? tr.getAttribute('data-itemid') : '';
|
|
1606
|
+
if (!itemId) return;
|
|
1607
|
+
const location = String(el.value || '');
|
|
1608
|
+
try {
|
|
1609
|
+
await fetchJson(`/api/v3/plugins/calendar-onekite/maintenance/${encodeURIComponent(String(itemId))}`, {
|
|
1610
|
+
method: 'PUT',
|
|
1611
|
+
body: JSON.stringify({ location }),
|
|
1612
|
+
});
|
|
1613
|
+
} catch (e) {
|
|
1614
|
+
showAlert('error', 'Impossible de sauvegarder l\'emplacement.');
|
|
1615
|
+
}
|
|
1616
|
+
});
|
|
1588
1617
|
}
|
|
1589
1618
|
|
|
1590
1619
|
// Load once
|
|
@@ -314,7 +314,7 @@
|
|
|
314
314
|
<div class="table-responsive">
|
|
315
315
|
<table class="table table-sm" id="onekite-maint-table">
|
|
316
316
|
<thead>
|
|
317
|
-
<tr><th>Matériel</th><th style="width: 140px;">Maintenance</th></tr>
|
|
317
|
+
<tr><th>Matériel</th><th>Emplacement</th><th style="width: 140px;">Maintenance</th></tr>
|
|
318
318
|
</thead>
|
|
319
319
|
<tbody></tbody>
|
|
320
320
|
</table>
|