feat(ucp): v2.6.0 provisionnement XML Acrobits GroundWire par poste

This commit is contained in:
sorcier committed 2026-11-12 02:04:47 +01:00
1 parent 135a6267db
commit 28efb2d6bc
10 files changed
+359 -30

No files matched your search

+8 -4
View File
@@ -311,6 +311,7 @@ try {
$voicemail_attach = isset($payload['voicemail_attach']) ? (int)!empty($payload['voicemail_attach']) : 1;
$voicemail_delete = isset($payload['voicemail_delete']) ? (int)!empty($payload['voicemail_delete']) : 0;
$ring_time = max(5, min(120, (int)($payload['ring_time'] ?? 20)));
$groundwire_enabled = !empty($payload['groundwire_enabled']) ? 1 : 0;
if ($force_pin_change === 1) {
$secFile = "/var/spool/asterisk/voicemail/default/{$extension}/secret.conf";
@@ -339,7 +340,7 @@ try {
encryption = :encryption, codecs = :codecs, max_contacts = :max_contacts, enabled = :enabled,
voicemail_enabled = :vme, voicemail_pin = :vmp, force_pin_change = :fpc,
voicemail_skip_pin = :vsp, voicemail_email = :vme_mail, voicemail_attach = :vma,
voicemail_delete = :vmd, ring_time = :rt
voicemail_delete = :vmd, ring_time = :rt, groundwire_enabled = :gwe
WHERE id = :id
');
$stmt->execute([
@@ -360,14 +361,15 @@ try {
':vma' => $voicemail_attach,
':vmd' => $voicemail_delete,
':rt' => $ring_time,
':gwe' => $groundwire_enabled,
]);
} else {
$stmt = $db->prepare('
INSERT INTO extensions (extension, name, secret, transport, encryption, codecs, max_contacts, enabled,
voicemail_enabled, voicemail_pin, force_pin_change, voicemail_skip_pin,
voicemail_email, voicemail_attach, voicemail_delete, ring_time)
voicemail_email, voicemail_attach, voicemail_delete, ring_time, groundwire_enabled)
VALUES (:ext, :name, :secret, :transport, :encryption, :codecs, :max_contacts, :enabled,
:vme, :vmp, :fpc, :vsp, :vme_mail, :vma, :vmd, :rt)
:vme, :vmp, :fpc, :vsp, :vme_mail, :vma, :vmd, :rt, :gwe)
ON CONFLICT(extension) DO UPDATE SET
name = excluded.name,
secret = excluded.secret,
@@ -383,7 +385,8 @@ try {
voicemail_email = excluded.voicemail_email,
voicemail_attach = excluded.voicemail_attach,
voicemail_delete = excluded.voicemail_delete,
ring_time = excluded.ring_time
ring_time = excluded.ring_time,
groundwire_enabled = excluded.groundwire_enabled
');
$stmt->execute([
':ext' => $extension,
@@ -402,6 +405,7 @@ try {
':vma' => $voicemail_attach,
':vmd' => $voicemail_delete,
':rt' => $ring_time,
':gwe' => $groundwire_enabled,
]);
}
+9 -1
View File
@@ -937,14 +937,18 @@ function renderExtensionsTable() {
const vmBadge = Number(ext.voicemail_enabled) === 1
? `<span class="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold bg-amber-500/15 text-amber-300 border border-amber-500/30" title="Boîte vocale active (${ext.ring_time || 20}s)">📟 Boîte</span>`
: '';
const gwBadge = Number(ext.groundwire_enabled) === 1
? `<span class="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold bg-cyan-500/15 text-cyan-300 border border-cyan-500/30" title="Provisionnement XML GroundWire activé dans l'UCP">📱 GroundWire</span>`
: '';
return `
<tr class="hover:bg-anthracite-750/60 transition">
<td class="py-3.5 px-4 font-mono font-bold text-indigo-300">${escapeHtml(ext.extension)}</td>
<td class="py-3.5 px-4 font-medium text-white">
<div class="flex items-center gap-2">
<div class="flex items-center gap-2 flex-wrap">
<span>${escapeHtml(ext.name)}</span>
${vmBadge}
${gwBadge}
</div>
</td>
<td class="py-3.5 px-4"><div class="flex flex-wrap gap-1">${groupBadges}</div></td>
@@ -1027,6 +1031,9 @@ function openExtensionModal(ext = null) {
});
syncEncryptionToggle(transport, ext ? (ext.encryption ?? (transport === 'tls' ? 1 : 0)) : (transport === 'tls' ? 1 : 0));
const gwCheckbox = document.getElementById('ext-groundwire-enabled');
if (gwCheckbox) gwCheckbox.checked = ext ? (Number(ext.groundwire_enabled) === 1) : false;
// Réinitialisation de l'onglet actif vers "Général"
switchExtModalTab('general');
@@ -3829,6 +3836,7 @@ document.addEventListener('DOMContentLoaded', () => {
payload.voicemail_attach = document.getElementById('ext-vm-attach')?.checked ? 1 : 0;
payload.voicemail_delete = document.getElementById('ext-vm-delete')?.checked ? 1 : 0;
payload.ring_time = Number(payload.ring_time || 20);
payload.groundwire_enabled = document.getElementById('ext-groundwire-enabled')?.checked ? 1 : 0;
try {
const res = await apiCall('save_extension', payload);
+14
View File
@@ -3263,6 +3263,20 @@ $isDevEnv = file_exists(__DIR__ . '/../.dev')
<p class="text-[11px] text-slate-400">Le mode optionnel négocie le SRTP automatiquement tout en évitant les échecs d'appels si le poste IP a le SRTP désactivé.</p>
</div>
<label class="flex items-start gap-3 p-3.5 rounded-xl bg-anthracite-950 border border-anthracite-700 hover:border-cyan-500/50 cursor-pointer transition">
<input type="checkbox" name="groundwire_enabled" id="ext-groundwire-enabled" value="1"
class="mt-0.5 rounded bg-anthracite-900 border-anthracite-600 text-cyan-500 focus:ring-cyan-500">
<div class="leading-snug">
<div class="text-xs font-bold text-white flex items-center gap-2">
<span>📱 GroundWire XML</span>
<span class="px-1.5 py-0.5 rounded text-[10px] font-semibold bg-cyan-500/15 text-cyan-300 border border-cyan-500/30">Softphone Mobile UCP</span>
</div>
<div class="text-[11px] text-slate-400 mt-0.5">
Affiche les boutons d'auto-configuration Acrobits GroundWire (lien direct mobile + téléchargement XML) sur ce poste dans l'UCP.
</div>
</div>
</label>
<div class="p-3.5 rounded-xl bg-anthracite-950 border border-anthracite-700 space-y-2">
<div class="flex items-center justify-between">
<span class="text-xs font-bold text-cyan-300">Appartenance aux Groupes d'Extensions (Sites & Droits)</span>