assets/js/imports.js
/* ==========================================================================
Import providers
========================================================================== */
/*
|--------------------------------------------------------------------------
| Shared import modal
|--------------------------------------------------------------------------
|
| The dashboard uses one import modal for all providers. Provider-specific
| panels are switched from data-import-provider so future importers can be
| added without duplicating modal logic.
|
*/
(() => {
const availableProviders = new Set([
'matomo_api',
'matomo_db',
]);
function importText(message) {
return {
error: message?.dataset.error ?? 'Unable to import data.',
importing: message?.dataset.importing ?? 'Importing data...',
modeApi: message?.dataset.modeApi ?? 'API',
modeDatabase: message?.dataset.modeDatabase ?? 'Database',
networkError: message?.dataset.networkError ?? 'Network error.',
providerUnavailable: message?.dataset.providerUnavailable ?? 'This platform is not available yet.',
testing: message?.dataset.testing ?? 'Testing connection...',
};
}
function importFormToObject(form) {
const data = new FormData(form);
const result = {};
for (const [name, value] of data.entries()) {
result[name] = value;
}
form.querySelectorAll('input[type="checkbox"]').forEach((input) => {
result[input.name] = input.checked;
});
return result;
}
function providerLabels(message) {
const text = importText(message);
return {
adobe_analytics: 'Adobe Analytics',
google_analytics: 'Google Analytics',
matomo_api: `Matomo ${text.modeApi}`,
matomo_db: `Matomo ${text.modeDatabase}`,
plausible: 'Plausible',
umami: 'Umami',
};
}
function setButtonsDisabled(form, disabled) {
form.querySelectorAll('[data-import-action-button]').forEach((button) => {
button.disabled = disabled;
});
}
function setMessage(message, text, status = '') {
if (!message) {
return;
}
message.className = status;
message.textContent = text || '';
}
function setProviderInputsState(form, provider) {
form.querySelectorAll('[data-import-provider-input]').forEach((input) => {
input.disabled = input.dataset.importProviderInput !== provider;
});
}
function setProvider(provider, form = document.getElementById('import-form')) {
if (!form) {
return;
}
const selectedProvider = provider || 'matomo_api';
const hiddenProvider = form.querySelector('input[name="provider"]');
const label = form.closest('dialog')?.querySelector('[data-import-provider-label]');
const message = form.querySelector('#import-message');
const text = importText(message);
const labels = providerLabels(message);
const isAvailable = availableProviders.has(selectedProvider);
if (hiddenProvider) {
hiddenProvider.value = selectedProvider;
}
if (label) {
label.textContent = labels[selectedProvider] ?? selectedProvider;
}
form.querySelectorAll('[data-import-provider-panel]').forEach((panel) => {
panel.hidden = panel.dataset.importProviderPanel !== selectedProvider;
});
form.querySelectorAll('[data-import-shared-panel]').forEach((panel) => {
panel.hidden = !isAvailable;
});
form.querySelectorAll('[data-import-action-button]').forEach((button) => {
button.hidden = !isAvailable;
});
setProviderInputsState(form, selectedProvider);
setMessage(message, isAvailable ? '' : text.providerUnavailable, isAvailable ? '' : 'info');
}
window.brivaciaSetImportProvider = setProvider;
const modal = document.getElementById('import-modal');
if (modal?.dataset.importProvider) {
setProvider(modal.dataset.importProvider);
}
document.addEventListener('change', (event) => {
const toggle = event.target.closest('[data-import-domain-toggle]');
if (!toggle) {
return;
}
const panel = toggle.closest('[data-import-provider-panel]');
const field = panel?.querySelector('[data-import-domain-field]');
if (field) {
field.hidden = !toggle.checked;
}
});
document.addEventListener('click', (event) => {
const button = event.target.closest('#import-form button[value="cancel"]');
if (!button) {
return;
}
button.closest('dialog')?.close();
});
document.addEventListener('click', (event) => {
const button = event.target.closest('[data-token-toggle]');
if (!button) {
return;
}
const input = button.previousElementSibling;
if (!(input instanceof HTMLInputElement)) {
return;
}
input.type = input.type === 'password' ? 'text' : 'password';
});
document.addEventListener('submit', async (event) => {
const form = event.target.closest('#import-form');
if (!form) {
return;
}
event.preventDefault();
const provider = form.querySelector('input[name="provider"]')?.value || '';
const message = form.querySelector('#import-message');
const text = importText(message);
if (!availableProviders.has(provider)) {
setMessage(message, text.providerUnavailable, 'info');
return;
}
const submitter = event.submitter;
const action = submitter?.value === 'test' ? 'test' : 'import';
setMessage(message, action === 'test' ? text.testing : text.importing);
setButtonsDisabled(form, true);
try {
const response = await fetch(`/api/import.php?action=${action}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(importFormToObject(form)),
});
const data = await response.json();
if (!response.ok || !data.ok) {
setMessage(message, data.error || text.error, 'danger');
return;
}
setMessage(message, data.message || '', 'success');
if (action === 'import') {
setTimeout(() => {
form.closest('dialog')?.close();
window.location.reload();
}, 1200);
}
} catch {
setMessage(message, text.networkError, 'danger');
} finally {
setButtonsDisabled(form, false);
}
});
})();