fixed global styles issue
This commit is contained in:
parent
e6b4fe69c7
commit
a31af13c84
@ -0,0 +1,80 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove invalid element_type_defaults entries.
|
||||||
|
* Only valid element types defined in DEFAULT_ROWS should exist.
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
async up(queryInterface, Sequelize) {
|
||||||
|
// Valid element types as defined in element_type_defaults.js DEFAULT_ROWS
|
||||||
|
const validTypes = [
|
||||||
|
'navigation_next',
|
||||||
|
'navigation_prev',
|
||||||
|
'tooltip',
|
||||||
|
'description',
|
||||||
|
'gallery',
|
||||||
|
'carousel',
|
||||||
|
'video_player',
|
||||||
|
'audio_player',
|
||||||
|
'spot',
|
||||||
|
'logo',
|
||||||
|
'popup',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Find invalid entries
|
||||||
|
const invalidEntries = await queryInterface.sequelize.query(
|
||||||
|
`SELECT id, element_type, name
|
||||||
|
FROM element_type_defaults
|
||||||
|
WHERE element_type NOT IN (:validTypes)
|
||||||
|
AND "deletedAt" IS NULL`,
|
||||||
|
{
|
||||||
|
replacements: { validTypes },
|
||||||
|
type: Sequelize.QueryTypes.SELECT,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (invalidEntries.length === 0) {
|
||||||
|
console.log('No invalid element_type_defaults found.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Found ${invalidEntries.length} invalid element_type_defaults:`,
|
||||||
|
);
|
||||||
|
invalidEntries.forEach((entry) => {
|
||||||
|
console.log(` - ${entry.name} (${entry.element_type})`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete invalid entries
|
||||||
|
const idsToDelete = invalidEntries.map((e) => e.id);
|
||||||
|
await queryInterface.sequelize.query(
|
||||||
|
`DELETE FROM element_type_defaults WHERE id IN (:ids)`,
|
||||||
|
{ replacements: { ids: idsToDelete } },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Also delete from project_element_defaults
|
||||||
|
const deletedProjectDefaults = await queryInterface.sequelize.query(
|
||||||
|
`DELETE FROM project_element_defaults
|
||||||
|
WHERE element_type NOT IN (:validTypes)
|
||||||
|
RETURNING id, element_type`,
|
||||||
|
{
|
||||||
|
replacements: { validTypes },
|
||||||
|
type: Sequelize.QueryTypes.SELECT,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`Deleted ${idsToDelete.length} invalid element_type_defaults.`,
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`Deleted ${deletedProjectDefaults.length} invalid project_element_defaults.`,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
async down(_queryInterface, _Sequelize) {
|
||||||
|
// Cannot restore deleted invalid entries
|
||||||
|
console.log(
|
||||||
|
'Down migration not applicable - invalid entries cannot be restored.',
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -106,6 +106,9 @@ const CarouselSettingsSection: React.FC<CarouselSettingsSectionProps> = ({
|
|||||||
</FormField>
|
</FormField>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Slides editor only shown in constructor - slides are instance-specific */}
|
||||||
|
{isConstructor && (
|
||||||
|
<>
|
||||||
<div className='mb-3 mt-4 flex items-center justify-between'>
|
<div className='mb-3 mt-4 flex items-center justify-between'>
|
||||||
<h3 className='text-sm font-semibold'>Carousel slides</h3>
|
<h3 className='text-sm font-semibold'>Carousel slides</h3>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
@ -137,7 +140,6 @@ const CarouselSettingsSection: React.FC<CarouselSettingsSectionProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='grid gap-3 md:grid-cols-2'>
|
<div className='grid gap-3 md:grid-cols-2'>
|
||||||
{isConstructor ? (
|
|
||||||
<FormField label='Image'>
|
<FormField label='Image'>
|
||||||
<select
|
<select
|
||||||
value={slide.imageUrl}
|
value={slide.imageUrl}
|
||||||
@ -153,16 +155,6 @@ const CarouselSettingsSection: React.FC<CarouselSettingsSectionProps> = ({
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</FormField>
|
</FormField>
|
||||||
) : (
|
|
||||||
<FormField label='Image URL'>
|
|
||||||
<input
|
|
||||||
value={slide.imageUrl}
|
|
||||||
onChange={(event) =>
|
|
||||||
onUpdateSlide(slide.id, 'imageUrl', event.target.value)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormField>
|
|
||||||
)}
|
|
||||||
<FormField label='Caption'>
|
<FormField label='Caption'>
|
||||||
<input
|
<input
|
||||||
value={slide.caption}
|
value={slide.caption}
|
||||||
@ -176,6 +168,8 @@ const CarouselSettingsSection: React.FC<CarouselSettingsSectionProps> = ({
|
|||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</CardBox>
|
</CardBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -63,6 +63,9 @@ const GallerySettingsSection: React.FC<GallerySettingsSectionProps> = ({
|
|||||||
</FormField>
|
</FormField>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Cards editor only shown in constructor - cards are instance-specific */}
|
||||||
|
{isConstructor && (
|
||||||
|
<>
|
||||||
<div className='mb-3 flex items-center justify-between'>
|
<div className='mb-3 flex items-center justify-between'>
|
||||||
<h3 className='text-sm font-semibold'>Gallery cards</h3>
|
<h3 className='text-sm font-semibold'>Gallery cards</h3>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
@ -94,7 +97,6 @@ const GallerySettingsSection: React.FC<GallerySettingsSectionProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='grid gap-3 md:grid-cols-2'>
|
<div className='grid gap-3 md:grid-cols-2'>
|
||||||
{isConstructor ? (
|
|
||||||
<FormField label='Image'>
|
<FormField label='Image'>
|
||||||
<select
|
<select
|
||||||
value={card.imageUrl}
|
value={card.imageUrl}
|
||||||
@ -110,16 +112,6 @@ const GallerySettingsSection: React.FC<GallerySettingsSectionProps> = ({
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</FormField>
|
</FormField>
|
||||||
) : (
|
|
||||||
<FormField label='Image URL'>
|
|
||||||
<input
|
|
||||||
value={card.imageUrl}
|
|
||||||
onChange={(event) =>
|
|
||||||
onUpdateCard(card.id, 'imageUrl', event.target.value)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormField>
|
|
||||||
)}
|
|
||||||
<FormField label='Title'>
|
<FormField label='Title'>
|
||||||
<input
|
<input
|
||||||
value={card.title}
|
value={card.title}
|
||||||
@ -133,7 +125,11 @@ const GallerySettingsSection: React.FC<GallerySettingsSectionProps> = ({
|
|||||||
<textarea
|
<textarea
|
||||||
value={card.description}
|
value={card.description}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
onUpdateCard(card.id, 'description', event.target.value)
|
onUpdateCard(
|
||||||
|
card.id,
|
||||||
|
'description',
|
||||||
|
event.target.value,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
className='h-24 w-full rounded border border-gray-300 p-2 dark:border-dark-700 dark:bg-dark-900'
|
className='h-24 w-full rounded border border-gray-300 p-2 dark:border-dark-700 dark:bg-dark-900'
|
||||||
/>
|
/>
|
||||||
@ -144,6 +140,8 @@ const GallerySettingsSection: React.FC<GallerySettingsSectionProps> = ({
|
|||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</CardBox>
|
</CardBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user