Files
WLTBAgent 0bf1e53f65 Phase 4: Complete admin UI with TemplateResponse and configuration forms
- PageController: Replaced simple HTML with proper TemplateResponse
  - Added index() method with full admin interface
  - Added save() method for POST /save
  - Added load() method for GET /load
  - Injected IConfig service for configuration storage
  - Added validation for required fields
  - Proper error handling with JSONResponse

- Admin template: Full Nextcloud-compatible admin interface
  - Google Analytics configuration section (client ID, secret, refresh token)
  - Anthropic Claude API configuration section (API key)
  - Configuration status display (success/warning states)
  - Form with proper Nextcloud components
  - CSRF token handling

- Routes: Added /save and /load endpoints
  - page#index (GET) - renders admin page
  - page#save (POST) - saves configuration
  - page#load (GET) - loads configuration

- Application.php: Updated with APP_VERSION constant
  - Proper style and script loading

- CSS: Complete styling for admin interface
  - Responsive design with Nextcloud theme colors
  - Form input styling with focus states
  - Action buttons with hover effects

- JavaScript: Complete form handling
  - AJAX submission to /save endpoint
  - Configuration loading from /load endpoint
  - CSRF token handling with OC.requestToken
  - OC.Notification integration for success/error messages
  - Real-time status updates

This is a complete, working admin interface for configuration.
Users can now save/load Google Analytics and Claude API credentials through the UI.
2026-02-13 22:49:20 +00:00

138 lines
4.8 KiB
JavaScript

(function() {
'use strict';
const saveButton = document.getElementById('analytics-hub-save');
const cancelButton = document.getElementById('analytics-hub-cancel');
const form = document.getElementById('analytics-hub-form');
if (saveButton) {
saveButton.addEventListener('click', function(e) {
e.preventDefault();
saveConfiguration();
});
}
if (cancelButton) {
cancelButton.addEventListener('click', function(e) {
e.preventDefault();
loadConfiguration();
});
}
function saveConfiguration() {
// Get form data
const formData = new FormData(form);
const data = {
google_client_id: document.getElementById('google_client_id').value,
google_client_secret: document.getElementById('google_client_secret').value,
google_refresh_token: document.getElementById('google_refresh_token').value,
anthropic_api_key: document.getElementById('anthropic_api_key').value
};
// Validate required fields
if (!data.google_client_id) {
showNotification('Error', 'Google Client ID is required');
return;
}
if (!data.google_client_secret) {
showNotification('Error', 'Google Client Secret is required');
return;
}
if (!data.anthropic_api_key) {
showNotification('Error', 'Anthropic API Key is required');
return;
}
// Send save request
saveButton.textContent = 'Saving...';
saveButton.disabled = true;
const url = OC.generateUrl('/apps/analyticshub/admin/save');
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'requesttoken': OC.requestToken
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('Success', 'Configuration saved successfully');
if (data.data && data.data.is_configured) {
updateStatus(true);
}
} else {
showNotification('Error', data.error || 'Failed to save configuration');
}
})
.catch(error => {
showNotification('Error', 'Failed to save configuration: ' + error.message);
})
.finally(() => {
saveButton.textContent = 'Save Configuration';
saveButton.disabled = false;
});
}
function loadConfiguration() {
const url = OC.generateUrl('/apps/analyticshub/admin/load');
fetch(url, {
method: 'GET',
headers: {
'requesttoken': OC.requestToken
}
})
.then(response => response.json())
.then(data => {
if (data.success && data.data) {
document.getElementById('google_client_id').value = data.data.google_client_id || '';
document.getElementById('google_client_secret').value = '';
document.getElementById('google_refresh_token').value = '';
document.getElementById('anthropic_api_key').value = '';
updateStatus(!!data.data.is_configured);
showNotification('Success', 'Configuration loaded');
} else {
showNotification('Error', data.error || 'Failed to load configuration');
}
})
.catch(error => {
showNotification('Error', 'Failed to load configuration: ' + error.message);
});
}
function updateStatus(isConfigured) {
const statusDiv = document.querySelector('.analytics-hub-settings__status');
if (!statusDiv) return;
const statusMessage = isConfigured ? '✅ Configured' : '❌ Not configured';
// Update status indicators in the status section
const statusElements = statusDiv.querySelectorAll('p strong');
statusElements.forEach(el => {
const text = el.textContent;
if (text.includes('Google Client ID')) {
el.parentElement.innerHTML = '<strong>Google Client ID:</strong> ' + statusMessage;
}
if (text.includes('Anthropic API Key')) {
el.parentElement.innerHTML = '<strong>Anthropic API Key:</strong> ' + statusMessage;
}
});
}
function showNotification(title, message) {
// Try Nextcloud's notification system first
if (typeof OC !== 'undefined' && OC.Notification) {
OC.Notification.showTemporary(t('analyticshub', title) + ': ' + message);
} else {
// Fallback to alert
alert(title + ': ' + message);
}
}
})();