Zammad-asetukset API-välilehdelle, integraatio-checkboxit erilliseksi kortiksi, korjaa tyyppi puuttuu -virhe

- Integraatiot erillinen table-card yrityksen asetuksissa (vain superadmin)
- Zammad-konfiguraatio (URL, token, ryhmät, synkronointi) siirretty API-tabiin
- Saatavuus-API, Telegram ja Zammad kortit näkyvät API-tabissa kun integraatio on enabloitu
- Korjattu integration_save ja integration_test: puuttuva $input json_decode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 20:00:36 +02:00
parent 648cb949ac
commit 4a46ce56f3
3 changed files with 61 additions and 43 deletions

View File

@@ -4987,6 +4987,7 @@ switch ($action) {
case 'integration_save': case 'integration_save':
requireCompany(); requireCompany();
$input = json_decode(file_get_contents('php://input'), true);
$type = $input['type'] ?? ''; $type = $input['type'] ?? '';
$enabled = (bool)($input['enabled'] ?? false); $enabled = (bool)($input['enabled'] ?? false);
$config = $input['config'] ?? []; $config = $input['config'] ?? [];
@@ -5006,6 +5007,7 @@ switch ($action) {
case 'integration_test': case 'integration_test':
requireCompany(); requireCompany();
$input = json_decode(file_get_contents('php://input'), true);
$type = $input['type'] ?? $_GET['type'] ?? ''; $type = $input['type'] ?? $_GET['type'] ?? '';
$integ = dbGetIntegration($companyId, $type); $integ = dbGetIntegration($companyId, $type);
if (!$integ) { http_response_code(404); echo json_encode(['error' => 'Integraatiota ei löydy']); break; } if (!$integ) { http_response_code(404); echo json_encode(['error' => 'Integraatiota ei löydy']); break; }

View File

@@ -1535,6 +1535,32 @@
<button class="btn-secondary" id="btn-test-telegram">Testaa</button> <button class="btn-secondary" id="btn-test-telegram">Testaa</button>
</div> </div>
</div> </div>
<!-- Zammad-asetukset -->
<div class="table-card" id="settings-zammad-card" style="padding:1.5rem;margin-top:1rem;display:none;">
<h3 style="color:#0f3460;margin-bottom:0.5rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">📧 Zammad (O365-sähköposti)</h3>
<p style="color:#666;font-size:0.85rem;margin-bottom:1rem;">Synkronoi tiketit Zammad-helpdeskistä. Yhdistää O365-sähköpostit tikettijärjestelmään.</p>
<div class="form-grid" style="max-width:500px;">
<div class="form-group full-width">
<label>Zammad URL</label>
<input type="text" id="company-zammad-url" placeholder="https://desk.yritys.fi" style="font-family:monospace;">
</div>
<div class="form-group full-width">
<label>API Token</label>
<input type="password" id="company-zammad-token" placeholder="Token..." style="font-family:monospace;">
</div>
<div class="form-group full-width">
<label>Synkronoitavat ryhmät</label>
<div id="company-zammad-groups" style="color:#888;font-size:0.85rem;">Tallenna ensin, sitten valitse ryhmät.</div>
</div>
<div class="form-group full-width" style="display:flex;gap:0.5rem;flex-wrap:wrap;">
<button type="button" class="btn-secondary" id="btn-company-zammad-groups">Lataa ryhmät</button>
<button type="button" class="btn-secondary" id="btn-company-zammad-test">Testaa yhteys</button>
<button type="button" class="btn-primary" id="btn-company-zammad-sync" style="background:#28a745;">▶ Synkronoi</button>
</div>
</div>
<div id="company-zammad-result" style="margin-top:0.75rem;display:none;padding:0.75rem;border-radius:8px;font-size:0.85rem;"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -1640,11 +1666,18 @@
</label> </label>
</div> </div>
</div> </div>
<div id="company-allowed-ips-section" class="form-group" style="margin-top:1rem;display:none;">
<label style="font-weight:600;font-size:0.9rem;">Sallitut IP-osoitteet</label>
<textarea id="company-edit-allowed-ips" rows="3" style="font-family:monospace;font-size:0.85rem;" placeholder="192.168.1.100&#10;10.0.0.0/8"></textarea>
<small style="color:#888;">Yksi IP tai CIDR per rivi. "kaikki" = ei rajoitusta.</small>
</div>
<button class="btn-primary" id="btn-save-company-settings" style="font-size:0.85rem;">Tallenna asetukset</button>
</div>
<!-- Integraatiot (vain superadmin) --> <!-- Integraatiot (vain superadmin) -->
<div id="company-integrations-section" style="margin-bottom:1.5rem;display:none;"> <div id="company-integrations-section" class="table-card" style="padding:1.5rem;margin-top:1rem;display:none;">
<h4 style="color:#0f3460;margin-bottom:0.5rem;font-size:0.95rem;">Integraatiot</h4> <h3 style="color:#0f3460;margin-bottom:0.5rem;border-bottom:2px solid #f0f2f5;padding-bottom:0.5rem;">Integraatiot</h3>
<p style="color:#888;font-size:0.82rem;margin-bottom:0.75rem;">Ota käyttöön ulkoiset integraatiot tälle yritykselle.</p> <p style="color:#888;font-size:0.85rem;margin-bottom:1rem;">Ota käyttöön ulkoiset integraatiot tälle yritykselle.</p>
<div id="integrations-checkboxes" style="display:flex;flex-direction:column;gap:0.4rem;"> <div id="integrations-checkboxes" style="display:flex;flex-direction:column;gap:0.5rem;margin-bottom:1rem;">
<label style="display:flex;align-items:center;gap:0.5rem;font-size:0.9rem;cursor:pointer;"> <label style="display:flex;align-items:center;gap:0.5rem;font-size:0.9rem;cursor:pointer;">
<input type="checkbox" data-integration="zammad"> 📧 Zammad (O365-sähköposti) <input type="checkbox" data-integration="zammad"> 📧 Zammad (O365-sähköposti)
</label> </label>
@@ -1656,37 +1689,6 @@
</label> </label>
</div> </div>
</div> </div>
<!-- Zammad-asetukset (näkyy kun Zammad on valittu) -->
<div id="company-zammad-config" style="display:none;margin-bottom:1.5rem;padding:1rem;background:#f8f9fb;border-radius:10px;border-left:3px solid var(--primary-color);">
<h4 style="color:#0f3460;margin-bottom:0.5rem;font-size:0.95rem;">📧 Zammad-asetukset</h4>
<div class="form-grid" style="max-width:500px;">
<div class="form-group full-width">
<label>Zammad URL</label>
<input type="text" id="company-zammad-url" placeholder="https://desk.yritys.fi" style="font-family:monospace;">
</div>
<div class="form-group full-width">
<label>API Token</label>
<input type="password" id="company-zammad-token" placeholder="Token..." style="font-family:monospace;">
</div>
<div class="form-group full-width">
<label>Synkronoitavat ryhmät</label>
<div id="company-zammad-groups" style="color:#888;font-size:0.85rem;">Tallenna ensin, sitten valitse ryhmät.</div>
</div>
<div class="form-group full-width" style="display:flex;gap:0.5rem;flex-wrap:wrap;">
<button type="button" class="btn-secondary" id="btn-company-zammad-groups">Lataa ryhmät</button>
<button type="button" class="btn-secondary" id="btn-company-zammad-test">Testaa yhteys</button>
<button type="button" class="btn-primary" id="btn-company-zammad-sync" style="background:#28a745;">▶ Synkronoi</button>
</div>
</div>
<div id="company-zammad-result" style="margin-top:0.75rem;display:none;padding:0.75rem;border-radius:8px;font-size:0.85rem;"></div>
</div>
<div id="company-allowed-ips-section" class="form-group" style="margin-top:1rem;display:none;">
<label style="font-weight:600;font-size:0.9rem;">Sallitut IP-osoitteet</label>
<textarea id="company-edit-allowed-ips" rows="3" style="font-family:monospace;font-size:0.85rem;" placeholder="192.168.1.100&#10;10.0.0.0/8"></textarea>
<small style="color:#888;">Yksi IP tai CIDR per rivi. "kaikki" = ei rajoitusta.</small>
</div>
<button class="btn-primary" id="btn-save-company-settings" style="font-size:0.85rem;">Tallenna asetukset</button>
</div>
<!-- Postilaatikot --> <!-- Postilaatikot -->
<div class="table-card" style="padding:1.5rem;margin-top:1rem;"> <div class="table-card" style="padding:1.5rem;margin-top:1rem;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:1rem;">

View File

@@ -2366,10 +2366,25 @@ async function loadSettings() {
const integs = await apiCall('integrations'); const integs = await apiCall('integrations');
const saatavuusEnabled = integs.find(i => i.type === 'saatavuus_api')?.enabled; const saatavuusEnabled = integs.find(i => i.type === 'saatavuus_api')?.enabled;
const telegramEnabled = integs.find(i => i.type === 'telegram')?.enabled; const telegramEnabled = integs.find(i => i.type === 'telegram')?.enabled;
const zammadInteg = integs.find(i => i.type === 'zammad');
const zammadEnabled = zammadInteg?.enabled;
const saatCard = document.getElementById('settings-saatavuus-api-card'); const saatCard = document.getElementById('settings-saatavuus-api-card');
const teleCard = document.getElementById('settings-telegram-card'); const teleCard = document.getElementById('settings-telegram-card');
const zammadCard = document.getElementById('settings-zammad-card');
if (saatCard) saatCard.style.display = saatavuusEnabled ? '' : 'none'; if (saatCard) saatCard.style.display = saatavuusEnabled ? '' : 'none';
if (teleCard) teleCard.style.display = telegramEnabled ? '' : 'none'; if (teleCard) teleCard.style.display = telegramEnabled ? '' : 'none';
if (zammadCard) zammadCard.style.display = zammadEnabled ? '' : 'none';
// Lataa Zammad-asetukset korttiin
if (zammadEnabled && zammadInteg?.config) {
document.getElementById('company-zammad-url').value = zammadInteg.config.url || '';
document.getElementById('company-zammad-token').value = zammadInteg.config.token || '';
if (zammadInteg.config.group_ids && zammadInteg.config.group_names) {
renderCompanyZammadGroups(
zammadInteg.config.group_names.map((name, i) => ({ id: zammadInteg.config.group_ids[i], name })),
zammadInteg.config.group_ids
);
}
}
} catch (e) { console.error(e); } } catch (e) { console.error(e); }
// Vastauspohjat // Vastauspohjat
@@ -2572,11 +2587,9 @@ async function showCompanyDetail(id) {
const isSA = currentUser?.role === 'superadmin'; const isSA = currentUser?.role === 'superadmin';
const modulesSection = document.getElementById('company-modules-section'); const modulesSection = document.getElementById('company-modules-section');
const integrationsSection = document.getElementById('company-integrations-section'); const integrationsSection = document.getElementById('company-integrations-section');
const zammadConfig = document.getElementById('company-zammad-config');
const ipsSection = document.getElementById('company-allowed-ips-section'); const ipsSection = document.getElementById('company-allowed-ips-section');
if (modulesSection) modulesSection.style.display = isSA ? '' : 'none'; if (modulesSection) modulesSection.style.display = isSA ? '' : 'none';
if (integrationsSection) integrationsSection.style.display = isSA ? '' : 'none'; if (integrationsSection) integrationsSection.style.display = isSA ? '' : 'none';
if (!isSA && zammadConfig) zammadConfig.style.display = 'none';
if (ipsSection) ipsSection.style.display = isSA ? '' : 'none'; if (ipsSection) ipsSection.style.display = isSA ? '' : 'none';
// Moduuli-checkboxit (yhteensopivuus: vanha 'devices' → 'tekniikka') // Moduuli-checkboxit (yhteensopivuus: vanha 'devices' → 'tekniikka')
@@ -2641,7 +2654,8 @@ async function loadCompanyIntegrations() {
} }
function toggleCompanyZammadConfig(show) { function toggleCompanyZammadConfig(show) {
const card = document.getElementById('company-zammad-config'); // Zammad-kortti on nyt API-tabissa
const card = document.getElementById('settings-zammad-card');
if (card) card.style.display = show ? '' : 'none'; if (card) card.style.display = show ? '' : 'none';
} }