From 6581fd70c20a295a7e6078e3aae024f045bcf367 Mon Sep 17 00:00:00 2001 From: Dmitri Date: Mon, 4 May 2026 17:30:32 +0200 Subject: [PATCH] formatting --- .../src/db/api/project_transition_settings.js | 6 ++- backend/src/db/api/projects.js | 13 +++--- ...0002-create-project-transition-settings.js | 34 +++++++++++----- backend/src/middlewares/runtime-public.js | 6 ++- backend/src/services/file.js | 40 +++++++++++-------- .../services/project_transition_settings.js | 6 ++- backend/src/services/projects.js | 38 ++++++++++++------ backend/src/services/publish.js | 29 +++++++------- .../Constructor/ElementEditorPanel.tsx | 20 +++++----- .../EffectsSettingsSectionCompact.tsx | 4 +- .../UiElements/elements/CarouselElement.tsx | 8 +++- frontend/src/lib/resolveSlideTransition.ts | 30 ++++++++------ frontend/src/pages/constructor.tsx | 9 ++++- 13 files changed, 156 insertions(+), 87 deletions(-) diff --git a/backend/src/db/api/project_transition_settings.js b/backend/src/db/api/project_transition_settings.js index 547ad4c..f1be307 100644 --- a/backend/src/db/api/project_transition_settings.js +++ b/backend/src/db/api/project_transition_settings.js @@ -73,7 +73,11 @@ class Project_transition_settingsDBApi extends GenericDBApi { * @param {object} options - Query options * @returns {object|null} Settings record or null */ - static async findByProjectAndEnvironment(projectId, environment, options = {}) { + static async findByProjectAndEnvironment( + projectId, + environment, + options = {}, + ) { const transaction = options.transaction; const record = await this.MODEL.findOne({ diff --git a/backend/src/db/api/projects.js b/backend/src/db/api/projects.js index 3bca6d5..9cf7650 100644 --- a/backend/src/db/api/projects.js +++ b/backend/src/db/api/projects.js @@ -52,12 +52,13 @@ class ProjectsDBApi extends GenericDBApi { // Note: transition_settings moved to project_transition_settings table return { id: data.id || undefined, - name: 'name' in data ? (data.name || null) : undefined, - slug: 'slug' in data ? (data.slug || null) : undefined, - description: 'description' in data ? (data.description || null) : undefined, - logo_url: 'logo_url' in data ? (data.logo_url || null) : undefined, - favicon_url: 'favicon_url' in data ? (data.favicon_url || null) : undefined, - og_image_url: 'og_image_url' in data ? (data.og_image_url || null) : undefined, + name: 'name' in data ? data.name || null : undefined, + slug: 'slug' in data ? data.slug || null : undefined, + description: 'description' in data ? data.description || null : undefined, + logo_url: 'logo_url' in data ? data.logo_url || null : undefined, + favicon_url: 'favicon_url' in data ? data.favicon_url || null : undefined, + og_image_url: + 'og_image_url' in data ? data.og_image_url || null : undefined, design_width: 'design_width' in data ? data.design_width : undefined, design_height: 'design_height' in data ? data.design_height : undefined, }; diff --git a/backend/src/db/migrations/20260501000002-create-project-transition-settings.js b/backend/src/db/migrations/20260501000002-create-project-transition-settings.js index 8de19d3..8083860 100644 --- a/backend/src/db/migrations/20260501000002-create-project-transition-settings.js +++ b/backend/src/db/migrations/20260501000002-create-project-transition-settings.js @@ -130,13 +130,20 @@ module.exports = { try { settings = JSON.parse(settings); } catch (e) { - console.warn(`Failed to parse transition_settings for project ${project.id}:`, e); + console.warn( + `Failed to parse transition_settings for project ${project.id}:`, + e, + ); continue; } } // Skip if settings is null, empty object, or has no actual values - if (!settings || typeof settings !== 'object' || Object.keys(settings).length === 0) { + if ( + !settings || + typeof settings !== 'object' || + Object.keys(settings).length === 0 + ) { continue; } @@ -160,7 +167,9 @@ module.exports = { if (records.length > 0) { await queryInterface.bulkInsert('project_transition_settings', records); - console.log(`Migrated ${records.length} project transition settings to 'dev' environment`); + console.log( + `Migrated ${records.length} project transition settings to 'dev' environment`, + ); } // Step 3: Drop the transition_settings column from projects table @@ -192,16 +201,19 @@ module.exports = { overlayColor: setting.overlay_color, }); - await queryInterface.sequelize.query(` + await queryInterface.sequelize.query( + ` UPDATE projects SET transition_settings = :settings::jsonb WHERE id = :projectId - `, { - replacements: { - settings: jsonValue, - projectId: setting.projectId, + `, + { + replacements: { + settings: jsonValue, + projectId: setting.projectId, + }, }, - }); + ); } // Step 3: Drop indexes and table @@ -212,6 +224,8 @@ module.exports = { await queryInterface.dropTable('project_transition_settings'); // Drop the ENUM type - await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_project_transition_settings_environment";'); + await queryInterface.sequelize.query( + 'DROP TYPE IF EXISTS "enum_project_transition_settings_environment";', + ); }, }; diff --git a/backend/src/middlewares/runtime-public.js b/backend/src/middlewares/runtime-public.js index f4c07e8..4da8363 100644 --- a/backend/src/middlewares/runtime-public.js +++ b/backend/src/middlewares/runtime-public.js @@ -114,7 +114,11 @@ const sanitizePublicRuntimeListResponse = (entityName) => { pattern instanceof RegExp ? pattern.test(req.path) : req.path === pattern, ); - if (!isPublicRuntimeReadRequest(req) || !pathMatches || fields.length === 0) { + if ( + !isPublicRuntimeReadRequest(req) || + !pathMatches || + fields.length === 0 + ) { return next(); } diff --git a/backend/src/services/file.js b/backend/src/services/file.js index dcca386..3b09364 100644 --- a/backend/src/services/file.js +++ b/backend/src/services/file.js @@ -433,10 +433,7 @@ const downloadFile = async (req, res) => { res.setHeader('Content-Length', result.contentLength); // Add caching headers for browser - res.setHeader( - 'Cache-Control', - `public, max-age=${config.s3CacheMaxAge}`, - ); + res.setHeader('Cache-Control', `public, max-age=${config.s3CacheMaxAge}`); if (useCache && typeof result.body.pipe === 'function') { // Stream to both response and cache file @@ -839,13 +836,11 @@ const finalizeUploadSession = async (req, res) => { // Verify all chunks exist for (let i = 0; i < session.totalChunks; i++) { if (!sessionManager.chunkExists(sessionId, i)) { - return res - .status(400) - .send( - createErrorResponse(`Missing chunk ${i}`, 'MISSING_CHUNK', { - missingChunk: i, - }), - ); + return res.status(400).send( + createErrorResponse(`Missing chunk ${i}`, 'MISSING_CHUNK', { + missingChunk: i, + }), + ); } } @@ -956,12 +951,16 @@ const getMimeTypeFromExtension = (filepath) => { */ const copyFile = async (sourceKey, destKey, options = {}) => { const provider = getFileStorageProvider(); - const contentType = options.contentType || getMimeTypeFromExtension(sourceKey); + const contentType = + options.contentType || getMimeTypeFromExtension(sourceKey); if (provider === 's3') { const s3 = getS3Provider(); const result = await s3.copy(sourceKey, destKey, { contentType }); - logger.debug({ sourceKey, destKey, provider: 's3' }, 'File copied (server-side)'); + logger.debug( + { sourceKey, destKey, provider: 's3' }, + 'File copied (server-side)', + ); return { url: result.url }; } @@ -969,7 +968,9 @@ const copyFile = async (sourceKey, destKey, options = {}) => { const local = getLocalProvider(); await local.copy(sourceKey, destKey); logger.debug({ sourceKey, destKey, provider: 'local' }, 'File copied'); - return { url: `/api/file/download?privateUrl=${encodeURIComponent(destKey)}` }; + return { + url: `/api/file/download?privateUrl=${encodeURIComponent(destKey)}`, + }; } // GCloud fallback: download + upload (no native copy implemented) @@ -1029,13 +1030,20 @@ const copyFilesParallel = async (copies, options = {}) => { throw new Error(`Copy failed for ${copy.sourceKey}: ${errorMsg}`); } - logger.warn({ sourceKey: copy.sourceKey, error: errorMsg }, 'File copy failed'); + logger.warn( + { sourceKey: copy.sourceKey, error: errorMsg }, + 'File copy failed', + ); } } } logger.info( - { succeeded: succeeded.length, failed: failed.length, total: copies.length }, + { + succeeded: succeeded.length, + failed: failed.length, + total: copies.length, + }, 'Batch file copy completed', ); diff --git a/backend/src/services/project_transition_settings.js b/backend/src/services/project_transition_settings.js index 1d6590b..ae832fe 100644 --- a/backend/src/services/project_transition_settings.js +++ b/backend/src/services/project_transition_settings.js @@ -124,7 +124,11 @@ module.exports = class Project_transition_settingsService { /** * Find settings by project ID and environment */ - static async findByProjectAndEnvironment(projectId, environment, currentUser) { + static async findByProjectAndEnvironment( + projectId, + environment, + currentUser, + ) { return Project_transition_settingsDBApi.findByProjectAndEnvironment( projectId, environment, diff --git a/backend/src/services/projects.js b/backend/src/services/projects.js index b92cab7..5e1d52e 100644 --- a/backend/src/services/projects.js +++ b/backend/src/services/projects.js @@ -293,10 +293,13 @@ class ProjectsService extends BaseProjectsService { 'Starting parallel file copy for project clone', ); - const { succeeded, failed } = await FileService.copyFilesParallel(copyOperations, { - concurrency: 10, - continueOnError: true, - }); + const { succeeded, failed } = await FileService.copyFilesParallel( + copyOperations, + { + concurrency: 10, + continueOnError: true, + }, + ); // ============================================ // Phase D: Build assetPathMap from results @@ -322,7 +325,9 @@ class ProjectsService extends BaseProjectsService { asset_type: sourceAsset.asset_type, type: sourceAsset.type || 'general', cdn_url: '', // Will be populated on first presigned URL request - storage_key: assetPathMap.get(sourceAsset.storage_key) || sourceAsset.storage_key, + storage_key: + assetPathMap.get(sourceAsset.storage_key) || + sourceAsset.storage_key, mime_type: sourceAsset.mime_type, size_mb: sourceAsset.size_mb, width_px: sourceAsset.width_px, @@ -345,7 +350,8 @@ class ProjectsService extends BaseProjectsService { if (sourceVariant.variant_type === 'reversed') continue; // Handled in Phase F const variantStorageKey = - assetPathMap.get(sourceVariant.storage_key) || sourceVariant.storage_key; + assetPathMap.get(sourceVariant.storage_key) || + sourceVariant.storage_key; await db.asset_variants.create( { @@ -385,10 +391,13 @@ class ProjectsService extends BaseProjectsService { 'Copying reversed videos for cloned assets', ); - const reversedResults = await FileService.copyFilesParallel(reversedCopyOps, { - concurrency: 10, - continueOnError: true, // Many assets won't have reversed videos - that's OK - }); + const reversedResults = await FileService.copyFilesParallel( + reversedCopyOps, + { + concurrency: 10, + continueOnError: true, // Many assets won't have reversed videos - that's OK + }, + ); // Add successful reversed video copies to assetPathMap for (const { sourceKey, destKey } of reversedResults.succeeded) { @@ -431,15 +440,18 @@ class ProjectsService extends BaseProjectsService { // Transform background URLs to new storage keys if (pageData.background_image_url) { pageData.background_image_url = - assetPathMap.get(pageData.background_image_url) || pageData.background_image_url; + assetPathMap.get(pageData.background_image_url) || + pageData.background_image_url; } if (pageData.background_video_url) { pageData.background_video_url = - assetPathMap.get(pageData.background_video_url) || pageData.background_video_url; + assetPathMap.get(pageData.background_video_url) || + pageData.background_video_url; } if (pageData.background_audio_url) { pageData.background_audio_url = - assetPathMap.get(pageData.background_audio_url) || pageData.background_audio_url; + assetPathMap.get(pageData.background_audio_url) || + pageData.background_audio_url; } await db.tour_pages.create( diff --git a/backend/src/services/publish.js b/backend/src/services/publish.js index 14027bc..9899660 100644 --- a/backend/src/services/publish.js +++ b/backend/src/services/publish.js @@ -257,20 +257,21 @@ module.exports = class PublishService { transaction, ) { // Get source content - const [sourcePages, sourceAudioTracks, sourceTransitionSettings] = await Promise.all([ - db.tour_pages.findAll({ - where: { projectId, environment: fromEnv }, - transaction, - }), - db.project_audio_tracks.findAll({ - where: { projectId, environment: fromEnv }, - transaction, - }), - db.project_transition_settings.findOne({ - where: { projectId, environment: fromEnv }, - transaction, - }), - ]); + const [sourcePages, sourceAudioTracks, sourceTransitionSettings] = + await Promise.all([ + db.tour_pages.findAll({ + where: { projectId, environment: fromEnv }, + transaction, + }), + db.project_audio_tracks.findAll({ + where: { projectId, environment: fromEnv }, + transaction, + }), + db.project_transition_settings.findOne({ + where: { projectId, environment: fromEnv }, + transaction, + }), + ]); // Clean up target environment (hard delete - paranoid models need force: true) await Promise.all([ diff --git a/frontend/src/components/Constructor/ElementEditorPanel.tsx b/frontend/src/components/Constructor/ElementEditorPanel.tsx index 27cfd67..76940b7 100644 --- a/frontend/src/components/Constructor/ElementEditorPanel.tsx +++ b/frontend/src/components/Constructor/ElementEditorPanel.tsx @@ -773,19 +773,20 @@ export function ElementEditorPanel({ selectedElement.type === 'gallery' ? selectedElement.gallerySlideTransitionDurationMs !== undefined && - selectedElement.gallerySlideTransitionDurationMs !== '' + selectedElement.gallerySlideTransitionDurationMs !== + '' ? String( selectedElement.gallerySlideTransitionDurationMs, ) : '' : selectedElement.carouselSlideTransitionDurationMs !== - undefined && - selectedElement.carouselSlideTransitionDurationMs !== - '' - ? String( - selectedElement.carouselSlideTransitionDurationMs, - ) - : '', + undefined && + selectedElement.carouselSlideTransitionDurationMs !== + '' + ? String( + selectedElement.carouselSlideTransitionDurationMs, + ) + : '', slideTransitionEasing: selectedElement.type === 'gallery' ? selectedElement.gallerySlideTransitionEasing || '' @@ -848,7 +849,8 @@ export function ElementEditorPanel({ } else if (prop === 'slideTransitionOverlayColor') { if (selectedElement.type === 'gallery') { updateSelectedElement({ - gallerySlideTransitionOverlayColor: value || undefined, + gallerySlideTransitionOverlayColor: + value || undefined, }); } else if (selectedElement.type === 'carousel') { updateSelectedElement({ diff --git a/frontend/src/components/ElementSettings/EffectsSettingsSectionCompact.tsx b/frontend/src/components/ElementSettings/EffectsSettingsSectionCompact.tsx index 6dbb1d5..437013b 100644 --- a/frontend/src/components/ElementSettings/EffectsSettingsSectionCompact.tsx +++ b/frontend/src/components/ElementSettings/EffectsSettingsSectionCompact.tsx @@ -270,7 +270,9 @@ const EffectsSettingsSectionCompact: React.FC<