fix
This commit is contained in:
@@ -16,6 +16,9 @@ from igny8_core.business.integration.services.integration_service import Integra
|
|||||||
from igny8_core.business.integration.services.sync_service import SyncService
|
from igny8_core.business.integration.services.sync_service import SyncService
|
||||||
from igny8_core.business.integration.services.sync_health_service import SyncHealthService
|
from igny8_core.business.integration.services.sync_health_service import SyncHealthService
|
||||||
from igny8_core.business.integration.services.content_sync_service import ContentSyncService
|
from igny8_core.business.integration.services.content_sync_service import ContentSyncService
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class IntegrationViewSet(SiteSectorModelViewSet):
|
class IntegrationViewSet(SiteSectorModelViewSet):
|
||||||
@@ -186,15 +189,21 @@ class IntegrationViewSet(SiteSectorModelViewSet):
|
|||||||
# Try to find an existing integration for this site+platform
|
# Try to find an existing integration for this site+platform
|
||||||
integration = SiteIntegration.objects.filter(site=site, platform='wordpress').first()
|
integration = SiteIntegration.objects.filter(site=site, platform='wordpress').first()
|
||||||
|
|
||||||
# If not found, create a temporary in-memory integration object
|
# If not found, create and save the integration to database
|
||||||
|
integration_created = False
|
||||||
if not integration:
|
if not integration:
|
||||||
integration = SiteIntegration(
|
integration = SiteIntegration.objects.create(
|
||||||
|
account=site.account,
|
||||||
site=site,
|
site=site,
|
||||||
platform='wordpress',
|
platform='wordpress',
|
||||||
|
platform_type='cms',
|
||||||
config_json={'site_url': site_url} if site_url else {},
|
config_json={'site_url': site_url} if site_url else {},
|
||||||
credentials_json={'api_key': api_key} if api_key else {},
|
credentials_json={'api_key': api_key} if api_key else {},
|
||||||
is_active=False
|
is_active=True,
|
||||||
|
sync_enabled=True
|
||||||
)
|
)
|
||||||
|
integration_created = True
|
||||||
|
logger.info(f"[IntegrationViewSet] Created WordPress integration {integration.id} for site {site.id}")
|
||||||
|
|
||||||
service = IntegrationService()
|
service = IntegrationService()
|
||||||
# Mark this as initial connection test since API key was provided in request body
|
# Mark this as initial connection test since API key was provided in request body
|
||||||
@@ -203,8 +212,15 @@ class IntegrationViewSet(SiteSectorModelViewSet):
|
|||||||
result = service._test_wordpress_connection(integration, is_initial_connection=is_initial_connection)
|
result = service._test_wordpress_connection(integration, is_initial_connection=is_initial_connection)
|
||||||
|
|
||||||
if result.get('success'):
|
if result.get('success'):
|
||||||
|
# Include integration_id in response so plugin can store it
|
||||||
|
result['integration_id'] = integration.id
|
||||||
|
result['integration_created'] = integration_created
|
||||||
return success_response(result, request=request)
|
return success_response(result, request=request)
|
||||||
else:
|
else:
|
||||||
|
# If test failed and we just created integration, delete it
|
||||||
|
if integration_created:
|
||||||
|
integration.delete()
|
||||||
|
logger.info(f"[IntegrationViewSet] Deleted integration {integration.id} due to failed connection test")
|
||||||
return error_response(result.get('message', 'Connection test failed'), None, status.HTTP_400_BAD_REQUEST, request)
|
return error_response(result.get('message', 'Connection test failed'), None, status.HTTP_400_BAD_REQUEST, request)
|
||||||
|
|
||||||
@action(detail=True, methods=['post'])
|
@action(detail=True, methods=['post'])
|
||||||
|
|||||||
@@ -178,46 +178,29 @@ export default function WordPressIntegrationForm({
|
|||||||
return key.substring(0, 8) + '**********' + key.substring(key.length - 4);
|
return key.substring(0, 8) + '**********' + key.substring(key.length - 4);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Toggle integration enabled status
|
// Toggle integration sync enabled status (not creation - that happens automatically)
|
||||||
const [integrationEnabled, setIntegrationEnabled] = useState(integration?.is_active ?? true);
|
const [integrationEnabled, setIntegrationEnabled] = useState(integration?.sync_enabled ?? false);
|
||||||
|
|
||||||
const handleToggleIntegration = async (enabled: boolean) => {
|
const handleToggleIntegration = async (enabled: boolean) => {
|
||||||
try {
|
try {
|
||||||
setIntegrationEnabled(enabled);
|
setIntegrationEnabled(enabled);
|
||||||
|
|
||||||
if (integration) {
|
if (integration) {
|
||||||
// Update existing integration
|
// Update existing integration - only toggle sync_enabled, not creation
|
||||||
await integrationApi.updateIntegration(integration.id, {
|
await integrationApi.updateIntegration(integration.id, {
|
||||||
is_active: enabled,
|
sync_enabled: enabled,
|
||||||
} as any);
|
} as any);
|
||||||
toast.success(enabled ? 'Integration enabled' : 'Integration disabled');
|
toast.success(enabled ? 'Sync enabled' : 'Sync disabled');
|
||||||
|
|
||||||
// Reload integration
|
// Reload integration
|
||||||
const updated = await integrationApi.getWordPressIntegration(siteId);
|
const updated = await integrationApi.getWordPressIntegration(siteId);
|
||||||
if (onIntegrationUpdate && updated) {
|
if (onIntegrationUpdate && updated) {
|
||||||
onIntegrationUpdate(updated);
|
onIntegrationUpdate(updated);
|
||||||
}
|
}
|
||||||
} else if (enabled && apiKey) {
|
} else {
|
||||||
// Create integration when enabling for first time
|
// Integration doesn't exist - it should be created automatically by plugin
|
||||||
// Use API key-only authentication (no username/password required)
|
// when user connects from WordPress side
|
||||||
await integrationApi.saveWordPressIntegration(siteId, {
|
toast.info('Integration will be created automatically when you connect from WordPress plugin. Please connect from the plugin first.');
|
||||||
url: siteUrl || '',
|
|
||||||
username: '', // Optional when using API key
|
|
||||||
app_password: '', // Optional when using API key
|
|
||||||
api_key: apiKey,
|
|
||||||
is_active: enabled,
|
|
||||||
sync_enabled: true,
|
|
||||||
});
|
|
||||||
toast.success('Integration created and enabled');
|
|
||||||
|
|
||||||
// Reload integration
|
|
||||||
const updated = await integrationApi.getWordPressIntegration(siteId);
|
|
||||||
if (onIntegrationUpdate && updated) {
|
|
||||||
onIntegrationUpdate(updated);
|
|
||||||
}
|
|
||||||
} else if (enabled && !apiKey) {
|
|
||||||
// Toggle enabled but no API key - show error
|
|
||||||
toast.error('API key is required to enable WordPress integration');
|
|
||||||
setIntegrationEnabled(false);
|
setIntegrationEnabled(false);
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -229,7 +212,7 @@ export default function WordPressIntegrationForm({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (integration) {
|
if (integration) {
|
||||||
setIntegrationEnabled(integration.is_active ?? true);
|
setIntegrationEnabled(integration.sync_enabled ?? false);
|
||||||
}
|
}
|
||||||
}, [integration]);
|
}, [integration]);
|
||||||
|
|
||||||
@@ -255,7 +238,7 @@ export default function WordPressIntegrationForm({
|
|||||||
{apiKey && (
|
{apiKey && (
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">
|
<span className="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||||
{integrationEnabled ? 'Enabled' : 'Disabled'}
|
{integrationEnabled ? 'Sync Enabled' : 'Sync Disabled'}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -209,22 +209,14 @@ export default function SiteSettings() {
|
|||||||
const [integrationStatus, setIntegrationStatus] = useState<'connected' | 'configured' | 'not_configured'>('not_configured');
|
const [integrationStatus, setIntegrationStatus] = useState<'connected' | 'configured' | 'not_configured'>('not_configured');
|
||||||
const [testingAuth, setTestingAuth] = useState(false);
|
const [testingAuth, setTestingAuth] = useState(false);
|
||||||
|
|
||||||
// Check basic configuration (API key + toggle)
|
// Check basic configuration - integration must exist in DB and have sync_enabled
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkStatus = async () => {
|
const checkStatus = async () => {
|
||||||
// If integration exists and is active, mark as configured
|
// Integration must exist in database and have sync_enabled = true
|
||||||
if (wordPressIntegration && wordPressIntegration.is_active) {
|
if (wordPressIntegration && wordPressIntegration.id && wordPressIntegration.sync_enabled) {
|
||||||
// Check if API key exists (either in site or in integration credentials)
|
setIntegrationStatus('configured');
|
||||||
const hasApiKey = site?.wp_api_key ||
|
// Test authentication
|
||||||
(wordPressIntegration.credentials_json?.api_key);
|
testAuthentication();
|
||||||
|
|
||||||
if (hasApiKey) {
|
|
||||||
setIntegrationStatus('configured');
|
|
||||||
// Test authentication
|
|
||||||
testAuthentication();
|
|
||||||
} else {
|
|
||||||
setIntegrationStatus('not_configured');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
setIntegrationStatus('not_configured');
|
setIntegrationStatus('not_configured');
|
||||||
}
|
}
|
||||||
@@ -232,6 +224,17 @@ export default function SiteSettings() {
|
|||||||
checkStatus();
|
checkStatus();
|
||||||
}, [wordPressIntegration, site]);
|
}, [wordPressIntegration, site]);
|
||||||
|
|
||||||
|
// Auto-refresh integration list periodically to detect plugin-created integrations
|
||||||
|
useEffect(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
if (!wordPressIntegration) {
|
||||||
|
loadIntegrations();
|
||||||
|
}
|
||||||
|
}, 5000); // Check every 5 seconds if integration doesn't exist
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [wordPressIntegration]);
|
||||||
|
|
||||||
// Test authentication with WordPress API
|
// Test authentication with WordPress API
|
||||||
const testAuthentication = async () => {
|
const testAuthentication = async () => {
|
||||||
if (testingAuth || !wordPressIntegration?.id) return;
|
if (testingAuth || !wordPressIntegration?.id) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user