From 4bb53ef792d4864fff8a99c0f246f5d8b97b0364 Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Thu, 19 Mar 2026 01:35:13 +1100 Subject: [PATCH] chore(studio) add resizable columns to Cron jobs (#43841) ## What kind of change does this PR introduce? Chore that resolves DEPR-399. ## What is the current behavior? The cron jobs table in Studio uses a fixed-width `Name` column, which can truncate long job titles and make them hard to read on `/project/:ref/integrations/cron/jobs`. ## What is the new behavior? The cron jobs table now allows resizing the informational columns, including `Name`, `Schedule`, `Last run`, `Next run`, and `Command`, while keeping the `Active` and `Actions` columns fixed-width. This also gives the `Name` column a sensible minimum width so it can be resized without collapsing. ## Additional context Adds a small regression test around the cron jobs column configuration to verify that: - informational columns are resizable - utility columns remain fixed - the `Name` column has a non-zero minimum width --- .../CronJobs/CronJobs.constants.tsx | 25 +++++++++++++------ .../CronJobs/CronJobs.utils.test.ts | 22 +++++++++++++++- .../Integrations/CronJobs/CronJobs.utils.tsx | 2 +- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.constants.tsx b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.constants.tsx index c830c8afc9e..9def10fbcf7 100644 --- a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.constants.tsx +++ b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.constants.tsx @@ -46,12 +46,21 @@ export type HTTPHeader = { name: string; value: string } export type HTTPParameter = { name: string; value: string } -export const CRON_TABLE_COLUMNS = [ - { id: 'jobname', name: 'Name', minWidth: 0, width: 200 }, - { id: 'schedule', name: 'Schedule', width: 100 }, - { id: 'latest_run', name: 'Last run', width: 265 }, - { id: 'next_run', name: 'Next run', minWidth: 180 }, - { id: 'command', name: 'Command', minWidth: 320 }, - { id: 'active', name: 'Active', width: 70, minWidth: 70, maxWidth: 70 }, - { id: 'actions', name: '', minWidth: 75, width: 75 }, +type CronTableColumn = { + id: string + name: string + width?: number + minWidth?: number + maxWidth?: number + resizable?: boolean +} + +export const CRON_TABLE_COLUMNS: CronTableColumn[] = [ + { id: 'jobname', name: 'Name', minWidth: 160, width: 200, resizable: true }, + { id: 'schedule', name: 'Schedule', width: 100, resizable: true }, + { id: 'latest_run', name: 'Last run', width: 265, resizable: true }, + { id: 'next_run', name: 'Next run', minWidth: 180, resizable: true }, + { id: 'command', name: 'Command', minWidth: 320, resizable: true }, + { id: 'active', name: 'Active', width: 70, minWidth: 70, maxWidth: 70, resizable: false }, + { id: 'actions', name: '', minWidth: 75, width: 75, resizable: false }, ] diff --git a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.test.ts b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.test.ts index 158a9c18c1b..143b76de9de 100644 --- a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.test.ts +++ b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { cronPattern, secondsPattern } from './CronJobs.constants' -import { parseCronJobCommand } from './CronJobs.utils' +import { formatCronJobColumns, parseCronJobCommand } from './CronJobs.utils' describe('parseCronJobCommand', () => { it('should return a default object when the command is null', () => { @@ -279,3 +279,23 @@ describe('parseCronJobCommand', () => { }) }) }) + +describe('formatCronJobColumns', () => { + it('enables resizing for informational columns and keeps utility columns fixed', () => { + const columns = formatCronJobColumns({ + onSelectEdit: () => undefined, + onSelectDelete: () => undefined, + }) + + const columnsByKey = Object.fromEntries(columns.map((column) => [String(column.key), column])) + + expect(columnsByKey.jobname.resizable).toBe(true) + expect(columnsByKey.jobname.minWidth).toBeGreaterThan(0) + expect(columnsByKey.schedule.resizable).toBe(true) + expect(columnsByKey.latest_run.resizable).toBe(true) + expect(columnsByKey.next_run.resizable).toBe(true) + expect(columnsByKey.command.resizable).toBe(true) + expect(columnsByKey.active.resizable).toBe(false) + expect(columnsByKey.actions.resizable).toBe(false) + }) +}) diff --git a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.tsx b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.tsx index 75ef9acf94e..1a1cfb6baed 100644 --- a/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.tsx +++ b/apps/studio/components/interfaces/Integrations/CronJobs/CronJobs.utils.tsx @@ -236,7 +236,7 @@ export const formatCronJobColumns = ({ minWidth: col.minWidth ?? 100, maxWidth: col.maxWidth, width: col.width, - resizable: false, + resizable: col.resizable ?? false, sortable: false, draggable: false, headerCellClass: undefined,