mirror of
https://github.com/ToolJet/ToolJet
synced 2026-04-26 07:57:17 +00:00
* Added Hover Background option for button, button group, modal trigger btn, popover menu button
* Added FontSize style property to Button, Button group, Popover menu, Modal Trigger btn. Adjusted line height and icon size accordingly
* Added FontWeight to Button, Button Group, Popover Menu, Modal Trigger Button
* Added Content Alignment for Button, Popover menu and Modal Trigger btn
* Added Hover Toggle for Button , Button Group, Popover menu and Modal Trigger Btn
* Reverted changes to button group legacy
* Added the properties to the new Button Group
* Resolved copilot comments
* Removed Content Alignment from Button group and changed the accordian for hover bg
* Created the migration and the import-export service
* perf: Replace placeholder text color migration with optimized version using cursor pagination
* fix: use result[1] for affected row count in batch DELETE
entityManager.query() returns [rows, rowCount] for DELETE/UPDATE
statements, not a QueryResult object. result.rowCount is undefined,
causing the cleanup loop to exit after the first batch.
* update: bump subproject commits for frontend and server components
* fix: include NULL styles rows in placeholder text color backfill
NOT (styles::jsonb ? 'key') yields NULL when styles IS NULL, so those
rows were silently skipped. Added explicit OR styles IS NULL to catch them.
* chore: use @helpers path alias for migration.helper import
* fix: implement two-pass delete for app history to avoid FK violations
* Revert "Reverted placeholder color changes (#15659)"
This reverts commit 8a458cfcbd.
* refactor: remove unused migration for backfilling placeholder text color
* refactor: button style migration and added the progess
---------
Co-authored-by: Rahul <rahulrnc03@gmail.com>
Co-authored-by: Shaurya Sharma <shaurya064@gmail.com>
Co-authored-by: Johnson Cherian <johnsonc.dev@gmail.com>
110 lines
4.1 KiB
TypeScript
110 lines
4.1 KiB
TypeScript
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
import { deleteAppHistoryForStructuralMigration } from '@helpers/migration.helper';
|
|
|
|
const MIGRATION_NAME = 'BackfillFontAndHoverStylesForButtonWidgets1774589474535';
|
|
const BATCH_SIZE = 2000;
|
|
const COMPONENT_TYPES = ['Button', 'ButtonGroupV2', 'ModalV2', 'PopoverMenu'];
|
|
|
|
// Patch applied to Button and PopoverMenu (5 props)
|
|
const BUTTON_POPOVER_PATCH = JSON.stringify({
|
|
textSize: { value: '{{14}}' },
|
|
fontWeight: { value: 'normal' },
|
|
contentAlignment: { value: 'center' },
|
|
hoverBackgroundMode: { value: 'auto' },
|
|
hoverBackgroundColor: { value: 'var(--cc-primary-brand)' },
|
|
});
|
|
|
|
// Patch applied to ButtonGroupV2 (4 props — no contentAlignment)
|
|
const BUTTON_GROUP_PATCH = JSON.stringify({
|
|
textSize: { value: '{{14}}' },
|
|
fontWeight: { value: 'normal' },
|
|
hoverBackgroundMode: { value: 'auto' },
|
|
hoverBackgroundColor: { value: 'var(--cc-primary-brand)' },
|
|
});
|
|
|
|
// Patch applied to ModalV2 (5 props with triggerButton prefix)
|
|
const MODAL_V2_PATCH = JSON.stringify({
|
|
triggerButtonTextSize: { value: '{{14}}' },
|
|
triggerButtonFontWeight: { value: 'normal' },
|
|
triggerButtonContentAlignment: { value: 'center' },
|
|
triggerButtonHoverBackgroundMode: { value: 'auto' },
|
|
triggerButtonHoverBackgroundColor: { value: 'var(--cc-primary-brand)' },
|
|
});
|
|
|
|
export class BackfillFontAndHoverStylesForButtonWidgets1774589474535 implements MigrationInterface {
|
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
const [{ count }] = await queryRunner.query(
|
|
`SELECT COUNT(*) FROM components
|
|
WHERE type = ANY($1)
|
|
AND (
|
|
(type IN ('Button', 'ButtonGroupV2', 'PopoverMenu') AND (styles IS NULL OR NOT (styles::jsonb ? 'textSize')))
|
|
OR (type = 'ModalV2' AND (styles IS NULL OR NOT (styles::jsonb ? 'triggerButtonTextSize')))
|
|
)`,
|
|
[COMPONENT_TYPES]
|
|
);
|
|
const total = parseInt(count, 10);
|
|
console.log(`${MIGRATION_NAME}: [START] Backfill font and hover styles | Total: ${total}`);
|
|
|
|
let lastId = '00000000-0000-0000-0000-000000000000';
|
|
let totalUpdated = 0;
|
|
|
|
while (true) {
|
|
const rows: { id: string }[] = await queryRunner.query(
|
|
`SELECT id FROM components
|
|
WHERE type = ANY($1)
|
|
AND id > $2
|
|
AND (
|
|
(type IN ('Button', 'ButtonGroupV2', 'PopoverMenu') AND (styles IS NULL OR NOT (styles::jsonb ? 'textSize')))
|
|
OR (type = 'ModalV2' AND (styles IS NULL OR NOT (styles::jsonb ? 'triggerButtonTextSize')))
|
|
)
|
|
ORDER BY id ASC
|
|
LIMIT $3`,
|
|
[COMPONENT_TYPES, lastId, BATCH_SIZE]
|
|
);
|
|
|
|
if (rows.length === 0) break;
|
|
|
|
lastId = rows[rows.length - 1].id;
|
|
const ids = rows.map((r) => r.id);
|
|
|
|
await queryRunner.query(
|
|
`UPDATE components
|
|
SET styles = (COALESCE(styles, '{}')::jsonb ||
|
|
CASE
|
|
WHEN type = 'ButtonGroupV2' THEN $1::jsonb
|
|
WHEN type = 'ModalV2' THEN $2::jsonb
|
|
ELSE $3::jsonb
|
|
END
|
|
)::json
|
|
WHERE id = ANY($4::uuid[])`,
|
|
[BUTTON_GROUP_PATCH, MODAL_V2_PATCH, BUTTON_POPOVER_PATCH, ids]
|
|
);
|
|
|
|
totalUpdated += rows.length;
|
|
const percentage = total > 0 ? ((totalUpdated / total) * 100).toFixed(1) : '0.0';
|
|
console.log(`${MIGRATION_NAME}: [PROGRESS] ${totalUpdated}/${total} (${percentage}%)`);
|
|
}
|
|
|
|
console.log(`${MIGRATION_NAME}: [SUCCESS] Backfill font and hover styles finished.`);
|
|
|
|
if (totalUpdated > 0) {
|
|
const appVersionRows: { app_version_id: string }[] = await queryRunner.query(
|
|
`SELECT DISTINCT p.app_version_id
|
|
FROM components c
|
|
INNER JOIN pages p ON c.page_id = p.id
|
|
WHERE c.type = ANY($1)`,
|
|
[COMPONENT_TYPES]
|
|
);
|
|
|
|
await deleteAppHistoryForStructuralMigration(
|
|
queryRunner.manager,
|
|
{ appVersionIds: appVersionRows.map((r) => r.app_version_id) },
|
|
MIGRATION_NAME
|
|
);
|
|
}
|
|
}
|
|
|
|
public async down(_queryRunner: QueryRunner): Promise<void> {
|
|
// Intentional no-op — structural migrations are not reversed
|
|
}
|
|
}
|