Files
orion/static/admin/js/platform-edit.js
Samir Boulahtit 3d3b8cae22 feat: add platform detail/edit admin UI and service enhancements
- Add platform detail and edit admin pages with templates and JS
- Add ContentPageService methods: list_all_platform_pages, list_all_vendor_defaults
- Deprecate /admin/platform-homepage route (redirects to /admin/platforms)
- Add migration to fix content_page nullable columns
- Refine platform and vendor context middleware
- Add platform context middleware unit tests
- Update platforms.js with improved functionality
- Add section-based homepage plan documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:08:02 +01:00

231 lines
6.5 KiB
JavaScript

/**
* Platform Edit - Alpine.js Component
*
* Handles platform editing for multi-platform CMS.
*/
const platformEditLog = window.LogConfig.createLogger('PLATFORM_EDIT');
function platformEdit() {
return {
// Inherit base layout functionality from init-alpine.js
...data(),
// Page identification
currentPage: 'platform-edit',
// State
platform: null,
loading: true,
saving: false,
error: null,
success: null,
platformCode: null,
// Form data
formData: {
name: '',
description: '',
domain: '',
path_prefix: '',
logo: '',
logo_dark: '',
favicon: '',
default_language: 'fr',
supported_languages: ['fr', 'de', 'en'],
is_active: true,
is_public: true,
theme_config: {},
settings: {},
},
errors: {},
// Available languages
availableLanguages: [
{ code: 'fr', name: 'French' },
{ code: 'de', name: 'German' },
{ code: 'en', name: 'English' },
{ code: 'lu', name: 'Luxembourgish' },
],
// Lifecycle
async init() {
platformEditLog.info('=== PLATFORM EDIT PAGE INITIALIZING ===');
// Duplicate initialization guard
if (window._platformEditInitialized) {
platformEditLog.warn('Platform edit page already initialized, skipping...');
return;
}
window._platformEditInitialized = true;
try {
// Extract platform code from URL
const path = window.location.pathname;
const match = path.match(/\/admin\/platforms\/([^\/]+)\/edit/);
if (match) {
this.platformCode = match[1];
platformEditLog.info('Editing platform:', this.platformCode);
await this.loadPlatform();
} else {
platformEditLog.error('No platform code in URL');
this.error = 'Platform code not found in URL';
this.loading = false;
}
platformEditLog.info('=== PLATFORM EDIT PAGE INITIALIZATION COMPLETE ===');
} catch (error) {
window.LogConfig.logError(error, 'Platform Edit Init');
this.error = 'Failed to initialize page';
this.loading = false;
}
},
// API Methods
async loadPlatform() {
this.loading = true;
this.error = null;
try {
const response = await apiClient.get(`/admin/platforms/${this.platformCode}`);
this.platform = response;
// Populate form data
this.formData = {
name: response.name || '',
description: response.description || '',
domain: response.domain || '',
path_prefix: response.path_prefix || '',
logo: response.logo || '',
logo_dark: response.logo_dark || '',
favicon: response.favicon || '',
default_language: response.default_language || 'fr',
supported_languages: response.supported_languages || ['fr', 'de', 'en'],
is_active: response.is_active ?? true,
is_public: response.is_public ?? true,
theme_config: response.theme_config || {},
settings: response.settings || {},
};
platformEditLog.info(`Loaded platform: ${this.platformCode}`);
} catch (err) {
platformEditLog.error('Error loading platform:', err);
this.error = err.message || 'Failed to load platform';
} finally {
this.loading = false;
}
},
async handleSubmit() {
this.saving = true;
this.error = null;
this.success = null;
this.errors = {};
try {
// Build update payload (only changed fields)
const payload = {
name: this.formData.name,
description: this.formData.description || null,
domain: this.formData.domain || null,
path_prefix: this.formData.path_prefix || null,
logo: this.formData.logo || null,
logo_dark: this.formData.logo_dark || null,
favicon: this.formData.favicon || null,
default_language: this.formData.default_language,
supported_languages: this.formData.supported_languages,
is_active: this.formData.is_active,
is_public: this.formData.is_public,
};
const response = await apiClient.put(
`/admin/platforms/${this.platformCode}`,
payload
);
this.platform = response;
this.success = 'Platform updated successfully';
platformEditLog.info(`Updated platform: ${this.platformCode}`);
// Clear success message after 3 seconds
setTimeout(() => {
this.success = null;
}, 3000);
} catch (err) {
platformEditLog.error('Error updating platform:', err);
this.error = err.message || 'Failed to update platform';
// Handle validation errors
if (err.details) {
this.errors = err.details;
}
} finally {
this.saving = false;
}
},
async toggleActive() {
try {
this.formData.is_active = !this.formData.is_active;
await this.handleSubmit();
} catch (err) {
platformEditLog.error('Error toggling active status:', err);
// Revert on error
this.formData.is_active = !this.formData.is_active;
}
},
async togglePublic() {
try {
this.formData.is_public = !this.formData.is_public;
await this.handleSubmit();
} catch (err) {
platformEditLog.error('Error toggling public status:', err);
// Revert on error
this.formData.is_public = !this.formData.is_public;
}
},
// Helper Methods
isLanguageSupported(code) {
return this.formData.supported_languages.includes(code);
},
toggleLanguage(code) {
const index = this.formData.supported_languages.indexOf(code);
if (index > -1) {
// Don't allow removing the last language
if (this.formData.supported_languages.length > 1) {
this.formData.supported_languages.splice(index, 1);
}
} else {
this.formData.supported_languages.push(code);
}
},
getPlatformIcon(code) {
const icons = {
main: 'home',
oms: 'clipboard-list',
loyalty: 'star',
sitebuilder: 'template',
};
return icons[code] || 'globe-alt';
},
formatDate(dateString) {
if (!dateString) return '—';
const date = new Date(dateString);
return date.toLocaleDateString('fr-LU', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
},
};
}